From 9d3917ae5843e5800508320245fb5e562af49519 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Tue, 11 Jun 2024 18:55:29 +0800
Subject: [PATCH 01/57] Support CallerArgumentExpression

---
 src/Compiler/Checking/MethodCalls.fs         | 24 +++++---
 src/Compiler/Checking/PostInferenceChecks.fs |  6 ++
 src/Compiler/Checking/infos.fs               | 38 ++++++++-----
 src/Compiler/Checking/infos.fsi              |  1 +
 src/Compiler/Service/ServiceStructure.fs     | 59 +++++++++++++++++---
 src/Compiler/TypedTree/TcGlobals.fs          |  3 +-
 src/Compiler/Utilities/range.fsi             |  2 +
 7 files changed, 103 insertions(+), 30 deletions(-)

diff --git a/src/Compiler/Checking/MethodCalls.fs b/src/Compiler/Checking/MethodCalls.fs
index 46f32c53431..b09e1866a78 100644
--- a/src/Compiler/Checking/MethodCalls.fs
+++ b/src/Compiler/Checking/MethodCalls.fs
@@ -1389,7 +1389,7 @@ let emptyPreBinder (e: Expr) = e
 
 /// Get the expression that must be inserted on the caller side for a CallerSide optional arg,
 /// i.e. one where there is no corresponding caller arg.
-let rec GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g (calledArg: CalledArg) currCalledArgTy currDfltVal eCallerMemberName mMethExpr =
+let rec GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g (calledArg: CalledArg) currCalledArgTy currDfltVal eCallerMemberName mMethExpr unnamedArgs =
     match currDfltVal with
     | MissingValue -> 
         // Add an I_nop if this is an initonly field to make sure we never recognize it as an lvalue. See mkExprAddrOfExpr. 
@@ -1406,7 +1406,7 @@ let rec GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g (calledArg: C
             let ctorArgs = [Expr.Const (tcFieldInit mMethExpr fieldInit, mMethExpr, inst)]
             emptyPreBinder, Expr.Op (TOp.ILCall (false, false, true, true, NormalValUse, false, false, ctor, [inst], [], [currCalledArgTy]), [], ctorArgs, mMethExpr)
         | ByrefTy g inst ->
-            GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g calledArg inst (PassByRef(inst, currDfltVal)) eCallerMemberName mMethExpr
+            GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g calledArg inst (PassByRef(inst, currDfltVal)) eCallerMemberName mMethExpr unnamedArgs
         | _ ->
             match calledArg.CallerInfo, eCallerMemberName with
             | CallerLineNumber, _ when typeEquiv g currCalledArgTy g.int_ty ->
@@ -1416,6 +1416,16 @@ let rec GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g (calledArg: C
                 emptyPreBinder, Expr.Const (Const.String fileName, mMethExpr, currCalledArgTy)
             | CallerMemberName, Some callerName when (typeEquiv g currCalledArgTy g.string_ty) ->
                 emptyPreBinder, Expr.Const (Const.String callerName, mMethExpr, currCalledArgTy)
+            | CallerArgumentExpression param, _ when typeEquiv g currCalledArgTy g.string_ty ->
+                let str =
+                    unnamedArgs
+                    |> List.tryPick (fun { CalledArg=called; CallerArg=caller } -> 
+                        match called.NameOpt with
+                        | Some x when x.idText = param ->
+                            Some (Const.String (caller.Range.DebugCode))
+                        | _ -> None)
+                    |> Option.defaultWith (fun _ -> tcFieldInit mMethExpr fieldInit)
+                emptyPreBinder, Expr.Const (str, mMethExpr, currCalledArgTy)
             | _ ->
                 emptyPreBinder, Expr.Const (tcFieldInit mMethExpr fieldInit, mMethExpr, currCalledArgTy)
                 
@@ -1439,7 +1449,7 @@ let rec GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g (calledArg: C
 
     | PassByRef (ty, dfltVal2) ->
         let v, _ = mkCompGenLocal mMethExpr "defaultByrefArg" ty
-        let wrapper2, rhs = GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g calledArg currCalledArgTy dfltVal2 eCallerMemberName mMethExpr
+        let wrapper2, rhs = GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g calledArg currCalledArgTy dfltVal2 eCallerMemberName mMethExpr unnamedArgs
         (wrapper2 >> mkCompGenLet mMethExpr v rhs), mkValAddr mMethExpr false (mkLocalValRef v)
 
 /// Get the expression that must be inserted on the caller side for a CalleeSide optional arg where
@@ -1469,7 +1479,7 @@ let GetDefaultExpressionForCalleeSideOptionalArg g (calledArg: CalledArg) eCalle
 
 /// Get the expression that must be inserted on the caller side for an optional arg where
 /// no caller argument has been provided. 
-let GetDefaultExpressionForOptionalArg tcFieldInit g (calledArg: CalledArg) eCallerMemberName mItem (mMethExpr: range) =
+let GetDefaultExpressionForOptionalArg tcFieldInit g (calledArg: CalledArg) eCallerMemberName mItem (mMethExpr: range) unnamedArgs =
     let calledArgTy = calledArg.CalledArgumentType
     let preBinder, expr = 
         match calledArg.OptArgInfo with 
@@ -1477,7 +1487,7 @@ let GetDefaultExpressionForOptionalArg tcFieldInit g (calledArg: CalledArg) eCal
             error(InternalError("Unexpected NotOptional", mItem))
 
         | CallerSide dfltVal ->
-            GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g calledArg calledArgTy dfltVal eCallerMemberName mMethExpr
+            GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g calledArg calledArgTy dfltVal eCallerMemberName mMethExpr unnamedArgs
 
         | CalleeSide ->
             emptyPreBinder, GetDefaultExpressionForCalleeSideOptionalArg g calledArg eCallerMemberName mMethExpr
@@ -1534,7 +1544,7 @@ let AdjustCallerArgForOptional tcVal tcFieldInit eCallerMemberName (infoReader:
                             mkOptionToNullable g m (destOptionTy g callerArgTy) callerArgExpr
                         else 
                             // CSharpMethod(?x=b) when 'b' has optional type and 'x' has non-nullable type --> CSharpMethod(x=Option.defaultValue DEFAULT v)
-                            let _wrapper, defaultExpr = GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g calledArg calledArgTy dfltVal eCallerMemberName m
+                            let _wrapper, defaultExpr = GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g calledArg calledArgTy dfltVal eCallerMemberName m [assignedArg]
                             let ty = destOptionTy g callerArgTy
                             mkOptionDefaultValue g m ty defaultExpr callerArgExpr
                     else
@@ -1594,7 +1604,7 @@ let AdjustCallerArgsForOptionals tcVal tcFieldInit eCallerMemberName (infoReader
     // i.e. there is no corresponding caller arg.
     let optArgs, optArgPreBinder = 
         (emptyPreBinder, calledMeth.UnnamedCalledOptArgs) ||> List.mapFold (fun preBinder calledArg -> 
-            let preBinder2, arg = GetDefaultExpressionForOptionalArg tcFieldInit g calledArg eCallerMemberName mItem mMethExpr
+            let preBinder2, arg = GetDefaultExpressionForOptionalArg tcFieldInit g calledArg eCallerMemberName mItem mMethExpr unnamedArgs
             arg, (preBinder >> preBinder2))
 
     let adjustedNormalUnnamedArgs = List.map (AdjustCallerArgForOptional tcVal tcFieldInit eCallerMemberName infoReader ad) unnamedArgs
diff --git a/src/Compiler/Checking/PostInferenceChecks.fs b/src/Compiler/Checking/PostInferenceChecks.fs
index c7090709cca..b94ec73032a 100644
--- a/src/Compiler/Checking/PostInferenceChecks.fs
+++ b/src/Compiler/Checking/PostInferenceChecks.fs
@@ -2365,6 +2365,12 @@ let CheckEntityDefn cenv env (tycon: Entity) =
                         if not (typeEquiv g g.string_ty ty) then
                             errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfo.ToString(), "string", NicePrint.minimalStringOfType cenv.denv ty), m))
                     | CalleeSide, CallerMemberName ->
+                        if not ((isOptionTy g ty) && (typeEquiv g g.string_ty (destOptionTy g ty))) then
+                            errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfo.ToString(), "string", NicePrint.minimalStringOfType cenv.denv (destOptionTy g ty)), m))
+                    | CallerSide _, CallerArgumentExpression _ ->
+                        if not (typeEquiv g g.string_ty ty) then
+                            errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfo.ToString(), "string", NicePrint.minimalStringOfType cenv.denv ty), m))
+                    | CalleeSide, CallerArgumentExpression _ ->
                         if not ((isOptionTy g ty) && (typeEquiv g g.string_ty (destOptionTy g ty))) then
                             errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfo.ToString(), "string", NicePrint.minimalStringOfType cenv.denv (destOptionTy g ty)), m)))
 
diff --git a/src/Compiler/Checking/infos.fs b/src/Compiler/Checking/infos.fs
index c90d49f3dcc..74637a34708 100644
--- a/src/Compiler/Checking/infos.fs
+++ b/src/Compiler/Checking/infos.fs
@@ -238,6 +238,7 @@ type CallerInfo =
     | CallerLineNumber
     | CallerMemberName
     | CallerFilePath
+    | CallerArgumentExpression of paramName: string
 
     override x.ToString() = sprintf "%+A" x
 
@@ -315,20 +316,23 @@ let CrackParamAttribsInfo g (ty: TType, argInfo: ArgReprInfo) =
     let isCallerLineNumberArg = HasFSharpAttribute g g.attrib_CallerLineNumberAttribute argInfo.Attribs
     let isCallerFilePathArg = HasFSharpAttribute g g.attrib_CallerFilePathAttribute argInfo.Attribs
     let isCallerMemberNameArg = HasFSharpAttribute g g.attrib_CallerMemberNameAttribute argInfo.Attribs
+    let callerArgumentExpressionArg = TryFindFSharpAttributeOpt g g.attrib_CallerArgumentExpressionAttribute argInfo.Attribs
 
     let callerInfo =
-        match isCallerLineNumberArg, isCallerFilePathArg, isCallerMemberNameArg with
-        | false, false, false -> NoCallerInfo
-        | true, false, false -> CallerLineNumber
-        | false, true, false -> CallerFilePath
-        | false, false, true -> CallerMemberName
-        | false, true, true -> 
+        match isCallerLineNumberArg, isCallerFilePathArg, isCallerMemberNameArg, callerArgumentExpressionArg with
+        | false, false, false, None -> NoCallerInfo
+        | true, false, false, None -> CallerLineNumber
+        | false, true, false, None -> CallerFilePath
+        | false, false, true, None -> CallerMemberName
+        | false, false, false, Some(Attrib(_, _, (AttribStringArg x :: _), _, _, _, _)) ->
+            CallerArgumentExpression(x)
+        | false, true, true, _ -> 
             match TryFindFSharpAttribute g g.attrib_CallerMemberNameAttribute argInfo.Attribs with
             | Some(Attrib(_, _, _, _, _, _, callerMemberNameAttributeRange)) ->
                 warning(Error(FSComp.SR.CallerMemberNameIsOverriden(argInfo.Name.Value.idText), callerMemberNameAttributeRange))
                 CallerFilePath
             | _ -> failwith "Impossible"
-        | _, _, _ ->
+        | _, _, _, _ ->
             // if multiple caller info attributes are specified, pick the "wrong" one here
             // so that we get an error later
             match tryDestOptionTy g ty with
@@ -1191,14 +1195,22 @@ type MethInfo =
                  let isCallerLineNumberArg = TryFindILAttribute g.attrib_CallerLineNumberAttribute attrs
                  let isCallerFilePathArg = TryFindILAttribute g.attrib_CallerFilePathAttribute attrs
                  let isCallerMemberNameArg = TryFindILAttribute g.attrib_CallerMemberNameAttribute attrs
+                 let isCallerArgumentExpressionArg = TryFindILAttributeOpt g.attrib_CallerArgumentExpressionAttribute attrs
 
                  let callerInfo =
-                    match isCallerLineNumberArg, isCallerFilePathArg, isCallerMemberNameArg with
-                    | false, false, false -> NoCallerInfo
-                    | true, false, false -> CallerLineNumber
-                    | false, true, false -> CallerFilePath
-                    | false, false, true -> CallerMemberName
-                    | _, _, _ ->
+                    match isCallerLineNumberArg, isCallerFilePathArg, isCallerMemberNameArg, isCallerArgumentExpressionArg with
+                    | false, false, false, false -> NoCallerInfo
+                    | true, false, false, false -> CallerLineNumber
+                    | false, true, false, false -> CallerFilePath
+                    | false, false, true, false -> CallerMemberName            
+                    | false, false, false, true ->
+                        match g.attrib_CallerArgumentExpressionAttribute with
+                        | Some (AttribInfo(tref,_)) ->
+                            match TryDecodeILAttribute tref attrs with
+                            | Some ([ILAttribElem.String (Some name) ], _) -> CallerArgumentExpression(name)
+                            | _ -> NoCallerInfo
+                        | None -> NoCallerInfo
+                    | _, _, _, _ ->
                         // if multiple caller info attributes are specified, pick the "wrong" one here
                         // so that we get an error later
                         if p.Type.TypeRef.FullName = "System.Int32" then CallerFilePath
diff --git a/src/Compiler/Checking/infos.fsi b/src/Compiler/Checking/infos.fsi
index a2b178d92ac..25fdac7cb33 100644
--- a/src/Compiler/Checking/infos.fsi
+++ b/src/Compiler/Checking/infos.fsi
@@ -101,6 +101,7 @@ type CallerInfo =
     | CallerLineNumber
     | CallerMemberName
     | CallerFilePath
+    | CallerArgumentExpression of paramName: string
 
 [<RequireQualifiedAccess>]
 type ReflectedArgInfo =
diff --git a/src/Compiler/Service/ServiceStructure.fs b/src/Compiler/Service/ServiceStructure.fs
index 1d0f7c7f8ec..6299dd11c7e 100644
--- a/src/Compiler/Service/ServiceStructure.fs
+++ b/src/Compiler/Service/ServiceStructure.fs
@@ -839,22 +839,40 @@ module Structure =
             elif line.StartsWithOrdinal("//") then Some SingleLine
             else None
 
+        /// Determine if a line is //#region or //#endregion or else some thing
+        let (|BeginRegion|EndRegion|NotRegion|) =
+            let regex = System.Text.RegularExpressions.Regex("^\\s*//\\s*#(end)?region", System.Text.RegularExpressions.RegexOptions.Compiled)
+            fun (line: string) ->
+                let result = regex.Match(line)
+                match result.Success, result.Groups[1].Success with
+                | false, _ -> NotRegion
+                | true, false -> BeginRegion
+                | true, true -> EndRegion
+
         let getCommentRanges trivia (lines: string[]) =
             let rec loop (lastLineNum, currentComment, result as state) (lines: string list) lineNum =
                 match lines with
                 | [] -> state
                 | lineStr :: rest ->
                     match lineStr.TrimStart(), currentComment with
+                    | (Comment SingleLine & (BeginRegion | EndRegion)), _ -> 
+                        let result' = 
+                            match currentComment with
+                            | Some comment -> comment :: result
+                            | None -> result
+                        let comments = CommentList.New SingleLine (lineNum, lineStr)
+                        loop (lineNum, Some comments, result') rest (lineNum + 1)
                     | Comment commentType, Some comment ->
-                        loop
-                            (if comment.Type = commentType && lineNum = lastLineNum + 1 then
-                                 comment.Lines.Add(lineNum, lineStr)
-                                 lineNum, currentComment, result
-                             else
-                                 let comments = CommentList.New commentType (lineNum, lineStr)
-                                 lineNum, Some comments, comment :: result)
-                            rest
-                            (lineNum + 1)
+                        let comments, result' = 
+                            match commentType, comment.Lines[comment.Lines.Count - 1] with
+                            | SingleLine, (_, NotRegion)
+                            | XmlDoc, _ when comment.Type = commentType && lineNum = lastLineNum + 1 ->
+                                comment.Lines.Add(lineNum, lineStr)
+                                currentComment, result
+                            | _ ->
+                                let comments = CommentList.New commentType (lineNum, lineStr)
+                                Some comments, comment :: result
+                        loop (lineNum, comments, result') rest (lineNum + 1)
                     | Comment commentType, None ->
                         let comments = CommentList.New commentType (lineNum, lineStr)
                         loop (lineNum, Some comments, result) rest (lineNum + 1)
@@ -893,6 +911,29 @@ module Structure =
                 })
             |> acc.AddRange
 
+            let _, scopes =
+                comments
+                |> List.filter (fun comment -> comment.Type = SingleLine && comment.Lines.Count = 1)
+                |> List.fold (fun (stack, state) comment -> 
+                    match stack, comment.Lines[0] with
+                    | _, (_, BeginRegion as startLine) -> startLine :: stack, state
+                    | (startLine, startStr) :: rest, (endLine, (EndRegion as endStr)) -> 
+                        let startCol = startStr.IndexOf '/'
+                        let endCol = endStr.TrimEnd().Length
+
+                        let range = mkRange "" (mkPos (startLine + 1) startCol) (mkPos (endLine + 1) endCol)
+                        let scope = 
+                            {
+                                Scope = Scope.Comment
+                                Collapse = Collapse.Same
+                                Range = range
+                                CollapseRange = range
+                            }
+                        rest, scope :: state
+                    | _, (_, EndRegion as endLine) -> endLine :: stack, state
+                    | _ -> stack, state) ([], [])
+            acc.AddRange scopes
+
             for trivia in trivia do
                 match trivia with
                 | CommentTrivia.BlockComment m when m.StartLine <> m.EndLine ->
diff --git a/src/Compiler/TypedTree/TcGlobals.fs b/src/Compiler/TypedTree/TcGlobals.fs
index 69a99dfe119..9566eb3f3cc 100644
--- a/src/Compiler/TypedTree/TcGlobals.fs
+++ b/src/Compiler/TypedTree/TcGlobals.fs
@@ -1074,7 +1074,7 @@ type TcGlobals(
   // Adding an unnecessary "let" instead of inlining into a muiti-line pipelined compute-once "member val" that is too complex for @dsyme
   let v_attribs_Unsupported = [
         tryFindSysAttrib "System.Runtime.CompilerServices.ModuleInitializerAttribute"
-        tryFindSysAttrib "System.Runtime.CompilerServices.CallerArgumentExpressionAttribute"
+        // tryFindSysAttrib "System.Runtime.CompilerServices.CallerArgumentExpressionAttribute"
         tryFindSysAttrib "System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute"
         tryFindSysAttrib "System.Runtime.CompilerServices.CompilerFeatureRequiredAttribute"
         tryFindSysAttrib "System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute"
@@ -1492,6 +1492,7 @@ type TcGlobals(
   member val attrib_ExtensionAttribute = findSysAttrib "System.Runtime.CompilerServices.ExtensionAttribute"
   member val attrib_CallerLineNumberAttribute = findSysAttrib "System.Runtime.CompilerServices.CallerLineNumberAttribute"
   member val attrib_CallerFilePathAttribute = findSysAttrib "System.Runtime.CompilerServices.CallerFilePathAttribute"
+  member val attrib_CallerArgumentExpressionAttribute = tryFindSysAttrib "System.Runtime.CompilerServices.CallerArgumentExpressionAttribute"
   member val attrib_CallerMemberNameAttribute = findSysAttrib "System.Runtime.CompilerServices.CallerMemberNameAttribute"
   member val attrib_ReferenceAssemblyAttribute = findSysAttrib "System.Runtime.CompilerServices.ReferenceAssemblyAttribute"
   member val attrib_SkipLocalsInitAttribute  = findSysAttrib "System.Runtime.CompilerServices.SkipLocalsInitAttribute"
diff --git a/src/Compiler/Utilities/range.fsi b/src/Compiler/Utilities/range.fsi
index 7b422fcd307..c952ac7f9a4 100755
--- a/src/Compiler/Utilities/range.fsi
+++ b/src/Compiler/Utilities/range.fsi
@@ -122,6 +122,8 @@ type Range =
 
     /// The range where all values are zero
     static member Zero: range
+
+    member internal DebugCode: string
   
 /// Represents a range within a file
 and range = Range

From dec3d3edc1caaf890b15cb70922796a2dd262e23 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Sun, 11 Aug 2024 17:21:18 +0800
Subject: [PATCH 02/57] fix for fsi

---
 src/Compiler/Checking/MethodCalls.fs   |  4 +++-
 src/Compiler/Driver/CompilerConfig.fs  |  4 ++++
 src/Compiler/Driver/CompilerConfig.fsi |  4 ++++
 src/Compiler/Driver/CompilerImports.fs |  3 ++-
 src/Compiler/Interactive/fsi.fs        |  2 ++
 src/Compiler/TypedTree/TcGlobals.fs    | 27 +++++++++++++++++++++++++-
 src/Compiler/TypedTree/TcGlobals.fsi   |  7 ++++++-
 7 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/src/Compiler/Checking/MethodCalls.fs b/src/Compiler/Checking/MethodCalls.fs
index d34b306c3cc..7dda8b368d2 100644
--- a/src/Compiler/Checking/MethodCalls.fs
+++ b/src/Compiler/Checking/MethodCalls.fs
@@ -1431,7 +1431,9 @@ let rec GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g (calledArg: C
                     |> List.tryPick (fun { CalledArg=called; CallerArg=caller } -> 
                         match called.NameOpt with
                         | Some x when x.idText = param ->
-                            Some (Const.String (caller.Range.DebugCode))
+                            match g.GetCodeText caller.Range with
+                            | ValueSome code -> Some (Const.String code)
+                            | ValueNone -> None
                         | _ -> None)
                     |> Option.defaultWith (fun _ -> tcFieldInit mMethExpr fieldInit)
                 emptyPreBinder, Expr.Const (str, mMethExpr, currCalledArgTy)
diff --git a/src/Compiler/Driver/CompilerConfig.fs b/src/Compiler/Driver/CompilerConfig.fs
index 4a1d0d18c74..09818c34819 100644
--- a/src/Compiler/Driver/CompilerConfig.fs
+++ b/src/Compiler/Driver/CompilerConfig.fs
@@ -619,6 +619,8 @@ type TcConfigBuilder =
         mutable dumpSignatureData: bool
 
         mutable realsig: bool
+
+        mutable getLine: (string -> int -> string) voption
     }
 
     // Directories to start probing in
@@ -829,6 +831,7 @@ type TcConfigBuilder =
             dumpSignatureData = false
             realsig = true
             strictIndentation = None
+            getLine = ValueNone
         }
 
     member tcConfigB.FxResolver =
@@ -1373,6 +1376,7 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) =
     member _.typeCheckingConfig = data.typeCheckingConfig
     member _.dumpSignatureData = data.dumpSignatureData
     member _.realsig = data.realsig
+    member _.getLine = data.getLine
 
     static member Create(builder, validate) =
         use _ = UseBuildPhase BuildPhase.Parameter
diff --git a/src/Compiler/Driver/CompilerConfig.fsi b/src/Compiler/Driver/CompilerConfig.fsi
index f21ae429029..0a3193f6ef3 100644
--- a/src/Compiler/Driver/CompilerConfig.fsi
+++ b/src/Compiler/Driver/CompilerConfig.fsi
@@ -525,6 +525,8 @@ type TcConfigBuilder =
         mutable dumpSignatureData: bool
 
         mutable realsig: bool
+
+        mutable getLine: (string -> int -> string) voption
     }
 
     static member CreateNew:
@@ -904,6 +906,8 @@ type TcConfig =
 
     member realsig: bool
 
+    member getLine: (string -> int -> string) voption
+
 /// Represents a computation to return a TcConfig. Normally this is just a constant immutable TcConfig,
 /// but for F# Interactive it may be based on an underlying mutable TcConfigBuilder.
 [<Sealed>]
diff --git a/src/Compiler/Driver/CompilerImports.fs b/src/Compiler/Driver/CompilerImports.fs
index 334a834db32..a1adeb451a3 100644
--- a/src/Compiler/Driver/CompilerImports.fs
+++ b/src/Compiler/Driver/CompilerImports.fs
@@ -2614,7 +2614,8 @@ and [<Sealed>] TcImports
                     tcConfig.noDebugAttributes,
                     tcConfig.pathMap,
                     tcConfig.langVersion,
-                    tcConfig.realsig
+                    tcConfig.realsig,
+                    tcConfig.getLine
                 )
 
 #if DEBUG
diff --git a/src/Compiler/Interactive/fsi.fs b/src/Compiler/Interactive/fsi.fs
index 5904071dd8a..b3b94bb763f 100644
--- a/src/Compiler/Interactive/fsi.fs
+++ b/src/Compiler/Interactive/fsi.fs
@@ -4661,6 +4661,8 @@ type FsiEvaluationSession
         if List.isEmpty fsiOptions.SourceFiles then
             fsiConsolePrompt.PrintAhead()
 
+    do tcConfigB.getLine <- ValueSome fsiStdinSyphon.GetLine
+
     let fsiConsoleInput = FsiConsoleInput(fsi, fsiOptions, inReader, outWriter)
 
     /// The single, global interactive checker that can be safely used in conjunction with other operations
diff --git a/src/Compiler/TypedTree/TcGlobals.fs b/src/Compiler/TypedTree/TcGlobals.fs
index 786b694bbf9..3e166a3d0a8 100644
--- a/src/Compiler/TypedTree/TcGlobals.fs
+++ b/src/Compiler/TypedTree/TcGlobals.fs
@@ -190,7 +190,8 @@ type TcGlobals(
     noDebugAttributes: bool,
     pathMap: PathMap,
     langVersion: LanguageVersion,
-    realsig: bool) =
+    realsig: bool,
+    getLine: (string -> int -> string) voption) =
 
   let v_langFeatureNullness = langVersion.SupportsFeature LanguageFeature.NullnessChecking
 
@@ -1980,6 +1981,30 @@ type TcGlobals(
     | _ ->
         None
 
+  member _.GetCodeText (m: Text.Range) =
+    let endCol = m.EndColumn - 1
+    let startCol = m.StartColumn - 1
+
+    let s = 
+        match getLine with
+        | ValueSome f -> 
+            [for i in m.StartLine..m.EndLine -> f m.FileName i]
+            |> String.concat "\n"
+        | ValueNone -> 
+            try
+                if FileSystem.IsInvalidPathShim m.FileName then
+                    System.String.Empty
+                elif not (FileSystem.FileExistsShim m.FileName) then
+                    System.String.Empty
+                else
+                    FileSystem.OpenFileForReadShim(m.FileName).ReadLines()
+                    |> Seq.skip (m.StartLine - 1)
+                    |> Seq.take (m.EndLine - m.StartLine + 1)
+                    |> String.concat "\n"
+            with e -> System.String.Empty
+    if System.String.IsNullOrEmpty s then ValueNone else
+    ValueSome <| s.Substring(startCol + 1, s.LastIndexOf("\n", System.StringComparison.Ordinal) + 1 - startCol + endCol)
+
 #if DEBUG
 // This global is only used during debug output
 let mutable global_g = None : TcGlobals option
diff --git a/src/Compiler/TypedTree/TcGlobals.fsi b/src/Compiler/TypedTree/TcGlobals.fsi
index b0b4a4d496b..0650086e708 100644
--- a/src/Compiler/TypedTree/TcGlobals.fsi
+++ b/src/Compiler/TypedTree/TcGlobals.fsi
@@ -147,7 +147,8 @@ type internal TcGlobals =
         noDebugAttributes: bool *
         pathMap: Internal.Utilities.PathMap *
         langVersion: FSharp.Compiler.Features.LanguageVersion *
-        realsig: bool ->
+        realsig: bool *
+        getLine: (string -> int -> string) voption ->
             TcGlobals
 
     static member IsInEmbeddableKnownSet: name: string -> bool
@@ -320,6 +321,8 @@ type internal TcGlobals =
 
     member attrib_CallerLineNumberAttribute: BuiltinAttribInfo
 
+    member attrib_CallerArgumentExpressionAttribute: BuiltinAttribInfo option
+
     member attrib_CallerMemberNameAttribute: BuiltinAttribInfo
 
     member attrib_ClassAttribute: BuiltinAttribInfo
@@ -1365,6 +1368,8 @@ type internal TcGlobals =
 
     member voidptr_tcr: FSharp.Compiler.TypedTree.EntityRef
 
+    member GetCodeText: m: Text.Range -> string voption
+
 #if DEBUG
 // This global is only used during debug output
 val mutable internal global_g: TcGlobals option

From e5d7763d46e8d174e08861ea2364042f7f66a71a Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Sun, 11 Aug 2024 17:28:45 +0800
Subject: [PATCH 03/57] revert unnecessary changes

---
 src/Compiler/Service/ServiceStructure.fs | 59 ++++--------------------
 src/Compiler/TypedTree/TcGlobals.fs      |  6 +--
 src/Compiler/Utilities/range.fsi         |  2 -
 3 files changed, 11 insertions(+), 56 deletions(-)

diff --git a/src/Compiler/Service/ServiceStructure.fs b/src/Compiler/Service/ServiceStructure.fs
index 6299dd11c7e..1d0f7c7f8ec 100644
--- a/src/Compiler/Service/ServiceStructure.fs
+++ b/src/Compiler/Service/ServiceStructure.fs
@@ -839,40 +839,22 @@ module Structure =
             elif line.StartsWithOrdinal("//") then Some SingleLine
             else None
 
-        /// Determine if a line is //#region or //#endregion or else some thing
-        let (|BeginRegion|EndRegion|NotRegion|) =
-            let regex = System.Text.RegularExpressions.Regex("^\\s*//\\s*#(end)?region", System.Text.RegularExpressions.RegexOptions.Compiled)
-            fun (line: string) ->
-                let result = regex.Match(line)
-                match result.Success, result.Groups[1].Success with
-                | false, _ -> NotRegion
-                | true, false -> BeginRegion
-                | true, true -> EndRegion
-
         let getCommentRanges trivia (lines: string[]) =
             let rec loop (lastLineNum, currentComment, result as state) (lines: string list) lineNum =
                 match lines with
                 | [] -> state
                 | lineStr :: rest ->
                     match lineStr.TrimStart(), currentComment with
-                    | (Comment SingleLine & (BeginRegion | EndRegion)), _ -> 
-                        let result' = 
-                            match currentComment with
-                            | Some comment -> comment :: result
-                            | None -> result
-                        let comments = CommentList.New SingleLine (lineNum, lineStr)
-                        loop (lineNum, Some comments, result') rest (lineNum + 1)
                     | Comment commentType, Some comment ->
-                        let comments, result' = 
-                            match commentType, comment.Lines[comment.Lines.Count - 1] with
-                            | SingleLine, (_, NotRegion)
-                            | XmlDoc, _ when comment.Type = commentType && lineNum = lastLineNum + 1 ->
-                                comment.Lines.Add(lineNum, lineStr)
-                                currentComment, result
-                            | _ ->
-                                let comments = CommentList.New commentType (lineNum, lineStr)
-                                Some comments, comment :: result
-                        loop (lineNum, comments, result') rest (lineNum + 1)
+                        loop
+                            (if comment.Type = commentType && lineNum = lastLineNum + 1 then
+                                 comment.Lines.Add(lineNum, lineStr)
+                                 lineNum, currentComment, result
+                             else
+                                 let comments = CommentList.New commentType (lineNum, lineStr)
+                                 lineNum, Some comments, comment :: result)
+                            rest
+                            (lineNum + 1)
                     | Comment commentType, None ->
                         let comments = CommentList.New commentType (lineNum, lineStr)
                         loop (lineNum, Some comments, result) rest (lineNum + 1)
@@ -911,29 +893,6 @@ module Structure =
                 })
             |> acc.AddRange
 
-            let _, scopes =
-                comments
-                |> List.filter (fun comment -> comment.Type = SingleLine && comment.Lines.Count = 1)
-                |> List.fold (fun (stack, state) comment -> 
-                    match stack, comment.Lines[0] with
-                    | _, (_, BeginRegion as startLine) -> startLine :: stack, state
-                    | (startLine, startStr) :: rest, (endLine, (EndRegion as endStr)) -> 
-                        let startCol = startStr.IndexOf '/'
-                        let endCol = endStr.TrimEnd().Length
-
-                        let range = mkRange "" (mkPos (startLine + 1) startCol) (mkPos (endLine + 1) endCol)
-                        let scope = 
-                            {
-                                Scope = Scope.Comment
-                                Collapse = Collapse.Same
-                                Range = range
-                                CollapseRange = range
-                            }
-                        rest, scope :: state
-                    | _, (_, EndRegion as endLine) -> endLine :: stack, state
-                    | _ -> stack, state) ([], [])
-            acc.AddRange scopes
-
             for trivia in trivia do
                 match trivia with
                 | CommentTrivia.BlockComment m when m.StartLine <> m.EndLine ->
diff --git a/src/Compiler/TypedTree/TcGlobals.fs b/src/Compiler/TypedTree/TcGlobals.fs
index 3e166a3d0a8..732ef43295d 100644
--- a/src/Compiler/TypedTree/TcGlobals.fs
+++ b/src/Compiler/TypedTree/TcGlobals.fs
@@ -1083,7 +1083,6 @@ type TcGlobals(
   // Adding an unnecessary "let" instead of inlining into a muiti-line pipelined compute-once "member val" that is too complex for @dsyme
   let v_attribs_Unsupported = [
         tryFindSysAttrib "System.Runtime.CompilerServices.ModuleInitializerAttribute"
-        // tryFindSysAttrib "System.Runtime.CompilerServices.CallerArgumentExpressionAttribute"
         tryFindSysAttrib "System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute"
         tryFindSysAttrib "System.Runtime.CompilerServices.CompilerFeatureRequiredAttribute"
         tryFindSysAttrib "System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute"
@@ -1992,9 +1991,8 @@ type TcGlobals(
             |> String.concat "\n"
         | ValueNone -> 
             try
-                if FileSystem.IsInvalidPathShim m.FileName then
-                    System.String.Empty
-                elif not (FileSystem.FileExistsShim m.FileName) then
+                if FileSystem.IsInvalidPathShim m.FileName || 
+                   not (FileSystem.FileExistsShim m.FileName) then
                     System.String.Empty
                 else
                     FileSystem.OpenFileForReadShim(m.FileName).ReadLines()
diff --git a/src/Compiler/Utilities/range.fsi b/src/Compiler/Utilities/range.fsi
index c952ac7f9a4..7b422fcd307 100755
--- a/src/Compiler/Utilities/range.fsi
+++ b/src/Compiler/Utilities/range.fsi
@@ -122,8 +122,6 @@ type Range =
 
     /// The range where all values are zero
     static member Zero: range
-
-    member internal DebugCode: string
   
 /// Represents a range within a file
 and range = Range

From 5119bb693f2ce6a20dfb6d9f99d90e2679416d1d Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Sun, 11 Aug 2024 23:45:34 +0800
Subject: [PATCH 04/57] Read and store file content before compilation

---
 src/Compiler/Driver/CompilerConfig.fs       |  4 ++--
 src/Compiler/Driver/CompilerConfig.fsi      |  4 ++--
 src/Compiler/Driver/ScriptClosure.fs        |  1 +
 src/Compiler/Driver/fsc.fs                  |  2 ++
 src/Compiler/Interactive/fsi.fs             |  2 +-
 src/Compiler/Service/IncrementalBuild.fs    |  2 ++
 src/Compiler/Service/TransparentCompiler.fs |  2 ++
 src/Compiler/Service/service.fs             |  3 +++
 src/Compiler/TypedTree/TcGlobals.fs         | 21 +++++----------------
 src/Compiler/TypedTree/TcGlobals.fsi        |  2 +-
 src/Compiler/Utilities/range.fs             | 14 ++++++++++++++
 src/Compiler/Utilities/range.fsi            |  7 +++++++
 12 files changed, 42 insertions(+), 22 deletions(-)

diff --git a/src/Compiler/Driver/CompilerConfig.fs b/src/Compiler/Driver/CompilerConfig.fs
index 09818c34819..ca6d1575c67 100644
--- a/src/Compiler/Driver/CompilerConfig.fs
+++ b/src/Compiler/Driver/CompilerConfig.fs
@@ -620,7 +620,7 @@ type TcConfigBuilder =
 
         mutable realsig: bool
 
-        mutable getLine: (string -> int -> string) voption
+        mutable getLine: string -> int -> string
     }
 
     // Directories to start probing in
@@ -831,7 +831,7 @@ type TcConfigBuilder =
             dumpSignatureData = false
             realsig = true
             strictIndentation = None
-            getLine = ValueNone
+            getLine = FileContent.getLine
         }
 
     member tcConfigB.FxResolver =
diff --git a/src/Compiler/Driver/CompilerConfig.fsi b/src/Compiler/Driver/CompilerConfig.fsi
index 0a3193f6ef3..5cf3d40ccf8 100644
--- a/src/Compiler/Driver/CompilerConfig.fsi
+++ b/src/Compiler/Driver/CompilerConfig.fsi
@@ -526,7 +526,7 @@ type TcConfigBuilder =
 
         mutable realsig: bool
 
-        mutable getLine: (string -> int -> string) voption
+        mutable getLine: string -> int -> string
     }
 
     static member CreateNew:
@@ -906,7 +906,7 @@ type TcConfig =
 
     member realsig: bool
 
-    member getLine: (string -> int -> string) voption
+    member getLine: (string -> int -> string)
 
 /// Represents a computation to return a TcConfig. Normally this is just a constant immutable TcConfig,
 /// but for F# Interactive it may be based on an underlying mutable TcConfigBuilder.
diff --git a/src/Compiler/Driver/ScriptClosure.fs b/src/Compiler/Driver/ScriptClosure.fs
index 2374fd6793b..8a068671128 100644
--- a/src/Compiler/Driver/ScriptClosure.fs
+++ b/src/Compiler/Driver/ScriptClosure.fs
@@ -159,6 +159,7 @@ module ScriptPreprocessClosure =
             reduceMemoryUsage
         ) =
 
+        FileContent.readFiles [fileName]
         let projectDir = Path.GetDirectoryName fileName
         let isInteractive = (codeContext = CodeContext.CompilationAndEvaluation)
         let isInvalidationSupported = (codeContext = CodeContext.Editing)
diff --git a/src/Compiler/Driver/fsc.fs b/src/Compiler/Driver/fsc.fs
index 34322176136..d8c40781210 100644
--- a/src/Compiler/Driver/fsc.fs
+++ b/src/Compiler/Driver/fsc.fs
@@ -621,6 +621,8 @@ let main1
 
     // Register framework tcImports to be disposed in future
     disposables.Register frameworkTcImports
+    
+    FileContent.readFiles sourceFiles
 
     // Parse sourceFiles
     ReportTime tcConfig "Parse inputs"
diff --git a/src/Compiler/Interactive/fsi.fs b/src/Compiler/Interactive/fsi.fs
index b3b94bb763f..f0faafe8d2f 100644
--- a/src/Compiler/Interactive/fsi.fs
+++ b/src/Compiler/Interactive/fsi.fs
@@ -4661,7 +4661,7 @@ type FsiEvaluationSession
         if List.isEmpty fsiOptions.SourceFiles then
             fsiConsolePrompt.PrintAhead()
 
-    do tcConfigB.getLine <- ValueSome fsiStdinSyphon.GetLine
+    do tcConfigB.getLine <- fsiStdinSyphon.GetLine
 
     let fsiConsoleInput = FsiConsoleInput(fsi, fsiOptions, inReader, outWriter)
 
diff --git a/src/Compiler/Service/IncrementalBuild.fs b/src/Compiler/Service/IncrementalBuild.fs
index 43a7a9cde96..187ee95e026 100644
--- a/src/Compiler/Service/IncrementalBuild.fs
+++ b/src/Compiler/Service/IncrementalBuild.fs
@@ -1467,6 +1467,8 @@ type IncrementalBuilder(initialState: IncrementalBuilderInitialState, state: Inc
 
                 tcConfigB, sourceFilesNew
 
+            FileContent.readFiles sourceFiles
+
             // If this is a builder for a script, re-apply the settings inferred from the
             // script and its load closure to the configuration.
             //
diff --git a/src/Compiler/Service/TransparentCompiler.fs b/src/Compiler/Service/TransparentCompiler.fs
index 734dd2a1eee..27e682f94bb 100644
--- a/src/Compiler/Service/TransparentCompiler.fs
+++ b/src/Compiler/Service/TransparentCompiler.fs
@@ -817,6 +817,8 @@ type internal TransparentCompiler
 
             tcConfigB.parallelReferenceResolution <- parallelReferenceResolution
             tcConfigB.captureIdentifiersWhenParsing <- captureIdentifiersWhenParsing
+            
+            FileContent.readFiles sourceFilesNew
 
             return tcConfigB, sourceFilesNew, loadClosureOpt
         }
diff --git a/src/Compiler/Service/service.fs b/src/Compiler/Service/service.fs
index 5a1535b6f2d..b4969287384 100644
--- a/src/Compiler/Service/service.fs
+++ b/src/Compiler/Service/service.fs
@@ -643,6 +643,9 @@ type FSharpChecker
 
         // Apply command-line arguments and collect more source files if they are in the arguments
         let sourceFilesNew = ApplyCommandLineArgs(tcConfigB, sourceFiles, argv)
+        
+        FileContent.readFiles sourceFilesNew
+
         FSharpParsingOptions.FromTcConfigBuilder(tcConfigB, Array.ofList sourceFilesNew, isInteractive), errorScope.Diagnostics
 
     member ic.GetParsingOptionsFromCommandLineArgs(argv, ?isInteractive: bool, ?isEditing) =
diff --git a/src/Compiler/TypedTree/TcGlobals.fs b/src/Compiler/TypedTree/TcGlobals.fs
index 732ef43295d..8f8879f0360 100644
--- a/src/Compiler/TypedTree/TcGlobals.fs
+++ b/src/Compiler/TypedTree/TcGlobals.fs
@@ -191,7 +191,8 @@ type TcGlobals(
     pathMap: PathMap,
     langVersion: LanguageVersion,
     realsig: bool,
-    getLine: (string -> int -> string) voption) =
+    // Get a line string from a code file. Use to implement `CallerArgumentExpression`
+    getLine: string -> int -> string) =
 
   let v_langFeatureNullness = langVersion.SupportsFeature LanguageFeature.NullnessChecking
 
@@ -1985,21 +1986,9 @@ type TcGlobals(
     let startCol = m.StartColumn - 1
 
     let s = 
-        match getLine with
-        | ValueSome f -> 
-            [for i in m.StartLine..m.EndLine -> f m.FileName i]
-            |> String.concat "\n"
-        | ValueNone -> 
-            try
-                if FileSystem.IsInvalidPathShim m.FileName || 
-                   not (FileSystem.FileExistsShim m.FileName) then
-                    System.String.Empty
-                else
-                    FileSystem.OpenFileForReadShim(m.FileName).ReadLines()
-                    |> Seq.skip (m.StartLine - 1)
-                    |> Seq.take (m.EndLine - m.StartLine + 1)
-                    |> String.concat "\n"
-            with e -> System.String.Empty
+        [| for i in m.StartLine..m.EndLine -> getLine m.FileName i |]
+        |> String.concat "\n"
+    printfn "%A" (m, s)
     if System.String.IsNullOrEmpty s then ValueNone else
     ValueSome <| s.Substring(startCol + 1, s.LastIndexOf("\n", System.StringComparison.Ordinal) + 1 - startCol + endCol)
 
diff --git a/src/Compiler/TypedTree/TcGlobals.fsi b/src/Compiler/TypedTree/TcGlobals.fsi
index 0650086e708..e59a79f7904 100644
--- a/src/Compiler/TypedTree/TcGlobals.fsi
+++ b/src/Compiler/TypedTree/TcGlobals.fsi
@@ -148,7 +148,7 @@ type internal TcGlobals =
         pathMap: Internal.Utilities.PathMap *
         langVersion: FSharp.Compiler.Features.LanguageVersion *
         realsig: bool *
-        getLine: (string -> int -> string) voption ->
+        getLine: (string -> int -> string) ->
             TcGlobals
 
     static member IsInEmbeddableKnownSet: name: string -> bool
diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs
index 678ab07f452..d7191b5bf0a 100755
--- a/src/Compiler/Utilities/range.fs
+++ b/src/Compiler/Utilities/range.fs
@@ -566,3 +566,17 @@ module Range =
                     | None -> mkRange file (mkPos 1 0) (mkPos 1 80)
         with _ ->
             mkRange file (mkPos 1 0) (mkPos 1 80)
+
+module internal FileContent =
+    let private dict = ConcurrentDictionary<string, string array>()
+
+    let readFiles (fileNames: string list) =
+        for fileName in fileNames do
+            if FileSystem.FileExistsShim fileName then
+                use fileStream = FileSystem.OpenFileForReadShim(fileName)
+                dict[fileName] <- fileStream.ReadAllLines()
+
+    let getLine fileName line =
+        match dict.TryGetValue fileName with
+        | true, lines when lines.Length > line -> lines[line - 1]
+        | _ -> String.Empty
\ No newline at end of file
diff --git a/src/Compiler/Utilities/range.fsi b/src/Compiler/Utilities/range.fsi
index 7b422fcd307..ed68d7f5eb2 100755
--- a/src/Compiler/Utilities/range.fsi
+++ b/src/Compiler/Utilities/range.fsi
@@ -269,4 +269,11 @@ module Line =
     /// Convert a line number from one-based line counting (used internally in the F# compiler and in F# error messages) to zero-based line counting (used by Visual Studio)
     val toZ: int -> Line0 
 
+/// Store code file content. Use to implement `CallerArgumentExpression`
+module internal FileContent =
 
+    /// Read all file contents
+    val readFiles: fileNames: string list -> unit
+
+    /// Get a line string from already read files
+    val getLine: fileName: string -> line: int -> string

From c9146724dc068dbb0479a924280cdfd2c9d4c190 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Sun, 11 Aug 2024 23:57:44 +0800
Subject: [PATCH 05/57] Change test; Add release note

---
 .../.FSharp.Compiler.Service/9.0.100.md           |  1 +
 .../ErrorMessages/UnsupportedAttributes.fs        | 15 ++++-----------
 2 files changed, 5 insertions(+), 11 deletions(-)

diff --git a/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md
index f05d847075d..c0225d23f73 100644
--- a/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md
+++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md
@@ -13,6 +13,7 @@
 * Parser: recover on missing union case fields (PR [#17452](https://github.com/dotnet/fsharp/pull/17452))
 * Parser: recover on missing union case field types (PR [#17455](https://github.com/dotnet/fsharp/pull/17455))
 * Sink: report function domain type ([PR #17470](https://github.com/dotnet/fsharp/pull/17470))
+* Support `CallerArgumentExpression` ([Language Suggestion #966](https://github.com/fsharp/fslang-suggestions/issues/966), [PR #17519](https://github.com/dotnet/fsharp/pull/17519))
 
 ### Changed
 
diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnsupportedAttributes.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnsupportedAttributes.fs
index 3eb78de55b4..a117a089a03 100644
--- a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnsupportedAttributes.fs
+++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnsupportedAttributes.fs
@@ -23,13 +23,6 @@ type C() =
         |> typecheck
         |> shouldFail
         |> withResults [
-            { Error = Warning 202
-              Range = { StartLine = 3
-                        StartColumn = 13
-                        EndLine = 3
-                        EndColumn = 41 }
-              Message =
-               "This attribute is currently unsupported by the F# compiler. Applying it will not achieve its intended effect." }
             { Error = Warning 202
               Range = { StartLine = 4
                         StartColumn = 7
@@ -37,13 +30,13 @@ type C() =
                         EndColumn = 24 }
               Message =
                "This attribute is currently unsupported by the F# compiler. Applying it will not achieve its intended effect." }
-            { Error = Warning 202
+            { Error = Warning 1247
               Range = { StartLine = 6
-                        StartColumn = 22
+                        StartColumn = 14
                         EndLine = 6
-                        EndColumn = 82 }
+                        EndColumn = 15 }
               Message =
-               "This attribute is currently unsupported by the F# compiler. Applying it will not achieve its intended effect." }
+               "'CallerArgumentExpression \"w\"' can only be applied to optional arguments" }
             { Error = Warning 202
               Range = { StartLine = 7
                         StartColumn = 7

From 536cf34cc6a4b266ddd1073d86386fb9e47e0805 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Mon, 12 Aug 2024 00:45:04 +0800
Subject: [PATCH 06/57] Add tests Put under lang version flag

---
 src/Compiler/Checking/MethodCalls.fs          |  2 +-
 src/Compiler/FSComp.txt                       |  1 +
 src/Compiler/Facilities/LanguageFeatures.fs   |  3 ++
 src/Compiler/Facilities/LanguageFeatures.fsi  |  1 +
 src/Compiler/TypedTree/TcGlobals.fs           |  1 -
 .../CallerArgumentExpression.fs               | 43 +++++++++++++++++++
 .../ErrorMessages/UnsupportedAttributes.fs    |  2 +-
 .../FSharp.Compiler.ComponentTests.fsproj     |  2 +
 8 files changed, 52 insertions(+), 3 deletions(-)
 create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs

diff --git a/src/Compiler/Checking/MethodCalls.fs b/src/Compiler/Checking/MethodCalls.fs
index 7dda8b368d2..977ee8b5bc9 100644
--- a/src/Compiler/Checking/MethodCalls.fs
+++ b/src/Compiler/Checking/MethodCalls.fs
@@ -1425,7 +1425,7 @@ let rec GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g (calledArg: C
                 emptyPreBinder, Expr.Const (Const.String fileName, mMethExpr, currCalledArgTy)
             | CallerMemberName, Some callerName when (typeEquiv g currCalledArgTy g.string_ty) ->
                 emptyPreBinder, Expr.Const (Const.String callerName, mMethExpr, currCalledArgTy)
-            | CallerArgumentExpression param, _ when typeEquiv g currCalledArgTy g.string_ty ->
+            | CallerArgumentExpression param, _ when g.langVersion.SupportsFeature LanguageFeature.SupportCallerArgumentExpression && typeEquiv g currCalledArgTy g.string_ty ->
                 let str =
                     unnamedArgs
                     |> List.tryPick (fun { CalledArg=called; CallerArg=caller } -> 
diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt
index 62412a7698a..e313e8f96bf 100644
--- a/src/Compiler/FSComp.txt
+++ b/src/Compiler/FSComp.txt
@@ -1776,3 +1776,4 @@ featureParsedHashDirectiveArgumentNonString,"# directives with non-quoted string
 3869,featureParsedHashDirectiveUnexpectedIdentifier,"Unexpected identifier '%s'."
 featureEmptyBodiedComputationExpressions,"Support for computation expressions with empty bodies: builder {{ }}"
 3870,parsExpectingUnionCaseField,"Expecting union case field"
+featureEmptyBodiedComputationExpressions,"Support `CallerArgumentExpression`"
\ No newline at end of file
diff --git a/src/Compiler/Facilities/LanguageFeatures.fs b/src/Compiler/Facilities/LanguageFeatures.fs
index 2fd2e150bcc..3cd1c36bdb3 100644
--- a/src/Compiler/Facilities/LanguageFeatures.fs
+++ b/src/Compiler/Facilities/LanguageFeatures.fs
@@ -92,6 +92,7 @@ type LanguageFeature =
     | LowerSimpleMappingsInComprehensionsToFastLoops
     | ParsedHashDirectiveArgumentNonQuotes
     | EmptyBodiedComputationExpressions
+    | SupportCallerArgumentExpression
 
 /// LanguageVersion management
 type LanguageVersion(versionText) =
@@ -215,6 +216,7 @@ type LanguageVersion(versionText) =
                 LanguageFeature.UnmanagedConstraintCsharpInterop, previewVersion // not enabled because: https://github.com/dotnet/fsharp/issues/17509
                 LanguageFeature.EnforceAttributeTargets, previewVersion // not enabled because: https://github.com/dotnet/fsharp/issues/17514
                 LanguageFeature.FromEndSlicing, previewVersion // Unfinished features --- needs work
+                LanguageFeature.SupportCallerArgumentExpression, previewVersion
             ]
 
     static let defaultLanguageVersion = LanguageVersion("default")
@@ -368,6 +370,7 @@ type LanguageVersion(versionText) =
             FSComp.SR.featureLowerSimpleMappingsInComprehensionsToFastLoops ()
         | LanguageFeature.ParsedHashDirectiveArgumentNonQuotes -> FSComp.SR.featureParsedHashDirectiveArgumentNonString ()
         | LanguageFeature.EmptyBodiedComputationExpressions -> FSComp.SR.featureEmptyBodiedComputationExpressions ()
+        | LanguageFeature.SupportCallerArgumentExpression -> FSComp.SR.featureSupportCallerArgumentExpression ()
 
     /// Get a version string associated with the given feature.
     static member GetFeatureVersionString feature =
diff --git a/src/Compiler/Facilities/LanguageFeatures.fsi b/src/Compiler/Facilities/LanguageFeatures.fsi
index 64f20d3f55a..0fc4d71cec2 100644
--- a/src/Compiler/Facilities/LanguageFeatures.fsi
+++ b/src/Compiler/Facilities/LanguageFeatures.fsi
@@ -83,6 +83,7 @@ type LanguageFeature =
     | LowerSimpleMappingsInComprehensionsToFastLoops
     | ParsedHashDirectiveArgumentNonQuotes
     | EmptyBodiedComputationExpressions
+    | SupportCallerArgumentExpression
 
 /// LanguageVersion management
 type LanguageVersion =
diff --git a/src/Compiler/TypedTree/TcGlobals.fs b/src/Compiler/TypedTree/TcGlobals.fs
index 8f8879f0360..4d223773a78 100644
--- a/src/Compiler/TypedTree/TcGlobals.fs
+++ b/src/Compiler/TypedTree/TcGlobals.fs
@@ -1988,7 +1988,6 @@ type TcGlobals(
     let s = 
         [| for i in m.StartLine..m.EndLine -> getLine m.FileName i |]
         |> String.concat "\n"
-    printfn "%A" (m, s)
     if System.String.IsNullOrEmpty s then ValueNone else
     ValueSome <| s.Substring(startCol + 1, s.LastIndexOf("\n", System.StringComparison.Ordinal) + 1 - startCol + endCol)
 
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
new file mode 100644
index 00000000000..78e7917e555
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
@@ -0,0 +1,43 @@
+// Copyright (c) Microsoft Corporation.  All Rights Reserved.  See License.txt in the project root for license information.
+
+namespace Conformance.BasicGrammarElements
+
+open Xunit
+open FSharp.Test.Compiler
+
+module CustomAttributes_CallerArgumentExpression =
+
+    [<Fact>]
+    let ``Can consume CallerArgumentExpression in BCL methods`` () =
+        FSharp """
+try System.ArgumentNullException.ThrowIfNullOrWhiteSpace(Seq.init 50 (fun _ -> " ")
+  (* comment *) 
+  |> String.concat " ")
+with :? System.ArgumentException as ex -> 
+  assert (ex.Message.Contains("(Parameter 'Seq.init 50 (fun _ -> \" \")\n  (* comment *) \n  |> String.concat \" \""))
+"""
+        |> withLangVersionPreview
+        |> compileAndRun
+        |> shouldSucceed
+        |> ignore
+
+    [<Fact>]
+    let ``Can define in F#`` () =
+        FSharp """# 1 "C:\\Program.fs"
+open System.Runtime.InteropServices
+type A() =
+static member aa (
+    a,
+    [<CallerMemberName; Optional; DefaultParameterValue "no value">]b: string, 
+    [<CallerLineNumber; Optional; DefaultParameterValue 0>]c: int, 
+    [<CallerFilePath; Optional; DefaultParameterValue "no value">]d: string, 
+    [<CallerArgumentExpressionAttribute("a"); Optional; DefaultParameterValue "no value">]e: string) = 
+    a,b,c,d,e
+
+let stringABC = "abc"
+assert (A.aa(stringABC) = ("abc", ".ctor", 12, "C:\Program.fs", "stringABC"))
+        """
+        |> withLangVersionPreview
+        |> compileAndRun
+        |> shouldSucceed
+        |> ignore
diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnsupportedAttributes.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnsupportedAttributes.fs
index a117a089a03..8f11db7aa58 100644
--- a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnsupportedAttributes.fs
+++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnsupportedAttributes.fs
@@ -30,7 +30,7 @@ type C() =
                         EndColumn = 24 }
               Message =
                "This attribute is currently unsupported by the F# compiler. Applying it will not achieve its intended effect." }
-            { Error = Warning 1247
+            { Error = Error 1247
               Range = { StartLine = 6
                         StartColumn = 14
                         EndLine = 6
diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
index 0509d424f8b..98d598800a0 100644
--- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
+++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
@@ -37,6 +37,7 @@
     <Compile Include="Conformance\BasicGrammarElements\AccessibilityAnnotations\PermittedLocations\PermittedLocations.fs" />
     <Compile Include="Conformance\BasicGrammarElements\CustomAttributes\AttributeInheritance\AttributeInheritance.fs" />
     <Compile Include="Conformance\BasicGrammarElements\CustomAttributes\AttributeUsage\AttributeUsage.fs" />
+    <Compile Include="Conformance\BasicGrammarElements\CustomAttributes\CallerArgumentExpression.fs" />
     <Compile Include="Conformance\BasicGrammarElements\CustomAttributes\Basic\Basic.fs" />
     <Compile Include="Conformance\BasicGrammarElements\CustomAttributes\ImportedAttributes\ImportedAttributes.fs" />
     <Compile Include="Conformance\BasicGrammarElements\CustomAttributes\ArgumentsOfAllTypes\ArgumentsOfAllTypes.fs" />
@@ -338,6 +339,7 @@
   <ItemGroup>
     <Content Include="resources\**" CopyToOutputDirectory="Never" CopyToPublishDirectory="PreserveNewest" />
     <EmbeddedResource Remove="Properties\**" />
+    <None Remove="Conformance\BasicGrammarElements\CustomAttributes\CallerArgumentExpression.fs" />
     <None Remove="EmittedIL\GenericComparison\CrossAssembly.fs" />
     <None Remove="ErrorMessages\ActivePatternArgCountMismatchTest.fs" />
     <Content Include="xunit.runner.json" CopyToOutputDirectory="PreserveNewest" />

From 3fc46425ca54af00d0ec9c78fe93ac23fa1749ad Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Mon, 12 Aug 2024 00:57:06 +0800
Subject: [PATCH 07/57] fix build; format

---
 docs/release-notes/.Language/preview.md     | 1 +
 src/Compiler/Driver/ScriptClosure.fs        | 2 +-
 src/Compiler/Driver/fsc.fs                  | 2 +-
 src/Compiler/FSComp.txt                     | 2 +-
 src/Compiler/Service/TransparentCompiler.fs | 2 +-
 src/Compiler/Service/service.fs             | 2 +-
 src/Compiler/Utilities/range.fs             | 2 +-
 7 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/docs/release-notes/.Language/preview.md b/docs/release-notes/.Language/preview.md
index 6c2d5f0597b..b71dc8b0016 100644
--- a/docs/release-notes/.Language/preview.md
+++ b/docs/release-notes/.Language/preview.md
@@ -10,6 +10,7 @@
 * Allow #nowarn to support the FS prefix on error codes to disable warnings ([Issue #17206](https://github.com/dotnet/fsharp/issues/16447), [PR #17209](https://github.com/dotnet/fsharp/pull/17209))
 * Allow ParsedHashDirectives to have argument types other than strings ([Issue #17240](https://github.com/dotnet/fsharp/issues/16447), [PR #17209](https://github.com/dotnet/fsharp/pull/17209))
 * Support empty-bodied computation expressions. ([Language suggestion #1232](https://github.com/fsharp/fslang-suggestions/issues/1232), [PR #17352](https://github.com/dotnet/fsharp/pull/17352))
+* Support `CallerArgumentExpression` ([Language Suggestion #966](https://github.com/fsharp/fslang-suggestions/issues/966), [PR #17519](https://github.com/dotnet/fsharp/pull/17519))
 
 ### Fixed
 
diff --git a/src/Compiler/Driver/ScriptClosure.fs b/src/Compiler/Driver/ScriptClosure.fs
index 8a068671128..6ed6b5077cb 100644
--- a/src/Compiler/Driver/ScriptClosure.fs
+++ b/src/Compiler/Driver/ScriptClosure.fs
@@ -159,7 +159,7 @@ module ScriptPreprocessClosure =
             reduceMemoryUsage
         ) =
 
-        FileContent.readFiles [fileName]
+        FileContent.readFiles [ fileName ]
         let projectDir = Path.GetDirectoryName fileName
         let isInteractive = (codeContext = CodeContext.CompilationAndEvaluation)
         let isInvalidationSupported = (codeContext = CodeContext.Editing)
diff --git a/src/Compiler/Driver/fsc.fs b/src/Compiler/Driver/fsc.fs
index d8c40781210..b4215e971ea 100644
--- a/src/Compiler/Driver/fsc.fs
+++ b/src/Compiler/Driver/fsc.fs
@@ -621,7 +621,7 @@ let main1
 
     // Register framework tcImports to be disposed in future
     disposables.Register frameworkTcImports
-    
+
     FileContent.readFiles sourceFiles
 
     // Parse sourceFiles
diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt
index e313e8f96bf..a816a48cbfc 100644
--- a/src/Compiler/FSComp.txt
+++ b/src/Compiler/FSComp.txt
@@ -1776,4 +1776,4 @@ featureParsedHashDirectiveArgumentNonString,"# directives with non-quoted string
 3869,featureParsedHashDirectiveUnexpectedIdentifier,"Unexpected identifier '%s'."
 featureEmptyBodiedComputationExpressions,"Support for computation expressions with empty bodies: builder {{ }}"
 3870,parsExpectingUnionCaseField,"Expecting union case field"
-featureEmptyBodiedComputationExpressions,"Support `CallerArgumentExpression`"
\ No newline at end of file
+featureSupportCallerArgumentExpression,"Support `CallerArgumentExpression`"
\ No newline at end of file
diff --git a/src/Compiler/Service/TransparentCompiler.fs b/src/Compiler/Service/TransparentCompiler.fs
index 27e682f94bb..2f5b8de8d5d 100644
--- a/src/Compiler/Service/TransparentCompiler.fs
+++ b/src/Compiler/Service/TransparentCompiler.fs
@@ -817,7 +817,7 @@ type internal TransparentCompiler
 
             tcConfigB.parallelReferenceResolution <- parallelReferenceResolution
             tcConfigB.captureIdentifiersWhenParsing <- captureIdentifiersWhenParsing
-            
+
             FileContent.readFiles sourceFilesNew
 
             return tcConfigB, sourceFilesNew, loadClosureOpt
diff --git a/src/Compiler/Service/service.fs b/src/Compiler/Service/service.fs
index b4969287384..46d722c0a8e 100644
--- a/src/Compiler/Service/service.fs
+++ b/src/Compiler/Service/service.fs
@@ -643,7 +643,7 @@ type FSharpChecker
 
         // Apply command-line arguments and collect more source files if they are in the arguments
         let sourceFilesNew = ApplyCommandLineArgs(tcConfigB, sourceFiles, argv)
-        
+
         FileContent.readFiles sourceFilesNew
 
         FSharpParsingOptions.FromTcConfigBuilder(tcConfigB, Array.ofList sourceFilesNew, isInteractive), errorScope.Diagnostics
diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs
index d7191b5bf0a..a7118a34ed0 100755
--- a/src/Compiler/Utilities/range.fs
+++ b/src/Compiler/Utilities/range.fs
@@ -579,4 +579,4 @@ module internal FileContent =
     let getLine fileName line =
         match dict.TryGetValue fileName with
         | true, lines when lines.Length > line -> lines[line - 1]
-        | _ -> String.Empty
\ No newline at end of file
+        | _ -> String.Empty

From 550daa4daa62cabd5c2726af156798d816fab392 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Fri, 16 Aug 2024 03:35:24 +0800
Subject: [PATCH 08/57] Support `#line` Simplify code

---
 src/Compiler/Checking/MethodCalls.fs        |   6 +-
 src/Compiler/Driver/CompilerConfig.fs       |   4 -
 src/Compiler/Driver/CompilerConfig.fsi      |   4 -
 src/Compiler/Driver/CompilerImports.fs      |   3 +-
 src/Compiler/Driver/ScriptClosure.fs        |   2 +-
 src/Compiler/Driver/fsc.fs                  |   2 +-
 src/Compiler/Facilities/prim-lexing.fs      |  16 +-
 src/Compiler/Facilities/prim-lexing.fsi     |   2 +
 src/Compiler/Interactive/fsi.fs             |  11 +-
 src/Compiler/Service/IncrementalBuild.fs    |   2 +-
 src/Compiler/Service/TransparentCompiler.fs |   2 +-
 src/Compiler/Service/service.fs             |   2 +-
 src/Compiler/SyntaxTree/ParseHelpers.fs     |   7 +-
 src/Compiler/TypedTree/TcGlobals.fs         |  14 +-
 src/Compiler/TypedTree/TcGlobals.fsi        |   3 +-
 src/Compiler/Utilities/range.fs             | 154 ++++++++++++++++++--
 src/Compiler/Utilities/range.fsi            |  50 ++++++-
 src/Compiler/xlf/FSComp.txt.cs.xlf          |   5 +
 src/Compiler/xlf/FSComp.txt.de.xlf          |   5 +
 src/Compiler/xlf/FSComp.txt.es.xlf          |   5 +
 src/Compiler/xlf/FSComp.txt.fr.xlf          |   5 +
 src/Compiler/xlf/FSComp.txt.it.xlf          |   5 +
 src/Compiler/xlf/FSComp.txt.ja.xlf          |   5 +
 src/Compiler/xlf/FSComp.txt.ko.xlf          |   5 +
 src/Compiler/xlf/FSComp.txt.pl.xlf          |   5 +
 src/Compiler/xlf/FSComp.txt.pt-BR.xlf       |   5 +
 src/Compiler/xlf/FSComp.txt.ru.xlf          |   5 +
 src/Compiler/xlf/FSComp.txt.tr.xlf          |   5 +
 src/Compiler/xlf/FSComp.txt.zh-Hans.xlf     |   5 +
 src/Compiler/xlf/FSComp.txt.zh-Hant.xlf     |   5 +
 30 files changed, 293 insertions(+), 56 deletions(-)

diff --git a/src/Compiler/Checking/MethodCalls.fs b/src/Compiler/Checking/MethodCalls.fs
index 977ee8b5bc9..3cb8ec6c846 100644
--- a/src/Compiler/Checking/MethodCalls.fs
+++ b/src/Compiler/Checking/MethodCalls.fs
@@ -1431,9 +1431,9 @@ let rec GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g (calledArg: C
                     |> List.tryPick (fun { CalledArg=called; CallerArg=caller } -> 
                         match called.NameOpt with
                         | Some x when x.idText = param ->
-                            match g.GetCodeText caller.Range with
-                            | ValueSome code -> Some (Const.String code)
-                            | ValueNone -> None
+                            let code = FileContent.getCodeText caller.Range
+                            if System.String.IsNullOrEmpty code then None
+                            else Some (Const.String code)
                         | _ -> None)
                     |> Option.defaultWith (fun _ -> tcFieldInit mMethExpr fieldInit)
                 emptyPreBinder, Expr.Const (str, mMethExpr, currCalledArgTy)
diff --git a/src/Compiler/Driver/CompilerConfig.fs b/src/Compiler/Driver/CompilerConfig.fs
index ca6d1575c67..4a1d0d18c74 100644
--- a/src/Compiler/Driver/CompilerConfig.fs
+++ b/src/Compiler/Driver/CompilerConfig.fs
@@ -619,8 +619,6 @@ type TcConfigBuilder =
         mutable dumpSignatureData: bool
 
         mutable realsig: bool
-
-        mutable getLine: string -> int -> string
     }
 
     // Directories to start probing in
@@ -831,7 +829,6 @@ type TcConfigBuilder =
             dumpSignatureData = false
             realsig = true
             strictIndentation = None
-            getLine = FileContent.getLine
         }
 
     member tcConfigB.FxResolver =
@@ -1376,7 +1373,6 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) =
     member _.typeCheckingConfig = data.typeCheckingConfig
     member _.dumpSignatureData = data.dumpSignatureData
     member _.realsig = data.realsig
-    member _.getLine = data.getLine
 
     static member Create(builder, validate) =
         use _ = UseBuildPhase BuildPhase.Parameter
diff --git a/src/Compiler/Driver/CompilerConfig.fsi b/src/Compiler/Driver/CompilerConfig.fsi
index 5cf3d40ccf8..f21ae429029 100644
--- a/src/Compiler/Driver/CompilerConfig.fsi
+++ b/src/Compiler/Driver/CompilerConfig.fsi
@@ -525,8 +525,6 @@ type TcConfigBuilder =
         mutable dumpSignatureData: bool
 
         mutable realsig: bool
-
-        mutable getLine: string -> int -> string
     }
 
     static member CreateNew:
@@ -906,8 +904,6 @@ type TcConfig =
 
     member realsig: bool
 
-    member getLine: (string -> int -> string)
-
 /// Represents a computation to return a TcConfig. Normally this is just a constant immutable TcConfig,
 /// but for F# Interactive it may be based on an underlying mutable TcConfigBuilder.
 [<Sealed>]
diff --git a/src/Compiler/Driver/CompilerImports.fs b/src/Compiler/Driver/CompilerImports.fs
index a1adeb451a3..334a834db32 100644
--- a/src/Compiler/Driver/CompilerImports.fs
+++ b/src/Compiler/Driver/CompilerImports.fs
@@ -2614,8 +2614,7 @@ and [<Sealed>] TcImports
                     tcConfig.noDebugAttributes,
                     tcConfig.pathMap,
                     tcConfig.langVersion,
-                    tcConfig.realsig,
-                    tcConfig.getLine
+                    tcConfig.realsig
                 )
 
 #if DEBUG
diff --git a/src/Compiler/Driver/ScriptClosure.fs b/src/Compiler/Driver/ScriptClosure.fs
index 6ed6b5077cb..5f37683445a 100644
--- a/src/Compiler/Driver/ScriptClosure.fs
+++ b/src/Compiler/Driver/ScriptClosure.fs
@@ -159,7 +159,7 @@ module ScriptPreprocessClosure =
             reduceMemoryUsage
         ) =
 
-        FileContent.readFiles [ fileName ]
+        FileContent.readFileContents [ fileName ]
         let projectDir = Path.GetDirectoryName fileName
         let isInteractive = (codeContext = CodeContext.CompilationAndEvaluation)
         let isInvalidationSupported = (codeContext = CodeContext.Editing)
diff --git a/src/Compiler/Driver/fsc.fs b/src/Compiler/Driver/fsc.fs
index b4215e971ea..71b47477476 100644
--- a/src/Compiler/Driver/fsc.fs
+++ b/src/Compiler/Driver/fsc.fs
@@ -622,7 +622,7 @@ let main1
     // Register framework tcImports to be disposed in future
     disposables.Register frameworkTcImports
 
-    FileContent.readFiles sourceFiles
+    FileContent.readFileContents sourceFiles
 
     // Parse sourceFiles
     ReportTime tcConfig "Parse inputs"
diff --git a/src/Compiler/Facilities/prim-lexing.fs b/src/Compiler/Facilities/prim-lexing.fs
index 6b927ef4a96..452d636a3be 100644
--- a/src/Compiler/Facilities/prim-lexing.fs
+++ b/src/Compiler/Facilities/prim-lexing.fs
@@ -206,15 +206,17 @@ open System.Collections.Generic
 [<Struct>]
 type internal Position =
     val FileIndex: int
+    val OriginalFileIndex: int
     val Line: int
     val OriginalLine: int
     val AbsoluteOffset: int
     val StartOfLineAbsoluteOffset: int
     member x.Column = x.AbsoluteOffset - x.StartOfLineAbsoluteOffset
 
-    new(fileIndex: int, line: int, originalLine: int, startOfLineAbsoluteOffset: int, absoluteOffset: int) =
+    new(fileIndex: int, originalFileIndex: int, line: int, originalLine: int, startOfLineAbsoluteOffset: int, absoluteOffset: int) =
         {
             FileIndex = fileIndex
+            OriginalFileIndex = originalFileIndex
             Line = line
             OriginalLine = originalLine
             AbsoluteOffset = absoluteOffset
@@ -222,25 +224,25 @@ type internal Position =
         }
 
     member x.NextLine =
-        Position(x.FileIndex, x.Line + 1, x.OriginalLine + 1, x.AbsoluteOffset, x.AbsoluteOffset)
+        Position(x.FileIndex, x.OriginalFileIndex, x.Line + 1, x.OriginalLine + 1, x.AbsoluteOffset, x.AbsoluteOffset)
 
     member x.EndOfToken n =
-        Position(x.FileIndex, x.Line, x.OriginalLine, x.StartOfLineAbsoluteOffset, x.AbsoluteOffset + n)
+        Position(x.FileIndex, x.OriginalFileIndex, x.Line, x.OriginalLine, x.StartOfLineAbsoluteOffset, x.AbsoluteOffset + n)
 
     member x.ShiftColumnBy by =
-        Position(x.FileIndex, x.Line, x.OriginalLine, x.StartOfLineAbsoluteOffset, x.AbsoluteOffset + by)
+        Position(x.FileIndex, x.OriginalFileIndex, x.Line, x.OriginalLine, x.StartOfLineAbsoluteOffset, x.AbsoluteOffset + by)
 
     member x.ColumnMinusOne =
-        Position(x.FileIndex, x.Line, x.OriginalLine, x.StartOfLineAbsoluteOffset, x.StartOfLineAbsoluteOffset - 1)
+        Position(x.FileIndex, x.OriginalFileIndex, x.Line, x.OriginalLine, x.StartOfLineAbsoluteOffset, x.StartOfLineAbsoluteOffset - 1)
 
     member x.ApplyLineDirective(fileIdx, line) =
-        Position(fileIdx, line, x.OriginalLine, x.AbsoluteOffset, x.AbsoluteOffset)
+        Position(fileIdx, x.OriginalFileIndex, line, x.OriginalLine + 1, x.AbsoluteOffset, x.AbsoluteOffset)
 
     override p.ToString() = $"({p.Line},{p.Column})"
 
     static member Empty = Position()
 
-    static member FirstLine fileIdx = Position(fileIdx, 1, 0, 0, 0)
+    static member FirstLine fileIdx = Position(fileIdx, fileIdx, 1, 1, 0, 0)
 
 type internal LexBufferFiller<'Char> = LexBuffer<'Char> -> unit
 
diff --git a/src/Compiler/Facilities/prim-lexing.fsi b/src/Compiler/Facilities/prim-lexing.fsi
index ff13f96c9e1..b58c3e26ef7 100644
--- a/src/Compiler/Facilities/prim-lexing.fsi
+++ b/src/Compiler/Facilities/prim-lexing.fsi
@@ -72,6 +72,8 @@ type internal Position =
     /// The file index for the file associated with the input stream, use <c>fileOfFileIndex</c> to decode
     val FileIndex: int
 
+    val OriginalFileIndex: int
+
     /// The line number in the input stream, assuming fresh positions have been updated
     /// for the new line by modifying the EndPos property of the LexBuffer.
     val Line: int
diff --git a/src/Compiler/Interactive/fsi.fs b/src/Compiler/Interactive/fsi.fs
index f0faafe8d2f..0977303e84a 100644
--- a/src/Compiler/Interactive/fsi.fs
+++ b/src/Compiler/Interactive/fsi.fs
@@ -831,6 +831,15 @@ type internal FsiStdinSyphon(errorWriter: TextWriter) =
             let lines = text.Split '\n'
             if 0 < i && i <= lines.Length then lines[i - 1] else ""
 
+    /// Gets the indicated line in the syphon text
+    member _.GetLineNoPrune fileName i =
+        if fileName <> stdinMockFileName then
+            ""
+        else
+            let text = syphonText.ToString()
+            let lines = text.Split '\n'
+            if 0 < i && i <= lines.Length then lines[i - 1] else ""
+
     /// Display the given error.
     member syphon.PrintDiagnostic(tcConfig: TcConfig, diagnostic: PhasedDiagnostic) =
         ignoreAllErrors (fun () ->
@@ -4661,7 +4670,7 @@ type FsiEvaluationSession
         if List.isEmpty fsiOptions.SourceFiles then
             fsiConsolePrompt.PrintAhead()
 
-    do tcConfigB.getLine <- fsiStdinSyphon.GetLine
+    do FileContent.getLineDynamic <- fsiStdinSyphon.GetLineNoPrune
 
     let fsiConsoleInput = FsiConsoleInput(fsi, fsiOptions, inReader, outWriter)
 
diff --git a/src/Compiler/Service/IncrementalBuild.fs b/src/Compiler/Service/IncrementalBuild.fs
index 187ee95e026..b7693da2c92 100644
--- a/src/Compiler/Service/IncrementalBuild.fs
+++ b/src/Compiler/Service/IncrementalBuild.fs
@@ -1467,7 +1467,7 @@ type IncrementalBuilder(initialState: IncrementalBuilderInitialState, state: Inc
 
                 tcConfigB, sourceFilesNew
 
-            FileContent.readFiles sourceFiles
+            FileContent.readFileContents sourceFiles
 
             // If this is a builder for a script, re-apply the settings inferred from the
             // script and its load closure to the configuration.
diff --git a/src/Compiler/Service/TransparentCompiler.fs b/src/Compiler/Service/TransparentCompiler.fs
index 2f5b8de8d5d..6b710c8a70f 100644
--- a/src/Compiler/Service/TransparentCompiler.fs
+++ b/src/Compiler/Service/TransparentCompiler.fs
@@ -818,7 +818,7 @@ type internal TransparentCompiler
             tcConfigB.parallelReferenceResolution <- parallelReferenceResolution
             tcConfigB.captureIdentifiersWhenParsing <- captureIdentifiersWhenParsing
 
-            FileContent.readFiles sourceFilesNew
+            FileContent.readFileContents sourceFilesNew
 
             return tcConfigB, sourceFilesNew, loadClosureOpt
         }
diff --git a/src/Compiler/Service/service.fs b/src/Compiler/Service/service.fs
index 46d722c0a8e..fd6a0b0f0ef 100644
--- a/src/Compiler/Service/service.fs
+++ b/src/Compiler/Service/service.fs
@@ -644,7 +644,7 @@ type FSharpChecker
         // Apply command-line arguments and collect more source files if they are in the arguments
         let sourceFilesNew = ApplyCommandLineArgs(tcConfigB, sourceFiles, argv)
 
-        FileContent.readFiles sourceFilesNew
+        FileContent.readFileContents sourceFilesNew
 
         FSharpParsingOptions.FromTcConfigBuilder(tcConfigB, Array.ofList sourceFilesNew, isInteractive), errorScope.Diagnostics
 
diff --git a/src/Compiler/SyntaxTree/ParseHelpers.fs b/src/Compiler/SyntaxTree/ParseHelpers.fs
index d90e395c0c9..d6667e75249 100644
--- a/src/Compiler/SyntaxTree/ParseHelpers.fs
+++ b/src/Compiler/SyntaxTree/ParseHelpers.fs
@@ -40,10 +40,15 @@ let warningStringOfPos (p: pos) = warningStringOfCoords p.Line p.Column
 
 /// Get an F# compiler position from a lexer position
 let posOfLexPosition (p: Position) = mkPos p.Line p.Column
+let posOfLexOriginalPosition (p: Position) = mkPos p.OriginalLine p.Column
 
 /// Get an F# compiler range from a lexer range
 let mkSynRange (p1: Position) (p2: Position) =
-    mkFileIndexRange p1.FileIndex (posOfLexPosition p1) (posOfLexPosition p2)
+    if p1.OriginalFileIndex <> p1.FileIndex || p1.OriginalLine <> p2.Line then
+        mkFileIndexRangeWithOriginRange
+            p1.FileIndex (posOfLexPosition p1) (posOfLexPosition p2)
+            p1.OriginalFileIndex (posOfLexOriginalPosition p1) (posOfLexOriginalPosition p2)
+    else mkFileIndexRange p1.FileIndex (posOfLexPosition p1) (posOfLexPosition p2)
 
 type LexBuffer<'Char> with
 
diff --git a/src/Compiler/TypedTree/TcGlobals.fs b/src/Compiler/TypedTree/TcGlobals.fs
index 4d223773a78..fbc5af28fc1 100644
--- a/src/Compiler/TypedTree/TcGlobals.fs
+++ b/src/Compiler/TypedTree/TcGlobals.fs
@@ -190,9 +190,7 @@ type TcGlobals(
     noDebugAttributes: bool,
     pathMap: PathMap,
     langVersion: LanguageVersion,
-    realsig: bool,
-    // Get a line string from a code file. Use to implement `CallerArgumentExpression`
-    getLine: string -> int -> string) =
+    realsig: bool) =
 
   let v_langFeatureNullness = langVersion.SupportsFeature LanguageFeature.NullnessChecking
 
@@ -1981,16 +1979,6 @@ type TcGlobals(
     | _ ->
         None
 
-  member _.GetCodeText (m: Text.Range) =
-    let endCol = m.EndColumn - 1
-    let startCol = m.StartColumn - 1
-
-    let s = 
-        [| for i in m.StartLine..m.EndLine -> getLine m.FileName i |]
-        |> String.concat "\n"
-    if System.String.IsNullOrEmpty s then ValueNone else
-    ValueSome <| s.Substring(startCol + 1, s.LastIndexOf("\n", System.StringComparison.Ordinal) + 1 - startCol + endCol)
-
 #if DEBUG
 // This global is only used during debug output
 let mutable global_g = None : TcGlobals option
diff --git a/src/Compiler/TypedTree/TcGlobals.fsi b/src/Compiler/TypedTree/TcGlobals.fsi
index e59a79f7904..c970c4a52cc 100644
--- a/src/Compiler/TypedTree/TcGlobals.fsi
+++ b/src/Compiler/TypedTree/TcGlobals.fsi
@@ -147,8 +147,7 @@ type internal TcGlobals =
         noDebugAttributes: bool *
         pathMap: Internal.Utilities.PathMap *
         langVersion: FSharp.Compiler.Features.LanguageVersion *
-        realsig: bool *
-        getLine: (string -> int -> string) ->
+        realsig: bool ->
             TcGlobals
 
     static member IsInEmbeddableKnownSet: name: string -> bool
diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs
index a7118a34ed0..ac081f9df93 100755
--- a/src/Compiler/Utilities/range.fs
+++ b/src/Compiler/Utilities/range.fs
@@ -260,8 +260,8 @@ module FileIndex =
 
 [<Struct; CustomEquality; NoComparison>]
 [<System.Diagnostics.DebuggerDisplay("({StartLine},{StartColumn}-{EndLine},{EndColumn}) {ShortFileName} -> {DebugCode}")>]
-type Range(code1: int64, code2: int64) =
-    static member Zero = range (0L, 0L)
+type _Range(code1: int64, code2: int64) =
+    static member Zero = _range (0L, 0L)
 
     new(fIdx, bl, bc, el, ec) =
         let code1 =
@@ -273,9 +273,9 @@ type Range(code1: int64, code2: int64) =
             ((int64 bl <<< startLineShift) &&& startLineMask)
             ||| ((int64 (el - bl) <<< heightShift) &&& heightMask)
 
-        range (code1, code2)
+        _range (code1, code2)
 
-    new(fIdx, b: pos, e: pos) = range (fIdx, b.Line, b.Column, e.Line, e.Column)
+    new(fIdx, b: pos, e: pos) = _range (fIdx, b.Line, b.Column, e.Line, e.Column)
 
     member _.StartLine = int32 (uint64 (code2 &&& startLineMask) >>> startLineShift)
 
@@ -307,18 +307,18 @@ type Range(code1: int64, code2: int64) =
 
     member _.FileIndex = int32 (code1 &&& fileIndexMask)
 
-    member m.StartRange = range (m.FileIndex, m.Start, m.Start)
+    member m.StartRange = _range (m.FileIndex, m.Start, m.Start)
 
-    member m.EndRange = range (m.FileIndex, m.End, m.End)
+    member m.EndRange = _range (m.FileIndex, m.End, m.End)
 
     member m.FileName = fileOfFileIndex m.FileIndex
 
     member m.ShortFileName = Path.GetFileName(fileOfFileIndex m.FileIndex)
 
     member _.MakeSynthetic() =
-        range (code1, code2 ||| isSyntheticMask)
+        _range (code1, code2 ||| isSyntheticMask)
 
-    member m.IsAdjacentTo(otherRange: Range) =
+    member m.IsAdjacentTo(otherRange: _Range) =
         m.FileIndex = otherRange.FileIndex && m.End.Encoding = otherRange.Start.Encoding
 
     member _.NoteSourceConstruct(kind) =
@@ -335,7 +335,7 @@ type Range(code1: int64, code2: int64) =
             | NotedSourceConstruct.Combine -> 8
             | NotedSourceConstruct.DelayOrQuoteOrRun -> 9
 
-        range (code1, (code2 &&& ~~~debugPointKindMask) ||| (int64 code <<< debugPointKindShift))
+        _range (code1, (code2 &&& ~~~debugPointKindMask) ||| (int64 code <<< debugPointKindShift))
 
     member _.Code1 = code1
 
@@ -369,14 +369,14 @@ type Range(code1: int64, code2: int64) =
             with e ->
                 e.ToString()
 
-    member _.Equals(m2: range) =
+    member _.Equals(m2: _range) =
         let code2 = code2 &&& ~~~(debugPointKindMask ||| isSyntheticMask)
         let rcode2 = m2.Code2 &&& ~~~(debugPointKindMask ||| isSyntheticMask)
         code1 = m2.Code1 && code2 = rcode2
 
     override m.Equals(obj) =
         match obj with
-        | :? range as m2 -> m.Equals(m2)
+        | :? _range as m2 -> m.Equals(m2)
         | _ -> false
 
     override _.GetHashCode() =
@@ -386,6 +386,112 @@ type Range(code1: int64, code2: int64) =
     override r.ToString() =
         sprintf "(%d,%d--%d,%d)" r.StartLine r.StartColumn r.EndLine r.EndColumn
 
+    member m.IsZero = m.Equals _range.Zero
+
+and _range = _Range
+
+
+[<Struct; CustomEquality; NoComparison>]
+[<System.Diagnostics.DebuggerDisplay("({OriginalStartLine},{OriginalStartColumn}-{OriginalEndLine},{OriginalEndColumn}) {OriginalShortFileName} -> ({StartLine},{StartColumn}-{EndLine},{EndColumn}) {ShortFileName} -> {DebugCode}")>]
+type Range(range1: _range, range2: _range) =
+    static member Zero = range (_range.Zero, _range.Zero)
+    
+    new(fIdx, bl, bc, el, ec) = 
+        range(_range (fIdx, bl, bc, el, ec), _Range.Zero)
+
+    new(fIdx, bl, bc, el, ec, fIdx2, bl2, bc2, el2, ec2) = 
+        range(_range (fIdx, bl, bc, el, ec), _range (fIdx2, bl2, bc2, el2, ec2))
+
+    new(fIdx, b: pos, e: pos) = range (_range(fIdx, b.Line, b.Column, e.Line, e.Column), _range.Zero)
+
+    new(fIdx, b: pos, e: pos, fIdx2, b2: pos, e2: pos) = range (_range(fIdx, b.Line, b.Column, e.Line, e.Column), _range(fIdx2, b2.Line, b2.Column, e2.Line, e2.Column))
+
+    member _.StartLine = range1.StartLine
+
+    member _.StartColumn = range1.StartColumn
+
+    member _.EndLine = range1.EndLine
+
+    member _.EndColumn = range1.EndColumn
+
+    member _.IsSynthetic = range1.IsSynthetic
+
+    member _.NotedSourceConstruct = range1.NotedSourceConstruct
+
+    member _.Start = range1.Start
+
+    member _.End = range1.End
+
+    member _.FileIndex = range1.FileIndex
+
+    member _.StartRange = Range(range1.StartRange, range2.StartRange)
+
+    member _.EndRange = Range(range1.EndRange, range2.EndRange)
+
+    member _.FileName = range1.FileName
+
+    member _.ShortFileName = range1.ShortFileName
+
+    member _.MakeSynthetic() = range (range1.MakeSynthetic(), range2.MakeSynthetic())
+
+    member _.IsAdjacentTo(otherRange: Range) = range1.IsAdjacentTo otherRange.Range1
+
+    member _.NoteSourceConstruct(kind) = range(range1.NoteSourceConstruct kind, range2.NoteSourceConstruct kind)
+
+    member _.Code1 = range1.Code1
+
+    member _.Code2 = range1.Code2
+
+    member _.Range1 = range1
+
+    member _.Range2 = range2
+
+    member _.DebugCode = range1.DebugCode
+
+    member _.Equals(m2: range) = 
+        range1.Equals m2.Range1 && range2.Equals m2.Range2
+
+    override m.Equals(obj) =
+        match obj with
+        | :? range as m2 -> m.Equals(m2)
+        | _ -> false
+
+    override _.GetHashCode() = 
+        range1.GetHashCode() + range2.GetHashCode()
+
+    override _.ToString() = 
+        range1.ToString() + 
+        if range2.IsZero then String.Empty else $"(from: {range2.ToString()})"
+
+    member _.HasOriginalRange = not range2.IsZero
+
+    member _.OriginalStartLine = range2.StartLine
+
+    member _.OriginalStartColumn = range2.StartColumn
+
+    member _.OriginalEndLine = range2.EndLine
+
+    member _.OriginalEndColumn = range2.EndColumn
+
+    member _.OriginalIsSynthetic = range2.IsSynthetic
+
+    member _.OriginalNotedSourceConstruct = range2.NotedSourceConstruct
+
+    member _.OriginalStart = range2.Start
+
+    member _.OriginalEnd = range2.End
+
+    member _.OriginalFileIndex = range2.FileIndex
+
+    member _.OriginalStartRange = Range(range2.StartRange, range2.StartRange)
+
+    member _.OriginalEndRange = Range(range2.EndRange, range2.EndRange)
+
+    member _.OriginalFileName = range2.FileName
+
+    member _.OriginalShortFileName = range2.ShortFileName
+
+
 and range = Range
 
 #if CHECK_LINE0_TYPES // turn on to check that we correctly transform zero-based line counts to one-based line counts
@@ -444,6 +550,8 @@ module Range =
 
     let mkFileIndexRange fileIndex startPos endPos = range (fileIndex, startPos, endPos)
 
+    let mkFileIndexRangeWithOriginRange fileIndex startPos endPos fileIndex2 startPos2 endPos2  = range (fileIndex, startPos, endPos, fileIndex2, startPos2, endPos2)
+
     let posOrder =
         Order.orderOn (fun (p: pos) -> p.Line, p.Column) (Pair.order (Int32.order, Int32.order))
 
@@ -484,7 +592,11 @@ module Range =
                     m2
 
             let m =
-                range (m1.FileIndex, start.StartLine, start.StartColumn, finish.EndLine, finish.EndColumn)
+                if m1.OriginalFileIndex = m2.OriginalFileIndex then
+                    range (m1.FileIndex, start.StartLine, start.StartColumn, finish.EndLine, finish.EndColumn,
+                            m1.OriginalFileIndex, start.OriginalStartLine, start.OriginalStartColumn, finish.OriginalEndLine, finish.OriginalEndColumn)
+                else
+                    range (m1.FileIndex, start.StartLine, start.StartColumn, finish.EndLine, finish.EndColumn)
 
             if m1.IsSynthetic || m2.IsSynthetic then
                 m.MakeSynthetic()
@@ -570,7 +682,7 @@ module Range =
 module internal FileContent =
     let private dict = ConcurrentDictionary<string, string array>()
 
-    let readFiles (fileNames: string list) =
+    let readFileContents (fileNames: string list) =
         for fileName in fileNames do
             if FileSystem.FileExistsShim fileName then
                 use fileStream = FileSystem.OpenFileForReadShim(fileName)
@@ -580,3 +692,19 @@ module internal FileContent =
         match dict.TryGetValue fileName with
         | true, lines when lines.Length > line -> lines[line - 1]
         | _ -> String.Empty
+
+    let mutable getLineDynamic = getLine
+
+    let getCodeText (m: range) =
+        let endCol = m.EndColumn - 1
+        let startCol = m.StartColumn - 1
+    
+        let s = 
+            let filename, startLine, endLine = 
+                if m.HasOriginalRange then m.OriginalFileName, m.OriginalStartLine, m.OriginalEndLine
+                else m.FileName, m.StartLine, m.EndLine
+    
+            [| for i in startLine..endLine -> getLineDynamic filename i |]
+            |> String.concat "\n"
+        if String.IsNullOrEmpty s then s else
+        s.Substring(startCol + 1, s.LastIndexOf("\n", StringComparison.Ordinal) + 1 - startCol + endCol)
\ No newline at end of file
diff --git a/src/Compiler/Utilities/range.fsi b/src/Compiler/Utilities/range.fsi
index ed68d7f5eb2..bd368f7d369 100755
--- a/src/Compiler/Utilities/range.fsi
+++ b/src/Compiler/Utilities/range.fsi
@@ -107,6 +107,44 @@ type Range =
     /// service operations like dot-completion.
     member IsSynthetic: bool 
 
+    member HasOriginalRange: bool
+
+    /// The start line of the range
+    member OriginalStartLine: int
+
+    /// The start column of the range
+    member OriginalStartColumn: int
+
+    /// The line number for the end position of the range
+    member OriginalEndLine: int
+
+    /// The column number for the end position of the range
+    member OriginalEndColumn: int
+
+    /// The start position of the range
+    member OriginalStart: pos
+
+    /// The end position of the range
+    member OriginalEnd: pos
+
+    /// The empty range that is located at the start position of the range
+    member OriginalStartRange: range
+
+    /// The empty range that is located at the end position of the range
+    member OriginalEndRange: range
+
+    /// The file index for the range
+    member internal OriginalFileIndex: int
+
+    /// The file name for the file of the range
+    member OriginalFileName: string
+
+    /// Synthetic marks ranges which are produced by intermediate compilation phases. This
+    /// bit signifies that the range covers something that should not be visible to language
+    /// service operations like dot-completion.
+    member OriginalIsSynthetic: bool 
+
+
     /// Convert a range to be synthetic
     member internal MakeSynthetic: unit -> range
 
@@ -191,6 +229,8 @@ module Range =
     /// This view of range marks uses file indexes explicitly 
     val mkFileIndexRange: FileIndex -> pos -> pos -> range
 
+    val mkFileIndexRangeWithOriginRange: FileIndex -> pos -> pos -> FileIndex -> pos -> pos -> range
+
     /// This view hides the use of file indexes and just uses filenames 
     val mkRange: string -> pos -> pos -> range
 
@@ -273,7 +313,15 @@ module Line =
 module internal FileContent =
 
     /// Read all file contents
-    val readFiles: fileNames: string list -> unit
+    val readFileContents: fileNames: string list -> unit
 
     /// Get a line string from already read files
     val getLine: fileName: string -> line: int -> string
+
+    /// Get a line string from already read files.
+    ///
+    /// Used by `getCodeText` to support `CallerArgumentExpression` in F# Interactive 
+    val mutable getLineDynamic: (string -> int -> string)
+
+    /// Get code text of the specific `range`
+    val getCodeText: range -> string
diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf
index dc578af9a99..395b62d199f 100644
--- a/src/Compiler/xlf/FSComp.txt.cs.xlf
+++ b/src/Compiler/xlf/FSComp.txt.cs.xlf
@@ -587,6 +587,11 @@
         <target state="translated">reprezentace struktury aktivních vzorů</target>
         <note />
       </trans-unit>
+      <trans-unit id="featureSupportCallerArgumentExpression">
+        <source>Support `CallerArgumentExpression`</source>
+        <target state="new">Support `CallerArgumentExpression`</target>
+        <note />
+      </trans-unit>
       <trans-unit id="featureUnionIsPropertiesVisible">
         <source>Union case test properties</source>
         <target state="translated">Vlastnosti testu případu sjednocení</target>
diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf
index 0d5007fed66..28c51bf8185 100644
--- a/src/Compiler/xlf/FSComp.txt.de.xlf
+++ b/src/Compiler/xlf/FSComp.txt.de.xlf
@@ -587,6 +587,11 @@
         <target state="translated">Strukturdarstellung für aktive Muster</target>
         <note />
       </trans-unit>
+      <trans-unit id="featureSupportCallerArgumentExpression">
+        <source>Support `CallerArgumentExpression`</source>
+        <target state="new">Support `CallerArgumentExpression`</target>
+        <note />
+      </trans-unit>
       <trans-unit id="featureUnionIsPropertiesVisible">
         <source>Union case test properties</source>
         <target state="translated">Eigenschaften von Union-Falltests</target>
diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf
index eee3b33c5c9..f6d6fd7e2ee 100644
--- a/src/Compiler/xlf/FSComp.txt.es.xlf
+++ b/src/Compiler/xlf/FSComp.txt.es.xlf
@@ -587,6 +587,11 @@
         <target state="translated">representación de struct para modelos activos</target>
         <note />
       </trans-unit>
+      <trans-unit id="featureSupportCallerArgumentExpression">
+        <source>Support `CallerArgumentExpression`</source>
+        <target state="new">Support `CallerArgumentExpression`</target>
+        <note />
+      </trans-unit>
       <trans-unit id="featureUnionIsPropertiesVisible">
         <source>Union case test properties</source>
         <target state="translated">Propiedades de prueba de caso de unión</target>
diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf
index 37b8637fac1..a51a72c8ee8 100644
--- a/src/Compiler/xlf/FSComp.txt.fr.xlf
+++ b/src/Compiler/xlf/FSComp.txt.fr.xlf
@@ -587,6 +587,11 @@
         <target state="translated">représentation de structure pour les modèles actifs</target>
         <note />
       </trans-unit>
+      <trans-unit id="featureSupportCallerArgumentExpression">
+        <source>Support `CallerArgumentExpression`</source>
+        <target state="new">Support `CallerArgumentExpression`</target>
+        <note />
+      </trans-unit>
       <trans-unit id="featureUnionIsPropertiesVisible">
         <source>Union case test properties</source>
         <target state="translated">Propriétés du test de cas d’union</target>
diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf
index 45f773a03e8..f8e336d8bc6 100644
--- a/src/Compiler/xlf/FSComp.txt.it.xlf
+++ b/src/Compiler/xlf/FSComp.txt.it.xlf
@@ -587,6 +587,11 @@
         <target state="translated">rappresentazione struct per criteri attivi</target>
         <note />
       </trans-unit>
+      <trans-unit id="featureSupportCallerArgumentExpression">
+        <source>Support `CallerArgumentExpression`</source>
+        <target state="new">Support `CallerArgumentExpression`</target>
+        <note />
+      </trans-unit>
       <trans-unit id="featureUnionIsPropertiesVisible">
         <source>Union case test properties</source>
         <target state="translated">Proprietà test case di unione</target>
diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf
index c4b21520176..8123f554cb4 100644
--- a/src/Compiler/xlf/FSComp.txt.ja.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ja.xlf
@@ -587,6 +587,11 @@
         <target state="translated">アクティブなパターンの構造体表現</target>
         <note />
       </trans-unit>
+      <trans-unit id="featureSupportCallerArgumentExpression">
+        <source>Support `CallerArgumentExpression`</source>
+        <target state="new">Support `CallerArgumentExpression`</target>
+        <note />
+      </trans-unit>
       <trans-unit id="featureUnionIsPropertiesVisible">
         <source>Union case test properties</source>
         <target state="translated">ユニオン ケースのテスト プロパティ</target>
diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf
index 00d19be0919..531d4d3552d 100644
--- a/src/Compiler/xlf/FSComp.txt.ko.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ko.xlf
@@ -587,6 +587,11 @@
         <target state="translated">활성 패턴에 대한 구조체 표현</target>
         <note />
       </trans-unit>
+      <trans-unit id="featureSupportCallerArgumentExpression">
+        <source>Support `CallerArgumentExpression`</source>
+        <target state="new">Support `CallerArgumentExpression`</target>
+        <note />
+      </trans-unit>
       <trans-unit id="featureUnionIsPropertiesVisible">
         <source>Union case test properties</source>
         <target state="translated">공용 구조체 사례 테스트 속성</target>
diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf
index f9f8d75e2c0..26de66bc57b 100644
--- a/src/Compiler/xlf/FSComp.txt.pl.xlf
+++ b/src/Compiler/xlf/FSComp.txt.pl.xlf
@@ -587,6 +587,11 @@
         <target state="translated">reprezentacja struktury aktywnych wzorców</target>
         <note />
       </trans-unit>
+      <trans-unit id="featureSupportCallerArgumentExpression">
+        <source>Support `CallerArgumentExpression`</source>
+        <target state="new">Support `CallerArgumentExpression`</target>
+        <note />
+      </trans-unit>
       <trans-unit id="featureUnionIsPropertiesVisible">
         <source>Union case test properties</source>
         <target state="translated">Właściwości testowe przypadku unii</target>
diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
index b6ecb582a3d..ff5b0825181 100644
--- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
+++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
@@ -587,6 +587,11 @@
         <target state="translated">representação estrutural para padrões ativos</target>
         <note />
       </trans-unit>
+      <trans-unit id="featureSupportCallerArgumentExpression">
+        <source>Support `CallerArgumentExpression`</source>
+        <target state="new">Support `CallerArgumentExpression`</target>
+        <note />
+      </trans-unit>
       <trans-unit id="featureUnionIsPropertiesVisible">
         <source>Union case test properties</source>
         <target state="translated">Propriedades de teste de caso de união</target>
diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf
index a55d1afade8..e89ea429b01 100644
--- a/src/Compiler/xlf/FSComp.txt.ru.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ru.xlf
@@ -587,6 +587,11 @@
         <target state="translated">представление структуры для активных шаблонов</target>
         <note />
       </trans-unit>
+      <trans-unit id="featureSupportCallerArgumentExpression">
+        <source>Support `CallerArgumentExpression`</source>
+        <target state="new">Support `CallerArgumentExpression`</target>
+        <note />
+      </trans-unit>
       <trans-unit id="featureUnionIsPropertiesVisible">
         <source>Union case test properties</source>
         <target state="translated">Свойства теста союзного случая</target>
diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf
index da224bfc0ee..cc7e1431793 100644
--- a/src/Compiler/xlf/FSComp.txt.tr.xlf
+++ b/src/Compiler/xlf/FSComp.txt.tr.xlf
@@ -587,6 +587,11 @@
         <target state="translated">etkin desenler için yapı gösterimi</target>
         <note />
       </trans-unit>
+      <trans-unit id="featureSupportCallerArgumentExpression">
+        <source>Support `CallerArgumentExpression`</source>
+        <target state="new">Support `CallerArgumentExpression`</target>
+        <note />
+      </trans-unit>
       <trans-unit id="featureUnionIsPropertiesVisible">
         <source>Union case test properties</source>
         <target state="translated">Birleşim durumu test özellikleri</target>
diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
index 26b945a8541..a8420dea45d 100644
--- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
+++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
@@ -587,6 +587,11 @@
         <target state="translated">活动模式的结构表示形式</target>
         <note />
       </trans-unit>
+      <trans-unit id="featureSupportCallerArgumentExpression">
+        <source>Support `CallerArgumentExpression`</source>
+        <target state="new">Support `CallerArgumentExpression`</target>
+        <note />
+      </trans-unit>
       <trans-unit id="featureUnionIsPropertiesVisible">
         <source>Union case test properties</source>
         <target state="translated">联合用例测试属性</target>
diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
index 16d8255e6aa..0cdb26de227 100644
--- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
+++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
@@ -587,6 +587,11 @@
         <target state="translated">現用模式的結構表示法</target>
         <note />
       </trans-unit>
+      <trans-unit id="featureSupportCallerArgumentExpression">
+        <source>Support `CallerArgumentExpression`</source>
+        <target state="new">Support `CallerArgumentExpression`</target>
+        <note />
+      </trans-unit>
       <trans-unit id="featureUnionIsPropertiesVisible">
         <source>Union case test properties</source>
         <target state="translated">聯集案例測試屬性</target>

From 5cecb20945e67e929c724681ba0659bfdf5feb74 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Fri, 16 Aug 2024 03:39:11 +0800
Subject: [PATCH 09/57] format

---
 src/Compiler/SyntaxTree/ParseHelpers.fs | 13 +++--
 src/Compiler/Utilities/range.fs         | 72 +++++++++++++++----------
 2 files changed, 54 insertions(+), 31 deletions(-)

diff --git a/src/Compiler/SyntaxTree/ParseHelpers.fs b/src/Compiler/SyntaxTree/ParseHelpers.fs
index d6667e75249..fb721bcf520 100644
--- a/src/Compiler/SyntaxTree/ParseHelpers.fs
+++ b/src/Compiler/SyntaxTree/ParseHelpers.fs
@@ -44,11 +44,16 @@ let posOfLexOriginalPosition (p: Position) = mkPos p.OriginalLine p.Column
 
 /// Get an F# compiler range from a lexer range
 let mkSynRange (p1: Position) (p2: Position) =
-    if p1.OriginalFileIndex <> p1.FileIndex || p1.OriginalLine <> p2.Line then
+    if p1.OriginalFileIndex <> p1.FileIndex || p1.OriginalLine <> p1.Line then
         mkFileIndexRangeWithOriginRange
-            p1.FileIndex (posOfLexPosition p1) (posOfLexPosition p2)
-            p1.OriginalFileIndex (posOfLexOriginalPosition p1) (posOfLexOriginalPosition p2)
-    else mkFileIndexRange p1.FileIndex (posOfLexPosition p1) (posOfLexPosition p2)
+            p1.FileIndex
+            (posOfLexPosition p1)
+            (posOfLexPosition p2)
+            p1.OriginalFileIndex
+            (posOfLexOriginalPosition p1)
+            (posOfLexOriginalPosition p2)
+    else
+        mkFileIndexRange p1.FileIndex (posOfLexPosition p1) (posOfLexPosition p2)
 
 type LexBuffer<'Char> with
 
diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs
index ac081f9df93..f51919c01a8 100755
--- a/src/Compiler/Utilities/range.fs
+++ b/src/Compiler/Utilities/range.fs
@@ -390,21 +390,19 @@ type _Range(code1: int64, code2: int64) =
 
 and _range = _Range
 
-
 [<Struct; CustomEquality; NoComparison>]
 [<System.Diagnostics.DebuggerDisplay("({OriginalStartLine},{OriginalStartColumn}-{OriginalEndLine},{OriginalEndColumn}) {OriginalShortFileName} -> ({StartLine},{StartColumn}-{EndLine},{EndColumn}) {ShortFileName} -> {DebugCode}")>]
 type Range(range1: _range, range2: _range) =
     static member Zero = range (_range.Zero, _range.Zero)
-    
-    new(fIdx, bl, bc, el, ec) = 
-        range(_range (fIdx, bl, bc, el, ec), _Range.Zero)
 
-    new(fIdx, bl, bc, el, ec, fIdx2, bl2, bc2, el2, ec2) = 
-        range(_range (fIdx, bl, bc, el, ec), _range (fIdx2, bl2, bc2, el2, ec2))
+    new(fIdx, bl, bc, el, ec) = range (_range (fIdx, bl, bc, el, ec), _Range.Zero)
+
+    new(fIdx, bl, bc, el, ec, fIdx2, bl2, bc2, el2, ec2) = range (_range (fIdx, bl, bc, el, ec), _range (fIdx2, bl2, bc2, el2, ec2))
 
-    new(fIdx, b: pos, e: pos) = range (_range(fIdx, b.Line, b.Column, e.Line, e.Column), _range.Zero)
+    new(fIdx, b: pos, e: pos) = range (_range (fIdx, b.Line, b.Column, e.Line, e.Column), _range.Zero)
 
-    new(fIdx, b: pos, e: pos, fIdx2, b2: pos, e2: pos) = range (_range(fIdx, b.Line, b.Column, e.Line, e.Column), _range(fIdx2, b2.Line, b2.Column, e2.Line, e2.Column))
+    new(fIdx, b: pos, e: pos, fIdx2, b2: pos, e2: pos) =
+        range (_range (fIdx, b.Line, b.Column, e.Line, e.Column), _range (fIdx2, b2.Line, b2.Column, e2.Line, e2.Column))
 
     member _.StartLine = range1.StartLine
 
@@ -432,11 +430,13 @@ type Range(range1: _range, range2: _range) =
 
     member _.ShortFileName = range1.ShortFileName
 
-    member _.MakeSynthetic() = range (range1.MakeSynthetic(), range2.MakeSynthetic())
+    member _.MakeSynthetic() =
+        range (range1.MakeSynthetic(), range2.MakeSynthetic())
 
     member _.IsAdjacentTo(otherRange: Range) = range1.IsAdjacentTo otherRange.Range1
 
-    member _.NoteSourceConstruct(kind) = range(range1.NoteSourceConstruct kind, range2.NoteSourceConstruct kind)
+    member _.NoteSourceConstruct(kind) =
+        range (range1.NoteSourceConstruct kind, range2.NoteSourceConstruct kind)
 
     member _.Code1 = range1.Code1
 
@@ -448,7 +448,7 @@ type Range(range1: _range, range2: _range) =
 
     member _.DebugCode = range1.DebugCode
 
-    member _.Equals(m2: range) = 
+    member _.Equals(m2: range) =
         range1.Equals m2.Range1 && range2.Equals m2.Range2
 
     override m.Equals(obj) =
@@ -456,12 +456,15 @@ type Range(range1: _range, range2: _range) =
         | :? range as m2 -> m.Equals(m2)
         | _ -> false
 
-    override _.GetHashCode() = 
+    override _.GetHashCode() =
         range1.GetHashCode() + range2.GetHashCode()
 
-    override _.ToString() = 
-        range1.ToString() + 
-        if range2.IsZero then String.Empty else $"(from: {range2.ToString()})"
+    override _.ToString() =
+        range1.ToString()
+        + if range2.IsZero then
+              String.Empty
+          else
+              $"(from: {range2.ToString()})"
 
     member _.HasOriginalRange = not range2.IsZero
 
@@ -491,7 +494,6 @@ type Range(range1: _range, range2: _range) =
 
     member _.OriginalShortFileName = range2.ShortFileName
 
-
 and range = Range
 
 #if CHECK_LINE0_TYPES // turn on to check that we correctly transform zero-based line counts to one-based line counts
@@ -550,7 +552,8 @@ module Range =
 
     let mkFileIndexRange fileIndex startPos endPos = range (fileIndex, startPos, endPos)
 
-    let mkFileIndexRangeWithOriginRange fileIndex startPos endPos fileIndex2 startPos2 endPos2  = range (fileIndex, startPos, endPos, fileIndex2, startPos2, endPos2)
+    let mkFileIndexRangeWithOriginRange fileIndex startPos endPos fileIndex2 startPos2 endPos2 =
+        range (fileIndex, startPos, endPos, fileIndex2, startPos2, endPos2)
 
     let posOrder =
         Order.orderOn (fun (p: pos) -> p.Line, p.Column) (Pair.order (Int32.order, Int32.order))
@@ -593,8 +596,18 @@ module Range =
 
             let m =
                 if m1.OriginalFileIndex = m2.OriginalFileIndex then
-                    range (m1.FileIndex, start.StartLine, start.StartColumn, finish.EndLine, finish.EndColumn,
-                            m1.OriginalFileIndex, start.OriginalStartLine, start.OriginalStartColumn, finish.OriginalEndLine, finish.OriginalEndColumn)
+                    range (
+                        m1.FileIndex,
+                        start.StartLine,
+                        start.StartColumn,
+                        finish.EndLine,
+                        finish.EndColumn,
+                        m1.OriginalFileIndex,
+                        start.OriginalStartLine,
+                        start.OriginalStartColumn,
+                        finish.OriginalEndLine,
+                        finish.OriginalEndColumn
+                    )
                 else
                     range (m1.FileIndex, start.StartLine, start.StartColumn, finish.EndLine, finish.EndColumn)
 
@@ -698,13 +711,18 @@ module internal FileContent =
     let getCodeText (m: range) =
         let endCol = m.EndColumn - 1
         let startCol = m.StartColumn - 1
-    
-        let s = 
-            let filename, startLine, endLine = 
-                if m.HasOriginalRange then m.OriginalFileName, m.OriginalStartLine, m.OriginalEndLine
-                else m.FileName, m.StartLine, m.EndLine
-    
+
+        let s =
+            let filename, startLine, endLine =
+                if m.HasOriginalRange then
+                    m.OriginalFileName, m.OriginalStartLine, m.OriginalEndLine
+                else
+                    m.FileName, m.StartLine, m.EndLine
+
             [| for i in startLine..endLine -> getLineDynamic filename i |]
             |> String.concat "\n"
-        if String.IsNullOrEmpty s then s else
-        s.Substring(startCol + 1, s.LastIndexOf("\n", StringComparison.Ordinal) + 1 - startCol + endCol)
\ No newline at end of file
+
+        if String.IsNullOrEmpty s then
+            s
+        else
+            s.Substring(startCol + 1, s.LastIndexOf("\n", StringComparison.Ordinal) + 1 - startCol + endCol)

From 1b6cd563db2c015b999ef06ba0b7456d9202249e Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Fri, 16 Aug 2024 11:15:53 +0800
Subject: [PATCH 10/57] support callee side optional arg add warning read the
 new line mark

---
 src/Compiler/Checking/MethodCalls.fs         | 20 +++++-
 src/Compiler/Checking/PostInferenceChecks.fs | 37 ++++++++--
 src/Compiler/FSComp.txt                      |  4 +-
 src/Compiler/Interactive/fsi.fs              |  8 ++-
 src/Compiler/TypedTree/TcGlobals.fsi         |  2 -
 src/Compiler/Utilities/range.fs              | 76 ++++++++++++--------
 src/Compiler/Utilities/range.fsi             |  7 +-
 src/Compiler/xlf/FSComp.txt.cs.xlf           | 10 +++
 src/Compiler/xlf/FSComp.txt.de.xlf           | 10 +++
 src/Compiler/xlf/FSComp.txt.es.xlf           | 10 +++
 src/Compiler/xlf/FSComp.txt.fr.xlf           | 10 +++
 src/Compiler/xlf/FSComp.txt.it.xlf           | 10 +++
 src/Compiler/xlf/FSComp.txt.ja.xlf           | 10 +++
 src/Compiler/xlf/FSComp.txt.ko.xlf           | 10 +++
 src/Compiler/xlf/FSComp.txt.pl.xlf           | 10 +++
 src/Compiler/xlf/FSComp.txt.pt-BR.xlf        | 10 +++
 src/Compiler/xlf/FSComp.txt.ru.xlf           | 10 +++
 src/Compiler/xlf/FSComp.txt.tr.xlf           | 10 +++
 src/Compiler/xlf/FSComp.txt.zh-Hans.xlf      | 10 +++
 src/Compiler/xlf/FSComp.txt.zh-Hant.xlf      | 10 +++
 20 files changed, 239 insertions(+), 45 deletions(-)

diff --git a/src/Compiler/Checking/MethodCalls.fs b/src/Compiler/Checking/MethodCalls.fs
index 3cb8ec6c846..a14f8ca3a00 100644
--- a/src/Compiler/Checking/MethodCalls.fs
+++ b/src/Compiler/Checking/MethodCalls.fs
@@ -1466,7 +1466,7 @@ let rec GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g (calledArg: C
 /// Get the expression that must be inserted on the caller side for a CalleeSide optional arg where
 /// no caller argument has been provided. Normally this is 'None', however CallerMemberName and friends
 /// can be used with 'CalleeSide' optional arguments
-let GetDefaultExpressionForCalleeSideOptionalArg g (calledArg: CalledArg) eCallerMemberName (mMethExpr: range) =
+let GetDefaultExpressionForCalleeSideOptionalArg g (calledArg: CalledArg) eCallerMemberName (mMethExpr: range) unnamedArgs =
     let calledArgTy = calledArg.CalledArgumentType
     let calledNonOptTy = 
         if isOptionTy g calledArgTy then 
@@ -1485,6 +1485,22 @@ let GetDefaultExpressionForCalleeSideOptionalArg g (calledArg: CalledArg) eCalle
     | CallerMemberName, Some(callerName) when typeEquiv g calledNonOptTy g.string_ty ->
         let memberNameExpr = Expr.Const (Const.String callerName, mMethExpr, calledNonOptTy)
         mkSome g calledNonOptTy memberNameExpr mMethExpr
+
+    | CallerArgumentExpression param, _ when g.langVersion.SupportsFeature LanguageFeature.SupportCallerArgumentExpression && typeEquiv g calledNonOptTy g.string_ty ->
+        let exprOpt =
+            unnamedArgs
+            |> List.tryPick (fun { CalledArg=called; CallerArg=caller } -> 
+                match called.NameOpt with
+                | Some x when x.idText = param ->
+                    let code = FileContent.getCodeText caller.Range
+                    if System.String.IsNullOrEmpty code then None
+                    else Some (Expr.Const(Const.String code, mMethExpr, calledNonOptTy))
+                | _ -> None)
+
+        match exprOpt with
+        | Some expr -> mkSome g calledNonOptTy expr mMethExpr
+        | None -> mkNone g calledNonOptTy mMethExpr
+
     | _ ->
         mkNone g calledNonOptTy mMethExpr
 
@@ -1501,7 +1517,7 @@ let GetDefaultExpressionForOptionalArg tcFieldInit g (calledArg: CalledArg) eCal
             GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g calledArg calledArgTy dfltVal eCallerMemberName mMethExpr unnamedArgs
 
         | CalleeSide ->
-            emptyPreBinder, GetDefaultExpressionForCalleeSideOptionalArg g calledArg eCallerMemberName mMethExpr
+            emptyPreBinder, GetDefaultExpressionForCalleeSideOptionalArg g calledArg eCallerMemberName mMethExpr unnamedArgs
 
     // Combine the variable allocators (if any)
     let callerArg = CallerArg(calledArgTy, mMethExpr, false, expr)
diff --git a/src/Compiler/Checking/PostInferenceChecks.fs b/src/Compiler/Checking/PostInferenceChecks.fs
index a66c2033fe1..7991a9d6107 100644
--- a/src/Compiler/Checking/PostInferenceChecks.fs
+++ b/src/Compiler/Checking/PostInferenceChecks.fs
@@ -2333,15 +2333,34 @@ let CheckEntityDefn cenv env (tycon: Entity) =
             if numCurriedArgSets > 1 && others |> List.exists (fun minfo2 -> not (IsAbstractDefaultPair2 minfo minfo2)) then
                 errorR(Error(FSComp.SR.chkDuplicateMethodCurried(nm, NicePrint.minimalStringOfType cenv.denv ty), m))
 
+            let paramDatas = minfo.GetParamDatas(cenv.amap, m, minfo.FormalMethodInst)
+
             if numCurriedArgSets > 1 &&
-               (minfo.GetParamDatas(cenv.amap, m, minfo.FormalMethodInst)
+               (paramDatas
                 |> List.existsSquared (fun (ParamData(isParamArrayArg, _isInArg, isOutArg, optArgInfo, callerInfo, _, reflArgInfo, ty)) ->
                     isParamArrayArg || isOutArg || reflArgInfo.AutoQuote || optArgInfo.IsOptional || callerInfo <> NoCallerInfo || isByrefLikeTy g m ty)) then
                 errorR(Error(FSComp.SR.chkCurriedMethodsCantHaveOutParams(), m))
 
             if numCurriedArgSets = 1 then
-                minfo.GetParamDatas(cenv.amap, m, minfo.FormalMethodInst)
-                |> List.iterSquared (fun (ParamData(_, isInArg, _, optArgInfo, callerInfo, _, _, ty)) ->
+                let paramNames =
+                    paramDatas 
+                    |> List.concat
+                    |> List.choose (fun (ParamData(_, _, _, _, _, nameOpt, _, _)) -> nameOpt)
+
+                let checkCallerArgumentExpression name (nameOpt: Ident option) =
+                    match nameOpt with
+                    | Some ident when name = ident.idText -> 
+                        warning(Error(FSComp.SR.tcCallerArgumentExpressionSelfReferential(name), m))
+                    | _ -> ()
+
+                    if
+                        paramNames
+                        |> List.exists (fun i -> name = i.idText)
+                        |> not
+                    then warning(Error(FSComp.SR.tcCallerArgumentExpressionHasInvalidParameterName(name), m))
+
+                paramDatas
+                |> List.iterSquared (fun (ParamData(_, isInArg, _, optArgInfo, callerInfo, nameOpt, _, ty)) ->
                     ignore isInArg
                     match (optArgInfo, callerInfo) with
                     | _, NoCallerInfo -> ()
@@ -2364,12 +2383,18 @@ let CheckEntityDefn cenv env (tycon: Entity) =
                     | CalleeSide, CallerMemberName ->
                         if not ((isOptionTy g ty) && (typeEquiv g g.string_ty (destOptionTy g ty))) then
                             errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfo.ToString(), "string", NicePrint.minimalStringOfType cenv.denv (destOptionTy g ty)), m))
-                    | CallerSide _, CallerArgumentExpression _ ->
+                    | CallerSide _, CallerArgumentExpression name ->
                         if not (typeEquiv g g.string_ty ty) then
                             errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfo.ToString(), "string", NicePrint.minimalStringOfType cenv.denv ty), m))
-                    | CalleeSide, CallerArgumentExpression _ ->
+
+                        checkCallerArgumentExpression name nameOpt
+
+                    | CalleeSide, CallerArgumentExpression name ->
                         if not ((isOptionTy g ty) && (typeEquiv g g.string_ty (destOptionTy g ty))) then
-                            errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfo.ToString(), "string", NicePrint.minimalStringOfType cenv.denv (destOptionTy g ty)), m)))
+                            errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfo.ToString(), "string", NicePrint.minimalStringOfType cenv.denv (destOptionTy g ty)), m))
+
+                        checkCallerArgumentExpression name nameOpt
+                )
 
         for pinfo in immediateProps do
             let nm = pinfo.PropertyName
diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt
index a816a48cbfc..c286e8896c6 100644
--- a/src/Compiler/FSComp.txt
+++ b/src/Compiler/FSComp.txt
@@ -1776,4 +1776,6 @@ featureParsedHashDirectiveArgumentNonString,"# directives with non-quoted string
 3869,featureParsedHashDirectiveUnexpectedIdentifier,"Unexpected identifier '%s'."
 featureEmptyBodiedComputationExpressions,"Support for computation expressions with empty bodies: builder {{ }}"
 3870,parsExpectingUnionCaseField,"Expecting union case field"
-featureSupportCallerArgumentExpression,"Support `CallerArgumentExpression`"
\ No newline at end of file
+featureSupportCallerArgumentExpression,"Support `CallerArgumentExpression`"
+3871,tcCallerArgumentExpressionSelfReferential,"This CallerArgumentExpression with argument '%s' will have no effect because it's self-referential."
+3871,tcCallerArgumentExpressionHasInvalidParameterName,"This CallerArgumentExpression with argument '%s' will have no effect because it's applied with an invalid parameter name."
\ No newline at end of file
diff --git a/src/Compiler/Interactive/fsi.fs b/src/Compiler/Interactive/fsi.fs
index 0977303e84a..7fc5db927c8 100644
--- a/src/Compiler/Interactive/fsi.fs
+++ b/src/Compiler/Interactive/fsi.fs
@@ -4670,7 +4670,13 @@ type FsiEvaluationSession
         if List.isEmpty fsiOptions.SourceFiles then
             fsiConsolePrompt.PrintAhead()
 
-    do FileContent.getLineDynamic <- fsiStdinSyphon.GetLineNoPrune
+    do FileContent.getLineDynamic <- 
+        { new FileContent.IFileContentGetLine with
+              member this.GetLine(fileName: string) (line: int): string = 
+                  fsiStdinSyphon.GetLineNoPrune fileName line
+
+              member this.GetLineNewLineMark _: string = 
+                  "\n" }
 
     let fsiConsoleInput = FsiConsoleInput(fsi, fsiOptions, inReader, outWriter)
 
diff --git a/src/Compiler/TypedTree/TcGlobals.fsi b/src/Compiler/TypedTree/TcGlobals.fsi
index c970c4a52cc..4ab900b1ec7 100644
--- a/src/Compiler/TypedTree/TcGlobals.fsi
+++ b/src/Compiler/TypedTree/TcGlobals.fsi
@@ -1367,8 +1367,6 @@ type internal TcGlobals =
 
     member voidptr_tcr: FSharp.Compiler.TypedTree.EntityRef
 
-    member GetCodeText: m: Text.Range -> string voption
-
 #if DEBUG
 // This global is only used during debug output
 val mutable internal global_g: TcGlobals option
diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs
index f51919c01a8..326bafeeff6 100755
--- a/src/Compiler/Utilities/range.fs
+++ b/src/Compiler/Utilities/range.fs
@@ -260,8 +260,8 @@ module FileIndex =
 
 [<Struct; CustomEquality; NoComparison>]
 [<System.Diagnostics.DebuggerDisplay("({StartLine},{StartColumn}-{EndLine},{EndColumn}) {ShortFileName} -> {DebugCode}")>]
-type _Range(code1: int64, code2: int64) =
-    static member Zero = _range (0L, 0L)
+type _RangeBackground(code1: int64, code2: int64) =
+    static member Zero = _rangeBackground (0L, 0L)
 
     new(fIdx, bl, bc, el, ec) =
         let code1 =
@@ -273,9 +273,9 @@ type _Range(code1: int64, code2: int64) =
             ((int64 bl <<< startLineShift) &&& startLineMask)
             ||| ((int64 (el - bl) <<< heightShift) &&& heightMask)
 
-        _range (code1, code2)
+        _rangeBackground (code1, code2)
 
-    new(fIdx, b: pos, e: pos) = _range (fIdx, b.Line, b.Column, e.Line, e.Column)
+    new(fIdx, b: pos, e: pos) = _rangeBackground (fIdx, b.Line, b.Column, e.Line, e.Column)
 
     member _.StartLine = int32 (uint64 (code2 &&& startLineMask) >>> startLineShift)
 
@@ -307,18 +307,18 @@ type _Range(code1: int64, code2: int64) =
 
     member _.FileIndex = int32 (code1 &&& fileIndexMask)
 
-    member m.StartRange = _range (m.FileIndex, m.Start, m.Start)
+    member m.StartRange = _rangeBackground (m.FileIndex, m.Start, m.Start)
 
-    member m.EndRange = _range (m.FileIndex, m.End, m.End)
+    member m.EndRange = _rangeBackground (m.FileIndex, m.End, m.End)
 
     member m.FileName = fileOfFileIndex m.FileIndex
 
     member m.ShortFileName = Path.GetFileName(fileOfFileIndex m.FileIndex)
 
     member _.MakeSynthetic() =
-        _range (code1, code2 ||| isSyntheticMask)
+        _rangeBackground (code1, code2 ||| isSyntheticMask)
 
-    member m.IsAdjacentTo(otherRange: _Range) =
+    member m.IsAdjacentTo(otherRange: _RangeBackground) =
         m.FileIndex = otherRange.FileIndex && m.End.Encoding = otherRange.Start.Encoding
 
     member _.NoteSourceConstruct(kind) =
@@ -335,7 +335,7 @@ type _Range(code1: int64, code2: int64) =
             | NotedSourceConstruct.Combine -> 8
             | NotedSourceConstruct.DelayOrQuoteOrRun -> 9
 
-        _range (code1, (code2 &&& ~~~debugPointKindMask) ||| (int64 code <<< debugPointKindShift))
+        _rangeBackground (code1, (code2 &&& ~~~debugPointKindMask) ||| (int64 code <<< debugPointKindShift))
 
     member _.Code1 = code1
 
@@ -369,14 +369,14 @@ type _Range(code1: int64, code2: int64) =
             with e ->
                 e.ToString()
 
-    member _.Equals(m2: _range) =
+    member _.Equals(m2: _rangeBackground) =
         let code2 = code2 &&& ~~~(debugPointKindMask ||| isSyntheticMask)
         let rcode2 = m2.Code2 &&& ~~~(debugPointKindMask ||| isSyntheticMask)
         code1 = m2.Code1 && code2 = rcode2
 
     override m.Equals(obj) =
         match obj with
-        | :? _range as m2 -> m.Equals(m2)
+        | :? _rangeBackground as m2 -> m.Equals(m2)
         | _ -> false
 
     override _.GetHashCode() =
@@ -386,23 +386,23 @@ type _Range(code1: int64, code2: int64) =
     override r.ToString() =
         sprintf "(%d,%d--%d,%d)" r.StartLine r.StartColumn r.EndLine r.EndColumn
 
-    member m.IsZero = m.Equals _range.Zero
+    member m.IsZero = m.Equals _rangeBackground.Zero
 
-and _range = _Range
+and _rangeBackground = _RangeBackground
 
 [<Struct; CustomEquality; NoComparison>]
 [<System.Diagnostics.DebuggerDisplay("({OriginalStartLine},{OriginalStartColumn}-{OriginalEndLine},{OriginalEndColumn}) {OriginalShortFileName} -> ({StartLine},{StartColumn}-{EndLine},{EndColumn}) {ShortFileName} -> {DebugCode}")>]
-type Range(range1: _range, range2: _range) =
-    static member Zero = range (_range.Zero, _range.Zero)
+type Range(range1: _rangeBackground, range2: _rangeBackground) =
+    static member Zero = range (_rangeBackground.Zero, _rangeBackground.Zero)
 
-    new(fIdx, bl, bc, el, ec) = range (_range (fIdx, bl, bc, el, ec), _Range.Zero)
+    new(fIdx, bl, bc, el, ec) = range (_rangeBackground (fIdx, bl, bc, el, ec), _RangeBackground.Zero)
 
-    new(fIdx, bl, bc, el, ec, fIdx2, bl2, bc2, el2, ec2) = range (_range (fIdx, bl, bc, el, ec), _range (fIdx2, bl2, bc2, el2, ec2))
+    new(fIdx, bl, bc, el, ec, fIdx2, bl2, bc2, el2, ec2) = range (_rangeBackground (fIdx, bl, bc, el, ec), _rangeBackground (fIdx2, bl2, bc2, el2, ec2))
 
-    new(fIdx, b: pos, e: pos) = range (_range (fIdx, b.Line, b.Column, e.Line, e.Column), _range.Zero)
+    new(fIdx, b: pos, e: pos) = range (_rangeBackground (fIdx, b.Line, b.Column, e.Line, e.Column), _rangeBackground.Zero)
 
     new(fIdx, b: pos, e: pos, fIdx2, b2: pos, e2: pos) =
-        range (_range (fIdx, b.Line, b.Column, e.Line, e.Column), _range (fIdx2, b2.Line, b2.Column, e2.Line, e2.Column))
+        range (_rangeBackground (fIdx, b.Line, b.Column, e.Line, e.Column), _rangeBackground (fIdx2, b2.Line, b2.Column, e2.Line, e2.Column))
 
     member _.StartLine = range1.StartLine
 
@@ -693,20 +693,36 @@ module Range =
             mkRange file (mkPos 1 0) (mkPos 1 80)
 
 module internal FileContent =
-    let private dict = ConcurrentDictionary<string, string array>()
+    let private fileContentDict = ConcurrentDictionary<string, string array>()
+    let private newlineMarkDict = ConcurrentDictionary<string, string>()
 
     let readFileContents (fileNames: string list) =
         for fileName in fileNames do
             if FileSystem.FileExistsShim fileName then
                 use fileStream = FileSystem.OpenFileForReadShim(fileName)
-                dict[fileName] <- fileStream.ReadAllLines()
-
-    let getLine fileName line =
-        match dict.TryGetValue fileName with
-        | true, lines when lines.Length > line -> lines[line - 1]
-        | _ -> String.Empty
-
-    let mutable getLineDynamic = getLine
+                let text = fileStream.ReadAllText()
+                let newlineMark =
+                    if text.IndexOf('\n') > -1 && text.IndexOf('\r') = -1 then
+                        "\n"
+                    else "\r\n"
+                newlineMarkDict[fileName] <- newlineMark
+                fileContentDict[fileName] <- text.Split([|newlineMark|], StringSplitOptions.None)
+
+    type IFileContentGetLine =
+        abstract GetLine: fileName: string -> line: int -> string
+        abstract GetLineNewLineMark: fileName: string -> string
+
+    let mutable getLineDynamic = 
+        { new IFileContentGetLine with
+              member this.GetLine(fileName: string) (line: int): string = 
+                  match fileContentDict.TryGetValue fileName with
+                  | true, lines when lines.Length > line -> lines[line - 1]
+                  | _ -> String.Empty
+
+              member this.GetLineNewLineMark(fileName: string): string = 
+                match newlineMarkDict.TryGetValue fileName with
+                | true, res -> res
+                | _ -> String.Empty }
 
     let getCodeText (m: range) =
         let endCol = m.EndColumn - 1
@@ -719,8 +735,8 @@ module internal FileContent =
                 else
                     m.FileName, m.StartLine, m.EndLine
 
-            [| for i in startLine..endLine -> getLineDynamic filename i |]
-            |> String.concat "\n"
+            [| for i in startLine..endLine -> getLineDynamic.GetLine filename i |]
+            |> String.concat (getLineDynamic.GetLineNewLineMark filename)
 
         if String.IsNullOrEmpty s then
             s
diff --git a/src/Compiler/Utilities/range.fsi b/src/Compiler/Utilities/range.fsi
index bd368f7d369..b7ceac1c725 100755
--- a/src/Compiler/Utilities/range.fsi
+++ b/src/Compiler/Utilities/range.fsi
@@ -315,13 +315,14 @@ module internal FileContent =
     /// Read all file contents
     val readFileContents: fileNames: string list -> unit
 
-    /// Get a line string from already read files
-    val getLine: fileName: string -> line: int -> string
+    type IFileContentGetLine =
+        abstract GetLine: fileName: string -> line: int -> string
+        abstract GetLineNewLineMark: fileName: string -> string
 
     /// Get a line string from already read files.
     ///
     /// Used by `getCodeText` to support `CallerArgumentExpression` in F# Interactive 
-    val mutable getLineDynamic: (string -> int -> string)
+    val mutable getLineDynamic: IFileContentGetLine
 
     /// Get code text of the specific `range`
     val getCodeText: range -> string
diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf
index 395b62d199f..515a3cf09c2 100644
--- a/src/Compiler/xlf/FSComp.txt.cs.xlf
+++ b/src/Compiler/xlf/FSComp.txt.cs.xlf
@@ -1282,6 +1282,16 @@
         <target state="translated">Atributy nejde použít pro rozšíření typů.</target>
         <note />
       </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <note />
+      </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionSelfReferential">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
         <source>This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead.</source>
         <target state="translated">Tento výraz záznamu kopírování a aktualizace mění všechna pole typu záznamu '{0}'. Zvažte použití syntaxe konstrukce záznamu.</target>
diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf
index 28c51bf8185..ef5096a1f9c 100644
--- a/src/Compiler/xlf/FSComp.txt.de.xlf
+++ b/src/Compiler/xlf/FSComp.txt.de.xlf
@@ -1282,6 +1282,16 @@
         <target state="translated">Attribute können nicht auf Typerweiterungen angewendet werden.</target>
         <note />
       </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <note />
+      </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionSelfReferential">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
         <source>This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead.</source>
         <target state="translated">Dieser Ausdruck zum Kopieren und Aktualisieren von Datensätzen ändert alle Felder des Datensatztyps "{0}". Erwägen Sie stattdessen die Verwendung der Datensatzerstellungssyntax.</target>
diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf
index f6d6fd7e2ee..8175ab017ac 100644
--- a/src/Compiler/xlf/FSComp.txt.es.xlf
+++ b/src/Compiler/xlf/FSComp.txt.es.xlf
@@ -1282,6 +1282,16 @@
         <target state="translated">Los atributos no se pueden aplicar a las extensiones de tipo.</target>
         <note />
       </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <note />
+      </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionSelfReferential">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
         <source>This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead.</source>
         <target state="translated">Esta expresión de copia y actualización de registros cambia todos los campos de tipo de registro "{0}". Es preferible utilizar la sintaxis de construcción de registros.</target>
diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf
index a51a72c8ee8..8fd21a431bf 100644
--- a/src/Compiler/xlf/FSComp.txt.fr.xlf
+++ b/src/Compiler/xlf/FSComp.txt.fr.xlf
@@ -1282,6 +1282,16 @@
         <target state="translated">Impossible d'appliquer des attributs aux extensions de type.</target>
         <note />
       </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <note />
+      </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionSelfReferential">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
         <source>This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead.</source>
         <target state="translated">Cette expression d'enregistrement de copie et de mise à jour modifie tous les champs du type d'enregistrement '{0}'. Envisagez d'utiliser la syntaxe de construction d'enregistrement à la place.</target>
diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf
index f8e336d8bc6..36e4b406f90 100644
--- a/src/Compiler/xlf/FSComp.txt.it.xlf
+++ b/src/Compiler/xlf/FSComp.txt.it.xlf
@@ -1282,6 +1282,16 @@
         <target state="translated">Gli attributi non possono essere applicati a estensioni di tipo.</target>
         <note />
       </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <note />
+      </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionSelfReferential">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
         <source>This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead.</source>
         <target state="translated">Questa espressione di record di copia e aggiornamento modifica tutti i campi del tipo di record '{0}'. Provare a usare la sintassi di costruzione dei record.</target>
diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf
index 8123f554cb4..0413fc2a5e5 100644
--- a/src/Compiler/xlf/FSComp.txt.ja.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ja.xlf
@@ -1282,6 +1282,16 @@
         <target state="translated">属性を型拡張に適用することはできません。</target>
         <note />
       </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <note />
+      </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionSelfReferential">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
         <source>This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead.</source>
         <target state="translated">この copy-and-update レコード式は、レコードの種類が '{0}' であるすべてのフィールドを変更します。代わりにレコード構築構文を使用することを検討してください。</target>
diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf
index 531d4d3552d..518268744d8 100644
--- a/src/Compiler/xlf/FSComp.txt.ko.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ko.xlf
@@ -1282,6 +1282,16 @@
         <target state="translated">형식 확장에 특성을 적용할 수 없습니다.</target>
         <note />
       </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <note />
+      </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionSelfReferential">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
         <source>This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead.</source>
         <target state="translated">이 레코드 복사 및 업데이트 식은 '{0}' 레코드 형식의 모든 필드를 변경합니다. 레코드 생성 구문을 대신 사용하는 것이 좋습니다.</target>
diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf
index 26de66bc57b..e0de32a2e08 100644
--- a/src/Compiler/xlf/FSComp.txt.pl.xlf
+++ b/src/Compiler/xlf/FSComp.txt.pl.xlf
@@ -1282,6 +1282,16 @@
         <target state="translated">Atrybutów nie można stosować do rozszerzeń typu.</target>
         <note />
       </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <note />
+      </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionSelfReferential">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
         <source>This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead.</source>
         <target state="translated">To wyrażenie rekordu kopiowania i aktualizacji zmienia wszystkie pola typu rekordu „{0}”. Zamiast tego rozważ użycie składni konstrukcji rekordu.</target>
diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
index ff5b0825181..cf9c9dcca01 100644
--- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
+++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
@@ -1282,6 +1282,16 @@
         <target state="translated">Os atributos não podem ser aplicados às extensões de tipo.</target>
         <note />
       </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <note />
+      </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionSelfReferential">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
         <source>This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead.</source>
         <target state="translated">Essa expressão de registro copiar e atualizar altera todos os campos do tipo de registro '{0}'. Considere usar a sintaxe de construção de registro em vez disso.</target>
diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf
index e89ea429b01..5856869f0f2 100644
--- a/src/Compiler/xlf/FSComp.txt.ru.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ru.xlf
@@ -1282,6 +1282,16 @@
         <target state="translated">Атрибуты не могут быть применены к расширениям типа.</target>
         <note />
       </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <note />
+      </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionSelfReferential">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
         <source>This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead.</source>
         <target state="translated">Это выражение записи копирования и обновления изменяет все поля типа записи "{0}". Вместо этого можно использовать синтаксис конструкции записи.</target>
diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf
index cc7e1431793..606ad7dc697 100644
--- a/src/Compiler/xlf/FSComp.txt.tr.xlf
+++ b/src/Compiler/xlf/FSComp.txt.tr.xlf
@@ -1282,6 +1282,16 @@
         <target state="translated">Öznitelikler tür uzantılarına uygulanamaz.</target>
         <note />
       </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <note />
+      </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionSelfReferential">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
         <source>This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead.</source>
         <target state="translated">Bu kopyalama ve güncelleştirme kayıt ifadesi, '{0}' kayıt türündeki tüm alanları değiştirir. Bunun yerine kayıt oluşturma söz dizimini kullanmayı deneyin.</target>
diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
index a8420dea45d..730a8fbbd40 100644
--- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
+++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
@@ -1282,6 +1282,16 @@
         <target state="translated">属性不可应用于类型扩展。</target>
         <note />
       </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <note />
+      </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionSelfReferential">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
         <source>This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead.</source>
         <target state="translated">此复制和更新记录表达式更改记录类型“{0}”的所有字段。请考虑改用记录构造语法。</target>
diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
index 0cdb26de227..c033f9071b9 100644
--- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
+++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
@@ -1282,6 +1282,16 @@
         <target state="translated">屬性無法套用到類型延伸模組。</target>
         <note />
       </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <note />
+      </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionSelfReferential">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
         <source>This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead.</source>
         <target state="translated">此複製和更新記錄運算式將變更記錄類型為 '{0}' 的所有欄位。請考慮改用記錄建構語法。</target>

From 68f2f6164471ec749c422eda474d99a85968f845 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Fri, 16 Aug 2024 11:28:36 +0800
Subject: [PATCH 11/57] format code

---
 src/Compiler/Interactive/fsi.fs | 13 +++++++------
 src/Compiler/Utilities/range.fs | 30 +++++++++++++++++++-----------
 2 files changed, 26 insertions(+), 17 deletions(-)

diff --git a/src/Compiler/Interactive/fsi.fs b/src/Compiler/Interactive/fsi.fs
index 7fc5db927c8..e0324413551 100644
--- a/src/Compiler/Interactive/fsi.fs
+++ b/src/Compiler/Interactive/fsi.fs
@@ -4670,13 +4670,14 @@ type FsiEvaluationSession
         if List.isEmpty fsiOptions.SourceFiles then
             fsiConsolePrompt.PrintAhead()
 
-    do FileContent.getLineDynamic <- 
-        { new FileContent.IFileContentGetLine with
-              member this.GetLine(fileName: string) (line: int): string = 
-                  fsiStdinSyphon.GetLineNoPrune fileName line
+    do
+        FileContent.getLineDynamic <-
+            { new FileContent.IFileContentGetLine with
+                member this.GetLine (fileName: string) (line: int) : string =
+                    fsiStdinSyphon.GetLineNoPrune fileName line
 
-              member this.GetLineNewLineMark _: string = 
-                  "\n" }
+                member this.GetLineNewLineMark _ : string = "\n"
+            }
 
     let fsiConsoleInput = FsiConsoleInput(fsi, fsiOptions, inReader, outWriter)
 
diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs
index 326bafeeff6..19849f97d79 100755
--- a/src/Compiler/Utilities/range.fs
+++ b/src/Compiler/Utilities/range.fs
@@ -397,12 +397,16 @@ type Range(range1: _rangeBackground, range2: _rangeBackground) =
 
     new(fIdx, bl, bc, el, ec) = range (_rangeBackground (fIdx, bl, bc, el, ec), _RangeBackground.Zero)
 
-    new(fIdx, bl, bc, el, ec, fIdx2, bl2, bc2, el2, ec2) = range (_rangeBackground (fIdx, bl, bc, el, ec), _rangeBackground (fIdx2, bl2, bc2, el2, ec2))
+    new(fIdx, bl, bc, el, ec, fIdx2, bl2, bc2, el2, ec2) =
+        range (_rangeBackground (fIdx, bl, bc, el, ec), _rangeBackground (fIdx2, bl2, bc2, el2, ec2))
 
     new(fIdx, b: pos, e: pos) = range (_rangeBackground (fIdx, b.Line, b.Column, e.Line, e.Column), _rangeBackground.Zero)
 
     new(fIdx, b: pos, e: pos, fIdx2, b2: pos, e2: pos) =
-        range (_rangeBackground (fIdx, b.Line, b.Column, e.Line, e.Column), _rangeBackground (fIdx2, b2.Line, b2.Column, e2.Line, e2.Column))
+        range (
+            _rangeBackground (fIdx, b.Line, b.Column, e.Line, e.Column),
+            _rangeBackground (fIdx2, b2.Line, b2.Column, e2.Line, e2.Column)
+        )
 
     member _.StartLine = range1.StartLine
 
@@ -701,28 +705,32 @@ module internal FileContent =
             if FileSystem.FileExistsShim fileName then
                 use fileStream = FileSystem.OpenFileForReadShim(fileName)
                 let text = fileStream.ReadAllText()
+
                 let newlineMark =
                     if text.IndexOf('\n') > -1 && text.IndexOf('\r') = -1 then
                         "\n"
-                    else "\r\n"
+                    else
+                        "\r\n"
+
                 newlineMarkDict[fileName] <- newlineMark
-                fileContentDict[fileName] <- text.Split([|newlineMark|], StringSplitOptions.None)
+                fileContentDict[fileName] <- text.Split([| newlineMark |], StringSplitOptions.None)
 
     type IFileContentGetLine =
         abstract GetLine: fileName: string -> line: int -> string
         abstract GetLineNewLineMark: fileName: string -> string
 
-    let mutable getLineDynamic = 
+    let mutable getLineDynamic =
         { new IFileContentGetLine with
-              member this.GetLine(fileName: string) (line: int): string = 
-                  match fileContentDict.TryGetValue fileName with
-                  | true, lines when lines.Length > line -> lines[line - 1]
-                  | _ -> String.Empty
+            member this.GetLine (fileName: string) (line: int) : string =
+                match fileContentDict.TryGetValue fileName with
+                | true, lines when lines.Length > line -> lines[line - 1]
+                | _ -> String.Empty
 
-              member this.GetLineNewLineMark(fileName: string): string = 
+            member this.GetLineNewLineMark(fileName: string) : string =
                 match newlineMarkDict.TryGetValue fileName with
                 | true, res -> res
-                | _ -> String.Empty }
+                | _ -> String.Empty
+        }
 
     let getCodeText (m: range) =
         let endCol = m.EndColumn - 1

From 7e93270e63988f74028fb794e4a13bc66dcc9274 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Fri, 16 Aug 2024 18:29:17 +0800
Subject: [PATCH 12/57] fix build

---
 src/Compiler/Checking/MethodCalls.fs         |  2 ++
 src/Compiler/Checking/PostInferenceChecks.fs | 11 ++++-------
 src/Compiler/Driver/ScriptClosure.fs         |  2 +-
 src/Compiler/Utilities/range.fs              | 12 +++++++-----
 4 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/src/Compiler/Checking/MethodCalls.fs b/src/Compiler/Checking/MethodCalls.fs
index 31fb9477473..76459d701cd 100644
--- a/src/Compiler/Checking/MethodCalls.fs
+++ b/src/Compiler/Checking/MethodCalls.fs
@@ -1425,6 +1425,7 @@ let rec GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g (calledArg: C
                 emptyPreBinder, Expr.Const (Const.String fileName, mMethExpr, currCalledArgTy)
             | CallerMemberName, Some callerName when (typeEquiv g currCalledArgTy g.string_ty) ->
                 emptyPreBinder, Expr.Const (Const.String callerName, mMethExpr, currCalledArgTy)
+            
             | CallerArgumentExpression param, _ when g.langVersion.SupportsFeature LanguageFeature.SupportCallerArgumentExpression && typeEquiv g currCalledArgTy g.string_ty ->
                 let str =
                     unnamedArgs
@@ -1437,6 +1438,7 @@ let rec GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g (calledArg: C
                         | _ -> None)
                     |> Option.defaultWith (fun _ -> tcFieldInit mMethExpr fieldInit)
                 emptyPreBinder, Expr.Const (str, mMethExpr, currCalledArgTy)
+            
             | _ ->
                 emptyPreBinder, Expr.Const (tcFieldInit mMethExpr fieldInit, mMethExpr, currCalledArgTy)
                 
diff --git a/src/Compiler/Checking/PostInferenceChecks.fs b/src/Compiler/Checking/PostInferenceChecks.fs
index 4b8bc277785..5f169183925 100644
--- a/src/Compiler/Checking/PostInferenceChecks.fs
+++ b/src/Compiler/Checking/PostInferenceChecks.fs
@@ -2351,14 +2351,10 @@ let CheckEntityDefn cenv env (tycon: Entity) =
                     match nameOpt with
                     | Some ident when name = ident.idText -> 
                         warning(Error(FSComp.SR.tcCallerArgumentExpressionSelfReferential(name), m))
+                    | _ when paramNames |> List.forall (fun i -> name <> i.idText) -> 
+                        warning(Error(FSComp.SR.tcCallerArgumentExpressionHasInvalidParameterName(name), m))
                     | _ -> ()
 
-                    if
-                        paramNames
-                        |> List.exists (fun i -> name = i.idText)
-                        |> not
-                    then warning(Error(FSComp.SR.tcCallerArgumentExpressionHasInvalidParameterName(name), m))
-
                 paramDatas
                 |> List.iterSquared (fun (ParamData(_, isInArg, _, optArgInfo, callerInfo, nameOpt, _, ty)) ->
                     ignore isInArg
@@ -2382,7 +2378,8 @@ let CheckEntityDefn cenv env (tycon: Entity) =
                             errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfo |> string, "string", NicePrint.minimalStringOfType cenv.denv ty), m))
                     | CalleeSide, CallerMemberName ->
                         if not ((isOptionTy g ty) && (typeEquiv g g.string_ty (destOptionTy g ty))) then
-                            errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfo |> string, "string", NicePrint.minimalStringOfType cenv.denv (destOptionTy g ty)), m)))
+                            errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfo |> string, "string", NicePrint.minimalStringOfType cenv.denv (destOptionTy g ty)), m))
+                    
                     | CallerSide _, CallerArgumentExpression name ->
                         if not (typeEquiv g g.string_ty ty) then
                             errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfo |> string, "string", NicePrint.minimalStringOfType cenv.denv ty), m))
diff --git a/src/Compiler/Driver/ScriptClosure.fs b/src/Compiler/Driver/ScriptClosure.fs
index 4b0db0f6c32..34f808f25ee 100644
--- a/src/Compiler/Driver/ScriptClosure.fs
+++ b/src/Compiler/Driver/ScriptClosure.fs
@@ -161,7 +161,7 @@ module ScriptPreprocessClosure =
 
         FileContent.readFileContents [ fileName ]
         let projectDir = !! Path.GetDirectoryName(fileName)
-        
+
         let isInteractive = (codeContext = CodeContext.CompilationAndEvaluation)
         let isInvalidationSupported = (codeContext = CodeContext.Editing)
 
diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs
index 19849f97d79..263e911fce1 100755
--- a/src/Compiler/Utilities/range.fs
+++ b/src/Compiler/Utilities/range.fs
@@ -464,11 +464,13 @@ type Range(range1: _rangeBackground, range2: _rangeBackground) =
         range1.GetHashCode() + range2.GetHashCode()
 
     override _.ToString() =
-        range1.ToString()
-        + if range2.IsZero then
-              String.Empty
-          else
-              $"(from: {range2.ToString()})"
+        let fromText =
+            if range2.IsZero then
+                String.Empty
+            else
+                $"(from: {range2.ToString()})"
+
+        $"{range1} {fromText}"
 
     member _.HasOriginalRange = not range2.IsZero
 

From 5790db9d2fed39e4aa1b08927cf073458c231926 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Fri, 16 Aug 2024 21:48:06 +0800
Subject: [PATCH 13/57] fix test

---
 .../CustomAttributes/CallerArgumentExpression.fs           | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
index 78e7917e555..b4178018c5b 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
@@ -9,7 +9,7 @@ module CustomAttributes_CallerArgumentExpression =
 
     [<Fact>]
     let ``Can consume CallerArgumentExpression in BCL methods`` () =
-        FSharp """
+        FSharp """module Program
 try System.ArgumentNullException.ThrowIfNullOrWhiteSpace(Seq.init 50 (fun _ -> " ")
   (* comment *) 
   |> String.concat " ")
@@ -23,10 +23,11 @@ with :? System.ArgumentException as ex ->
 
     [<Fact>]
     let ``Can define in F#`` () =
-        FSharp """# 1 "C:\\Program.fs"
+        FSharp """module Program
+# 1 "C:\\Program.fs"
 open System.Runtime.InteropServices
 type A() =
-static member aa (
+  static member aa (
     a,
     [<CallerMemberName; Optional; DefaultParameterValue "no value">]b: string, 
     [<CallerLineNumber; Optional; DefaultParameterValue 0>]c: int, 

From 46c4d46ffdd3ee73eabc694def793751fe1bc035 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Sun, 25 Aug 2024 17:01:15 +0800
Subject: [PATCH 14/57] try fix tests

---
 src/Compiler/Utilities/range.fs               |  5 +-
 .../CallerArgumentExpression.fs               | 66 +++++++++++++++----
 2 files changed, 57 insertions(+), 14 deletions(-)

diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs
index 263e911fce1..22a1658fe88 100755
--- a/src/Compiler/Utilities/range.fs
+++ b/src/Compiler/Utilities/range.fs
@@ -751,4 +751,7 @@ module internal FileContent =
         if String.IsNullOrEmpty s then
             s
         else
-            s.Substring(startCol + 1, s.LastIndexOf("\n", StringComparison.Ordinal) + 1 - startCol + endCol)
+            try
+                s.Substring(startCol + 1, s.LastIndexOf("\n", StringComparison.Ordinal) + 1 - startCol + endCol)
+            with ex ->
+                raise(System.AggregationException($"ex: {ex}; (s: {s}, startCol: {startCol}, endCol: {endCol})", ex))
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
index b4178018c5b..830fdd9389b 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
@@ -23,22 +23,62 @@ with :? System.ArgumentException as ex ->
 
     [<Fact>]
     let ``Can define in F#`` () =
-        FSharp """module Program
+        FSharp """#if !NETCOREAPP3_0_OR_GREATER
+namespace System.Runtime.CompilerServices
+  open System
+  [<AttributeUsage(AttributeTargets.Parameter, AllowMultiple=false, Inherited=false)>]
+  type CallerArgumentExpressionAttribute(parameterName) = 
+    inherit Attribute()
+    member val ParameterName: string = parameterName
+#endif
+
+module Program =
+  open System.Runtime.CompilerServices
+  type A() =
+    static member aa (
+      a,
+      [<CallerMemberName; Optional; DefaultParameterValue "no value">]b: string, 
+      [<CallerLineNumber; Optional; DefaultParameterValue 0>]c: int, 
+      [<CallerFilePath; Optional; DefaultParameterValue "no value">]d: string, 
+      [<CallerArgumentExpressionAttribute("a"); Optional; DefaultParameterValue "no value">]e: string) = 
+      a,b,c,d,e
+
+  let stringABC = "abc"
+  assert (A.aa(stringABC) = ("abc", ".ctor", 22, "C:\Program.fs", "stringABC"))
+        """
+        |> withLangVersionPreview
+        |> compileAndRun
+        |> shouldSucceed
+        |> ignore
+
+    [<Fact>]
+    let ``Can define in F# - with #line`` () =
+        FSharp """#if !NETCOREAPP3_0_OR_GREATER
+namespace System.Runtime.CompilerServices
+  open System
+  [<AttributeUsage(AttributeTargets.Parameter, AllowMultiple=false, Inherited=false)>]
+  type CallerArgumentExpressionAttribute(parameterName) = 
+    inherit Attribute()
+    member val ParameterName: string = parameterName
+#endif
+
+module Program =
 # 1 "C:\\Program.fs"
-open System.Runtime.InteropServices
-type A() =
-  static member aa (
-    a,
-    [<CallerMemberName; Optional; DefaultParameterValue "no value">]b: string, 
-    [<CallerLineNumber; Optional; DefaultParameterValue 0>]c: int, 
-    [<CallerFilePath; Optional; DefaultParameterValue "no value">]d: string, 
-    [<CallerArgumentExpressionAttribute("a"); Optional; DefaultParameterValue "no value">]e: string) = 
-    a,b,c,d,e
-
-let stringABC = "abc"
-assert (A.aa(stringABC) = ("abc", ".ctor", 12, "C:\Program.fs", "stringABC"))
+  open System.Runtime.CompilerServices
+  type A() =
+    static member aa (
+      a,
+      [<CallerMemberName; Optional; DefaultParameterValue "no value">]b: string, 
+      [<CallerLineNumber; Optional; DefaultParameterValue 0>]c: int, 
+      [<CallerFilePath; Optional; DefaultParameterValue "no value">]d: string, 
+      [<CallerArgumentExpressionAttribute("a"); Optional; DefaultParameterValue "no value">]e: string) = 
+      a,b,c,d,e
+
+  let stringABC = "abc"
+  assert (A.aa(stringABC) = ("abc", ".ctor", 12, "C:\Program.fs", "stringABC"))
         """
         |> withLangVersionPreview
         |> compileAndRun
         |> shouldSucceed
         |> ignore
+

From 8d792fa6664d51d5c5293f40c33c028450bd0169 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Mon, 26 Aug 2024 02:10:53 +0800
Subject: [PATCH 15/57] fix build

---
 src/Compiler/Utilities/range.fs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs
index 22a1658fe88..5248d3e9e5c 100755
--- a/src/Compiler/Utilities/range.fs
+++ b/src/Compiler/Utilities/range.fs
@@ -754,4 +754,4 @@ module internal FileContent =
             try
                 s.Substring(startCol + 1, s.LastIndexOf("\n", StringComparison.Ordinal) + 1 - startCol + endCol)
             with ex ->
-                raise(System.AggregationException($"ex: {ex}; (s: {s}, startCol: {startCol}, endCol: {endCol})", ex))
+                raise(System.AggregateException($"ex: {ex}; (s: {s}, startCol: {startCol}, endCol: {endCol})", ex))

From 65a4acc01b26258f1bebfdd2f6cb6f45edaf3b14 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Mon, 26 Aug 2024 02:29:19 +0800
Subject: [PATCH 16/57] test

---
 .../CustomAttributes/CallerArgumentExpression.fs | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
index 830fdd9389b..5f342427532 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
@@ -25,11 +25,13 @@ with :? System.ArgumentException as ex ->
     let ``Can define in F#`` () =
         FSharp """#if !NETCOREAPP3_0_OR_GREATER
 namespace System.Runtime.CompilerServices
-  open System
-  [<AttributeUsage(AttributeTargets.Parameter, AllowMultiple=false, Inherited=false)>]
-  type CallerArgumentExpressionAttribute(parameterName) = 
+open System
+[<AttributeUsage(AttributeTargets.Parameter, AllowMultiple=false, Inherited=false)>]
+type CallerArgumentExpressionAttribute(parameterName) = 
     inherit Attribute()
     member val ParameterName: string = parameterName
+
+namespace global
 #endif
 
 module Program =
@@ -55,11 +57,13 @@ module Program =
     let ``Can define in F# - with #line`` () =
         FSharp """#if !NETCOREAPP3_0_OR_GREATER
 namespace System.Runtime.CompilerServices
-  open System
-  [<AttributeUsage(AttributeTargets.Parameter, AllowMultiple=false, Inherited=false)>]
-  type CallerArgumentExpressionAttribute(parameterName) = 
+open System
+[<AttributeUsage(AttributeTargets.Parameter, AllowMultiple=false, Inherited=false)>]
+type CallerArgumentExpressionAttribute(parameterName) = 
     inherit Attribute()
     member val ParameterName: string = parameterName
+
+namespace global
 #endif
 
 module Program =

From f379b7f81fc45ab63283ff73abf3035a8c6550ed Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Tue, 4 Feb 2025 01:51:20 +0800
Subject: [PATCH 17/57] simplify code

---
 src/Compiler/Interactive/fsi.fs         | 11 ++---
 src/Compiler/Utilities/range.fs         | 58 ++++++++++---------------
 src/Compiler/Utilities/range.fsi        |  9 +++-
 src/Compiler/xlf/FSComp.txt.ko.xlf      |  5 +++
 src/Compiler/xlf/FSComp.txt.pl.xlf      |  5 +++
 src/Compiler/xlf/FSComp.txt.pt-BR.xlf   |  5 +++
 src/Compiler/xlf/FSComp.txt.ru.xlf      |  5 +++
 src/Compiler/xlf/FSComp.txt.tr.xlf      |  5 +++
 src/Compiler/xlf/FSComp.txt.zh-Hans.xlf |  5 +++
 src/Compiler/xlf/FSComp.txt.zh-Hant.xlf |  5 +++
 10 files changed, 72 insertions(+), 41 deletions(-)

diff --git a/src/Compiler/Interactive/fsi.fs b/src/Compiler/Interactive/fsi.fs
index 7ade5494d1c..bec3451a5b6 100644
--- a/src/Compiler/Interactive/fsi.fs
+++ b/src/Compiler/Interactive/fsi.fs
@@ -4677,11 +4677,12 @@ type FsiEvaluationSession
 
     do
         FileContent.getLineDynamic <-
-            { new FileContent.IFileContentGetLine with
-                member this.GetLine (fileName: string) (line: int) : string =
-                    fsiStdinSyphon.GetLineNoPrune fileName line
-
-                member this.GetLineNewLineMark _ : string = "\n"
+            { new FileContent.DefaultFileContentGetLine() with
+                override _.GetLine(fileName: string, line: int) : string =
+                    if fileName = stdinMockFileName then
+                        fsiStdinSyphon.GetLineNoPrune fileName line
+                    else
+                        base.GetLine(fileName, line)
             }
 
     let fsiConsoleInput = FsiConsoleInput(fsi, fsiOptions, inReader, outWriter)
diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs
index c8081562860..bdbf8894f06 100755
--- a/src/Compiler/Utilities/range.fs
+++ b/src/Compiler/Utilities/range.fs
@@ -703,53 +703,43 @@ module Range =
 
 module internal FileContent =
     let private fileContentDict = ConcurrentDictionary<string, string array>()
-    let private newlineMarkDict = ConcurrentDictionary<string, string>()
 
     let readFileContents (fileNames: string list) =
         for fileName in fileNames do
             if FileSystem.FileExistsShim fileName then
                 use fileStream = FileSystem.OpenFileForReadShim(fileName)
-                let text = fileStream.ReadAllText()
+                fileContentDict[fileName] <- fileStream.ReadAllLines()
 
-                let newlineMark =
-                    if text.IndexOf('\n') > -1 && text.IndexOf('\r') = -1 then
-                        "\n"
-                    else
-                        "\r\n"
+    type IFileContentGetLine =
+        abstract GetLine: fileName: string * line: int -> string
 
-                newlineMarkDict[fileName] <- newlineMark
-                fileContentDict[fileName] <- text.Split([| newlineMark |], StringSplitOptions.None)
+    type DefaultFileContentGetLine() =
 
-    type IFileContentGetLine =
-        abstract GetLine: fileName: string -> line: int -> string
-        abstract GetLineNewLineMark: fileName: string -> string
-
-    let mutable getLineDynamic =
-        { new IFileContentGetLine with
-            member this.GetLine (fileName: string) (line: int) : string =
-                match fileContentDict.TryGetValue fileName with
-                | true, lines when lines.Length > line -> lines[line - 1]
-                | _ -> String.Empty
-
-            member this.GetLineNewLineMark(fileName: string) : string =
-                match newlineMarkDict.TryGetValue fileName with
-                | true, res -> res
-                | _ -> String.Empty
-        }
+        abstract GetLine: fileName: string * line: int -> string
+
+        default _.GetLine(fileName: string, line: int) : string =
+            match fileContentDict.TryGetValue fileName with
+            | true, lines when lines.Length > line -> lines[line - 1]
+            | _ -> String.Empty
+
+        interface IFileContentGetLine with
+            member this.GetLine(fileName: string, line: int) : string = this.GetLine(fileName, line)
+
+    let mutable getLineDynamic = DefaultFileContentGetLine() :> IFileContentGetLine
 
     let getCodeText (m: range) =
+        let filename, startLine, endLine =
+            if m.HasOriginalRange then
+                m.OriginalFileName, m.OriginalStartLine, m.OriginalEndLine
+            else
+                m.FileName, m.StartLine, m.EndLine
+
         let endCol = m.EndColumn - 1
         let startCol = m.StartColumn - 1
 
         let s =
-            let filename, startLine, endLine =
-                if m.HasOriginalRange then
-                    m.OriginalFileName, m.OriginalStartLine, m.OriginalEndLine
-                else
-                    m.FileName, m.StartLine, m.EndLine
-
-            [| for i in startLine..endLine -> getLineDynamic.GetLine filename i |]
-            |> String.concat (getLineDynamic.GetLineNewLineMark filename)
+            [| for i in startLine..endLine -> getLineDynamic.GetLine(filename, i) |]
+            |> String.concat "\n"
 
         if String.IsNullOrEmpty s then
             s
@@ -757,4 +747,4 @@ module internal FileContent =
             try
                 s.Substring(startCol + 1, s.LastIndexOf("\n", StringComparison.Ordinal) + 1 - startCol + endCol)
             with ex ->
-                raise(System.AggregateException($"ex: {ex}; (s: {s}, startCol: {startCol}, endCol: {endCol})", ex))
+                raise (System.AggregateException($"ex: {ex}; (s: {s}, startCol: {startCol}, endCol: {endCol})", ex))
diff --git a/src/Compiler/Utilities/range.fsi b/src/Compiler/Utilities/range.fsi
index a3935af8b0f..32e792de5dd 100755
--- a/src/Compiler/Utilities/range.fsi
+++ b/src/Compiler/Utilities/range.fsi
@@ -316,8 +316,13 @@ module internal FileContent =
     val readFileContents: fileNames: string list -> unit
 
     type IFileContentGetLine =
-        abstract GetLine: fileName: string -> line: int -> string
-        abstract GetLineNewLineMark: fileName: string -> string
+        abstract GetLine: fileName: string * line: int -> string
+        
+    type DefaultFileContentGetLine =
+        new: unit -> DefaultFileContentGetLine
+        abstract GetLine: fileName: string * line: int -> string
+        override GetLine: fileName: string * line: int -> string
+        interface IFileContentGetLine
 
     /// Get a line string from already read files.
     ///
diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf
index 7da75084533..8a7d351255c 100644
--- a/src/Compiler/xlf/FSComp.txt.ko.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ko.xlf
@@ -612,6 +612,11 @@
         <target state="translated">활성 패턴에 대한 구조체 표현</target>
         <note />
       </trans-unit>
+      <trans-unit id="featureSupportCallerArgumentExpression">
+        <source>Support `CallerArgumentExpression`</source>
+        <target state="new">Support `CallerArgumentExpression`</target>
+        <note />
+      </trans-unit>
       <trans-unit id="featureSupportValueOptionsAsOptionalParameters">
         <source>Support ValueOption as valid type for optional member parameters</source>
         <target state="new">Support ValueOption as valid type for optional member parameters</target>
diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf
index 099eb6103f8..7c77acf39d3 100644
--- a/src/Compiler/xlf/FSComp.txt.pl.xlf
+++ b/src/Compiler/xlf/FSComp.txt.pl.xlf
@@ -612,6 +612,11 @@
         <target state="translated">reprezentacja struktury aktywnych wzorców</target>
         <note />
       </trans-unit>
+      <trans-unit id="featureSupportCallerArgumentExpression">
+        <source>Support `CallerArgumentExpression`</source>
+        <target state="new">Support `CallerArgumentExpression`</target>
+        <note />
+      </trans-unit>
       <trans-unit id="featureSupportValueOptionsAsOptionalParameters">
         <source>Support ValueOption as valid type for optional member parameters</source>
         <target state="new">Support ValueOption as valid type for optional member parameters</target>
diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
index cac94676681..011b3a2222d 100644
--- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
+++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
@@ -612,6 +612,11 @@
         <target state="translated">representação estrutural para padrões ativos</target>
         <note />
       </trans-unit>
+      <trans-unit id="featureSupportCallerArgumentExpression">
+        <source>Support `CallerArgumentExpression`</source>
+        <target state="new">Support `CallerArgumentExpression`</target>
+        <note />
+      </trans-unit>
       <trans-unit id="featureSupportValueOptionsAsOptionalParameters">
         <source>Support ValueOption as valid type for optional member parameters</source>
         <target state="new">Support ValueOption as valid type for optional member parameters</target>
diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf
index 945fd55a60f..dd41c3b09a9 100644
--- a/src/Compiler/xlf/FSComp.txt.ru.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ru.xlf
@@ -612,6 +612,11 @@
         <target state="translated">представление структуры для активных шаблонов</target>
         <note />
       </trans-unit>
+      <trans-unit id="featureSupportCallerArgumentExpression">
+        <source>Support `CallerArgumentExpression`</source>
+        <target state="new">Support `CallerArgumentExpression`</target>
+        <note />
+      </trans-unit>
       <trans-unit id="featureSupportValueOptionsAsOptionalParameters">
         <source>Support ValueOption as valid type for optional member parameters</source>
         <target state="new">Support ValueOption as valid type for optional member parameters</target>
diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf
index 0cc0df55c53..2b2a4a51c6d 100644
--- a/src/Compiler/xlf/FSComp.txt.tr.xlf
+++ b/src/Compiler/xlf/FSComp.txt.tr.xlf
@@ -612,6 +612,11 @@
         <target state="translated">etkin desenler için yapı gösterimi</target>
         <note />
       </trans-unit>
+      <trans-unit id="featureSupportCallerArgumentExpression">
+        <source>Support `CallerArgumentExpression`</source>
+        <target state="new">Support `CallerArgumentExpression`</target>
+        <note />
+      </trans-unit>
       <trans-unit id="featureSupportValueOptionsAsOptionalParameters">
         <source>Support ValueOption as valid type for optional member parameters</source>
         <target state="new">Support ValueOption as valid type for optional member parameters</target>
diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
index da26caf350d..da5843fef72 100644
--- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
+++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
@@ -612,6 +612,11 @@
         <target state="translated">活动模式的结构表示形式</target>
         <note />
       </trans-unit>
+      <trans-unit id="featureSupportCallerArgumentExpression">
+        <source>Support `CallerArgumentExpression`</source>
+        <target state="new">Support `CallerArgumentExpression`</target>
+        <note />
+      </trans-unit>
       <trans-unit id="featureSupportValueOptionsAsOptionalParameters">
         <source>Support ValueOption as valid type for optional member parameters</source>
         <target state="new">Support ValueOption as valid type for optional member parameters</target>
diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
index eed500a02e1..ae4f074ee38 100644
--- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
+++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
@@ -612,6 +612,11 @@
         <target state="translated">現用模式的結構表示法</target>
         <note />
       </trans-unit>
+      <trans-unit id="featureSupportCallerArgumentExpression">
+        <source>Support `CallerArgumentExpression`</source>
+        <target state="new">Support `CallerArgumentExpression`</target>
+        <note />
+      </trans-unit>
       <trans-unit id="featureSupportValueOptionsAsOptionalParameters">
         <source>Support ValueOption as valid type for optional member parameters</source>
         <target state="new">Support ValueOption as valid type for optional member parameters</target>

From 6d1a30d43896463a28ad613b9dfa5b0864fa4385 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Tue, 4 Feb 2025 18:31:47 +0800
Subject: [PATCH 18/57] simplify code; fix test

---
 .../.FSharp.Compiler.Service/9.0.100.md       |   1 -
 .../.FSharp.Compiler.Service/9.0.300.md       |   1 +
 src/Compiler/SyntaxTree/ParseHelpers.fs       |   7 +-
 src/Compiler/Utilities/range.fs               | 180 ++++--------------
 src/Compiler/Utilities/range.fsi              |  41 +---
 .../CompilerDirectives/Line.fs                |   2 +-
 .../CallerArgumentExpression.fs               |  53 +++---
 7 files changed, 79 insertions(+), 206 deletions(-)

diff --git a/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md
index 084bd77c1ba..51115b5ead0 100644
--- a/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md
+++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md
@@ -38,7 +38,6 @@
 * Enable consuming generic arguments defined as `allows ref struct` in C# ([Issue #17597](https://github.com/dotnet/fsharp/issues/17597), display them in tooltips [PR #17706](https://github.com/dotnet/fsharp/pull/17706))
 * Trivia for SynTypeConstraint.WhereTyparNotSupportsNull. ([Issue #17721](https://github.com/dotnet/fsharp/issues/17721), [PR #17745](https://github.com/dotnet/fsharp/pull/17745))
 * Trivia for SynType.WithNull. ([Issue #17720](https://github.com/dotnet/fsharp/issues/17720), [PR #17745](https://github.com/dotnet/fsharp/pull/17745))
-* Support `CallerArgumentExpression` ([Language Suggestion #966](https://github.com/fsharp/fslang-suggestions/issues/966), [PR #17519](https://github.com/dotnet/fsharp/pull/17519))
 
 
 ### Changed
diff --git a/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md b/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md
index a981aa6e79e..8a7d237e819 100644
--- a/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md
+++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md
@@ -9,6 +9,7 @@
 ### Added
 * Added missing type constraints in FCS. ([PR #18241](https://github.com/dotnet/fsharp/pull/18241))
 * The 'use' keyword can be used on IDisposable|null without nullness warnings ([PR #18262](https://github.com/dotnet/fsharp/pull/18262))
+* Support `CallerArgumentExpression` ([Language Suggestion #966](https://github.com/fsharp/fslang-suggestions/issues/966), [PR #17519](https://github.com/dotnet/fsharp/pull/17519))
 
 ### Changed
 
diff --git a/src/Compiler/SyntaxTree/ParseHelpers.fs b/src/Compiler/SyntaxTree/ParseHelpers.fs
index c8461e33bc2..3b2bc297e28 100644
--- a/src/Compiler/SyntaxTree/ParseHelpers.fs
+++ b/src/Compiler/SyntaxTree/ParseHelpers.fs
@@ -45,13 +45,14 @@ let posOfLexOriginalPosition (p: Position) = mkPos p.OriginalLine p.Column
 
 /// Get an F# compiler range from a lexer range
 let mkSynRange (p1: Position) (p2: Position) =
-    let p2' = 
-        if p1.FileIndex = p2.FileIndex then p2
+    let p2' =
+        if p1.FileIndex = p2.FileIndex then
+            p2
         else
             // This means we had a #line directive in the middle of this syntax element.
             (p1.ShiftColumnBy 1)
 
-    // TODO need tests 
+    // TODO need tests
     if p1.OriginalFileIndex <> p1.FileIndex || p1.OriginalLine <> p1.Line then
         mkFileIndexRangeWithOriginRange
             p1.FileIndex
diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs
index bdbf8894f06..2fe5664c531 100755
--- a/src/Compiler/Utilities/range.fs
+++ b/src/Compiler/Utilities/range.fs
@@ -262,9 +262,11 @@ module FileIndex =
     let commandLineArgsFileName = "commandLineArgs"
 
 [<Struct; CustomEquality; NoComparison>]
-[<System.Diagnostics.DebuggerDisplay("({StartLine},{StartColumn}-{EndLine},{EndColumn}) {ShortFileName} -> {DebugCode}")>]
-type _RangeBackground(code1: int64, code2: int64) =
-    static member Zero = _rangeBackground (0L, 0L)
+[<System.Diagnostics.DebuggerDisplay("{OriginalRange} -> ({StartLine},{StartColumn}-{EndLine},{EndColumn}) {ShortFileName} -> {DebugCode}")>]
+type Range private (code1: int64, code2: int64, originalRange: Range option) =
+    static member Zero = range (0L, 0L)
+
+    new(code1, code2) = range (code1, code2, None)
 
     new(fIdx, bl, bc, el, ec) =
         let code1 =
@@ -276,9 +278,9 @@ type _RangeBackground(code1: int64, code2: int64) =
             ((int64 bl <<< startLineShift) &&& startLineMask)
             ||| ((int64 (el - bl) <<< heightShift) &&& heightMask)
 
-        _rangeBackground (code1, code2)
+        range (code1, code2)
 
-    new(fIdx, b: pos, e: pos) = _rangeBackground (fIdx, b.Line, b.Column, e.Line, e.Column)
+    new(fIdx, b: pos, e: pos) = range (fIdx, b.Line, b.Column, e.Line, e.Column)
 
     member _.StartLine = int32 (uint64 (code2 &&& startLineMask) >>> startLineShift)
 
@@ -310,18 +312,18 @@ type _RangeBackground(code1: int64, code2: int64) =
 
     member _.FileIndex = int32 (code1 &&& fileIndexMask)
 
-    member m.StartRange = _rangeBackground (m.FileIndex, m.Start, m.Start)
+    member m.StartRange = range (m.FileIndex, m.Start, m.Start)
 
-    member m.EndRange = _rangeBackground (m.FileIndex, m.End, m.End)
+    member m.EndRange = range (m.FileIndex, m.End, m.End)
 
     member m.FileName = fileOfFileIndex m.FileIndex
 
     member m.ShortFileName = Path.GetFileName(fileOfFileIndex m.FileIndex)
 
     member _.MakeSynthetic() =
-        _rangeBackground (code1, code2 ||| isSyntheticMask)
+        range (code1, code2 ||| isSyntheticMask)
 
-    member m.IsAdjacentTo(otherRange: _RangeBackground) =
+    member m.IsAdjacentTo(otherRange: Range) =
         m.FileIndex = otherRange.FileIndex && m.End.Encoding = otherRange.Start.Encoding
 
     member _.NoteSourceConstruct(kind) =
@@ -338,7 +340,7 @@ type _RangeBackground(code1: int64, code2: int64) =
             | NotedSourceConstruct.Combine -> 8
             | NotedSourceConstruct.DelayOrQuoteOrRun -> 9
 
-        _rangeBackground (code1, (code2 &&& ~~~debugPointKindMask) ||| (int64 code <<< debugPointKindShift))
+        range (code1, (code2 &&& ~~~debugPointKindMask) ||| (int64 code <<< debugPointKindShift))
 
     member _.Code1 = code1
 
@@ -372,136 +374,39 @@ type _RangeBackground(code1: int64, code2: int64) =
             with e ->
                 e.ToString()
 
-    member _.Equals(m2: _rangeBackground) =
+    member _.Equals(m2: range) =
         let code2 = code2 &&& ~~~(debugPointKindMask ||| isSyntheticMask)
         let rcode2 = m2.Code2 &&& ~~~(debugPointKindMask ||| isSyntheticMask)
         code1 = m2.Code1 && code2 = rcode2
 
     override m.Equals(obj) =
         match obj with
-        | :? _rangeBackground as m2 -> m.Equals(m2)
+        | :? range as m2 -> m.Equals(m2)
         | _ -> false
 
     override _.GetHashCode() =
         let code2 = code2 &&& ~~~(debugPointKindMask ||| isSyntheticMask)
         hash code1 + hash code2
 
-    override r.ToString() =
-        sprintf "(%d,%d--%d,%d)" r.StartLine r.StartColumn r.EndLine r.EndColumn
-
-    member m.IsZero = m.Equals _rangeBackground.Zero
-
-and _rangeBackground = _RangeBackground
-
-[<Struct; CustomEquality; NoComparison>]
-[<System.Diagnostics.DebuggerDisplay("({OriginalStartLine},{OriginalStartColumn}-{OriginalEndLine},{OriginalEndColumn}) {OriginalShortFileName} -> ({StartLine},{StartColumn}-{EndLine},{EndColumn}) {ShortFileName} -> {DebugCode}")>]
-type Range(range1: _rangeBackground, range2: _rangeBackground) =
-    static member Zero = range (_rangeBackground.Zero, _rangeBackground.Zero)
-
-    new(fIdx, bl, bc, el, ec) = range (_rangeBackground (fIdx, bl, bc, el, ec), _RangeBackground.Zero)
-
-    new(fIdx, bl, bc, el, ec, fIdx2, bl2, bc2, el2, ec2) =
-        range (_rangeBackground (fIdx, bl, bc, el, ec), _rangeBackground (fIdx2, bl2, bc2, el2, ec2))
-
-    new(fIdx, b: pos, e: pos) = range (_rangeBackground (fIdx, b.Line, b.Column, e.Line, e.Column), _rangeBackground.Zero)
-
-    new(fIdx, b: pos, e: pos, fIdx2, b2: pos, e2: pos) =
-        range (
-            _rangeBackground (fIdx, b.Line, b.Column, e.Line, e.Column),
-            _rangeBackground (fIdx2, b2.Line, b2.Column, e2.Line, e2.Column)
-        )
-
-    member _.StartLine = range1.StartLine
-
-    member _.StartColumn = range1.StartColumn
-
-    member _.EndLine = range1.EndLine
-
-    member _.EndColumn = range1.EndColumn
-
-    member _.IsSynthetic = range1.IsSynthetic
-
-    member _.NotedSourceConstruct = range1.NotedSourceConstruct
-
-    member _.Start = range1.Start
-
-    member _.End = range1.End
-
-    member _.FileIndex = range1.FileIndex
-
-    member _.StartRange = Range(range1.StartRange, range2.StartRange)
-
-    member _.EndRange = Range(range1.EndRange, range2.EndRange)
-
-    member _.FileName = range1.FileName
-
-    member _.ShortFileName = range1.ShortFileName
-
-    member _.MakeSynthetic() =
-        range (range1.MakeSynthetic(), range2.MakeSynthetic())
-
-    member _.IsAdjacentTo(otherRange: Range) = range1.IsAdjacentTo otherRange.Range1
-
-    member _.NoteSourceConstruct(kind) =
-        range (range1.NoteSourceConstruct kind, range2.NoteSourceConstruct kind)
-
-    member _.Code1 = range1.Code1
+    member _.OriginalRange = originalRange
 
-    member _.Code2 = range1.Code2
-
-    member _.Range1 = range1
-
-    member _.Range2 = range2
-
-    member _.DebugCode = range1.DebugCode
-
-    member _.Equals(m2: range) =
-        range1.Equals m2.Range1 && range2.Equals m2.Range2
-
-    override m.Equals(obj) =
-        match obj with
-        | :? range as m2 -> m.Equals(m2)
-        | _ -> false
-
-    override _.GetHashCode() =
-        range1.GetHashCode() + range2.GetHashCode()
-
-    override _.ToString() =
+    override r.ToString() =
         let fromText =
-            if range2.IsZero then
-                String.Empty
+            if r.HasOriginalRange then
+                $" (from: %s{r.OriginalRange.Value.ToString()})"
             else
-                $"(from: {range2.ToString()})"
-
-        $"{range1} {fromText}"
-
-    member _.HasOriginalRange = not range2.IsZero
-
-    member _.OriginalStartLine = range2.StartLine
-
-    member _.OriginalStartColumn = range2.StartColumn
-
-    member _.OriginalEndLine = range2.EndLine
-
-    member _.OriginalEndColumn = range2.EndColumn
-
-    member _.OriginalIsSynthetic = range2.IsSynthetic
-
-    member _.OriginalNotedSourceConstruct = range2.NotedSourceConstruct
-
-    member _.OriginalStart = range2.Start
-
-    member _.OriginalEnd = range2.End
-
-    member _.OriginalFileIndex = range2.FileIndex
+                String.Empty
 
-    member _.OriginalStartRange = Range(range2.StartRange, range2.StartRange)
+        sprintf "(%d,%d--%d,%d)%s" r.StartLine r.StartColumn r.EndLine r.EndColumn fromText
 
-    member _.OriginalEndRange = Range(range2.EndRange, range2.EndRange)
+    member m.IsZero = m.Equals range.Zero
 
-    member _.OriginalFileName = range2.FileName
+    member _.WithOriginalRange(originalRange) = range (code1, code2, originalRange)
 
-    member _.OriginalShortFileName = range2.ShortFileName
+    member _.HasOriginalRange =
+        match originalRange with
+        | Some range2 when not range2.IsZero -> true
+        | _ -> false
 
 and range = Range
 
@@ -562,7 +467,8 @@ module Range =
     let mkFileIndexRange fileIndex startPos endPos = range (fileIndex, startPos, endPos)
 
     let mkFileIndexRangeWithOriginRange fileIndex startPos endPos fileIndex2 startPos2 endPos2 =
-        range (fileIndex, startPos, endPos, fileIndex2, startPos2, endPos2)
+        range(fileIndex, startPos, endPos)
+            .WithOriginalRange(Some(range (fileIndex2, startPos2, endPos2)))
 
     let posOrder =
         Order.orderOn (fun (p: pos) -> p.Line, p.Column) (Pair.order (Int32.order, Int32.order))
@@ -603,22 +509,15 @@ module Range =
                 else
                     m2
 
+            let originalRange =
+                match m1.OriginalRange, m2.OriginalRange with
+                | Some r1, Some r2 when r1.FileIndex = r2.FileIndex ->
+                    Some(range (r1.FileIndex, r1.StartLine, r1.StartColumn, r2.EndLine, r2.EndColumn))
+                | _ -> None
+
             let m =
-                if m1.OriginalFileIndex = m2.OriginalFileIndex then
-                    range (
-                        m1.FileIndex,
-                        start.StartLine,
-                        start.StartColumn,
-                        finish.EndLine,
-                        finish.EndColumn,
-                        m1.OriginalFileIndex,
-                        start.OriginalStartLine,
-                        start.OriginalStartColumn,
-                        finish.OriginalEndLine,
-                        finish.OriginalEndColumn
-                    )
-                else
-                    range (m1.FileIndex, start.StartLine, start.StartColumn, finish.EndLine, finish.EndColumn)
+                range(m1.FileIndex, start.StartLine, start.StartColumn, finish.EndLine, finish.EndColumn)
+                    .WithOriginalRange(originalRange)
 
             if m1.IsSynthetic || m2.IsSynthetic then
                 m.MakeSynthetic()
@@ -728,12 +627,9 @@ module internal FileContent =
     let mutable getLineDynamic = DefaultFileContentGetLine() :> IFileContentGetLine
 
     let getCodeText (m: range) =
-        let filename, startLine, endLine =
-            if m.HasOriginalRange then
-                m.OriginalFileName, m.OriginalStartLine, m.OriginalEndLine
-            else
-                m.FileName, m.StartLine, m.EndLine
+        let m = if m.HasOriginalRange then m.OriginalRange.Value else m
 
+        let filename, startLine, endLine = m.FileName, m.StartLine, m.EndLine
         let endCol = m.EndColumn - 1
         let startCol = m.StartColumn - 1
 
diff --git a/src/Compiler/Utilities/range.fsi b/src/Compiler/Utilities/range.fsi
index 32e792de5dd..994f09f1ede 100755
--- a/src/Compiler/Utilities/range.fsi
+++ b/src/Compiler/Utilities/range.fsi
@@ -107,43 +107,12 @@ type Range =
     /// service operations like dot-completion.
     member IsSynthetic: bool 
 
-    member HasOriginalRange: bool
-
-    /// The start line of the range
-    member OriginalStartLine: int
-
-    /// The start column of the range
-    member OriginalStartColumn: int
-
-    /// The line number for the end position of the range
-    member OriginalEndLine: int
-
-    /// The column number for the end position of the range
-    member OriginalEndColumn: int
-
-    /// The start position of the range
-    member OriginalStart: pos
-
-    /// The end position of the range
-    member OriginalEnd: pos
-
-    /// The empty range that is located at the start position of the range
-    member OriginalStartRange: range
-
-    /// The empty range that is located at the end position of the range
-    member OriginalEndRange: range
-
-    /// The file index for the range
-    member internal OriginalFileIndex: int
-
-    /// The file name for the file of the range
-    member OriginalFileName: string
-
-    /// Synthetic marks ranges which are produced by intermediate compilation phases. This
-    /// bit signifies that the range covers something that should not be visible to language
-    /// service operations like dot-completion.
-    member OriginalIsSynthetic: bool 
+    /// The original range for the range
+    member OriginalRange: range option
 
+    member HasOriginalRange: bool
+            
+    member WithOriginalRange: originalRange: range option -> range
 
     /// Convert a range to be synthetic
     member internal MakeSynthetic: unit -> range
diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Line.fs b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Line.fs
index 105670d1adb..161a1c45211 100644
--- a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Line.fs
+++ b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Line.fs
@@ -51,7 +51,7 @@ printfn ""
     """
 
     [<Theory>]
-    [<InlineData(1, case1, "xyz.fs:(1,0--3,1)")>]
+    [<InlineData(1, case1, "xyz.fs:(1,0--3,1) (from: (3,0--5,1))")>]
     [<InlineData(2, case2, "Line.fs:(2,0--2,1)")>]
     [<InlineData(3, case3, "Line.fs:(2,0--2,1)")>]
     let ``check expr range interacting with line directive`` (case, source, expectedRange) =
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
index 5f342427532..a6c0d058161 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
@@ -23,17 +23,7 @@ with :? System.ArgumentException as ex ->
 
     [<Fact>]
     let ``Can define in F#`` () =
-        FSharp """#if !NETCOREAPP3_0_OR_GREATER
-namespace System.Runtime.CompilerServices
-open System
-[<AttributeUsage(AttributeTargets.Parameter, AllowMultiple=false, Inherited=false)>]
-type CallerArgumentExpressionAttribute(parameterName) = 
-    inherit Attribute()
-    member val ParameterName: string = parameterName
-
-namespace global
-#endif
-
+        FSharp """
 module Program =
   open System.Runtime.CompilerServices
   type A() =
@@ -46,7 +36,7 @@ module Program =
       a,b,c,d,e
 
   let stringABC = "abc"
-  assert (A.aa(stringABC) = ("abc", ".ctor", 22, "C:\Program.fs", "stringABC"))
+  assert (A.aa(stringABC) = ("abc", ".ctor", 14, "C:\Program.fs", "stringABC"))
         """
         |> withLangVersionPreview
         |> compileAndRun
@@ -54,18 +44,35 @@ module Program =
         |> ignore
 
     [<Fact>]
-    let ``Can define in F# - with #line`` () =
-        FSharp """#if !NETCOREAPP3_0_OR_GREATER
-namespace System.Runtime.CompilerServices
-open System
-[<AttributeUsage(AttributeTargets.Parameter, AllowMultiple=false, Inherited=false)>]
-type CallerArgumentExpressionAttribute(parameterName) = 
-    inherit Attribute()
-    member val ParameterName: string = parameterName
+    let ``Can define in F# with F#-style optional arguments`` () =
+        FSharp """
+module Program =
+  open System.Runtime.CompilerServices
+  type A() =
+    static member aa (
+      a,
+      [<CallerMemberName>] ?b: string, 
+      [<CallerLineNumber>] ?c: int, 
+      [<CallerFilePath>] ?d: string, 
+      [<CallerArgumentExpressionAttribute("a")>] ?e: string) = 
+      let b = defaultArg b "no value"
+      let c = defaultArg c 0
+      let d = defaultArg d "no value"
+      let e = defaultArg e "no value"
+      a,b,c,d,e
 
-namespace global
-#endif
+  let stringABC = "abc"
+  assert (A.aa(stringABC) = ("abc", ".ctor", 18, "C:\Program.fs", "stringABC"))
+        """
+        |> withLangVersionPreview
+        |> compileAndRun
+        |> shouldSucceed
+        |> ignore
 
+        
+    [<Fact>]
+    let ``Can define in F# - with #line`` () =
+        FSharp """
 module Program =
 # 1 "C:\\Program.fs"
   open System.Runtime.CompilerServices
@@ -79,7 +86,7 @@ module Program =
       a,b,c,d,e
 
   let stringABC = "abc"
-  assert (A.aa(stringABC) = ("abc", ".ctor", 12, "C:\Program.fs", "stringABC"))
+  assert (A.aa(stringABC) = ("abc", ".ctor", 15, "C:\Program.fs", "stringABC"))
         """
         |> withLangVersionPreview
         |> compileAndRun

From 5f499a5810058eff1ac4d3e2a275455adf656d26 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Tue, 4 Feb 2025 19:22:59 +0800
Subject: [PATCH 19/57] fix range

---
 src/Compiler/Utilities/range.fs  | 25 ++++++++++++++-----------
 src/Compiler/Utilities/range.fsi |  4 ++--
 2 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs
index 2fe5664c531..2b94d97e25c 100755
--- a/src/Compiler/Utilities/range.fs
+++ b/src/Compiler/Utilities/range.fs
@@ -263,10 +263,10 @@ module FileIndex =
 
 [<Struct; CustomEquality; NoComparison>]
 [<System.Diagnostics.DebuggerDisplay("{OriginalRange} -> ({StartLine},{StartColumn}-{EndLine},{EndColumn}) {ShortFileName} -> {DebugCode}")>]
-type Range private (code1: int64, code2: int64, originalRange: Range option) =
+type Range private (code1: int64, code2: int64, originalRange: struct (int64 * int64) voption) =
     static member Zero = range (0L, 0L)
 
-    new(code1, code2) = range (code1, code2, None)
+    new(code1, code2) = range (code1, code2, ValueNone)
 
     new(fIdx, bl, bc, el, ec) =
         let code1 =
@@ -388,7 +388,9 @@ type Range private (code1: int64, code2: int64, originalRange: Range option) =
         let code2 = code2 &&& ~~~(debugPointKindMask ||| isSyntheticMask)
         hash code1 + hash code2
 
-    member _.OriginalRange = originalRange
+    member _.OriginalRange =
+        originalRange
+        |> ValueOption.map (fun struct (code1, code2) -> range (code1, code2))
 
     override r.ToString() =
         let fromText =
@@ -401,11 +403,12 @@ type Range private (code1: int64, code2: int64, originalRange: Range option) =
 
     member m.IsZero = m.Equals range.Zero
 
-    member _.WithOriginalRange(originalRange) = range (code1, code2, originalRange)
+    member _.WithOriginalRange(originalRange: range voption) =
+        range (code1, code2, originalRange |> ValueOption.map (fun m -> struct (m.Code1, m.Code2)))
 
-    member _.HasOriginalRange =
-        match originalRange with
-        | Some range2 when not range2.IsZero -> true
+    member this.HasOriginalRange =
+        match this.OriginalRange with
+        | ValueSome range2 when not range2.IsZero -> true
         | _ -> false
 
 and range = Range
@@ -468,7 +471,7 @@ module Range =
 
     let mkFileIndexRangeWithOriginRange fileIndex startPos endPos fileIndex2 startPos2 endPos2 =
         range(fileIndex, startPos, endPos)
-            .WithOriginalRange(Some(range (fileIndex2, startPos2, endPos2)))
+            .WithOriginalRange(ValueSome(range (fileIndex2, startPos2, endPos2)))
 
     let posOrder =
         Order.orderOn (fun (p: pos) -> p.Line, p.Column) (Pair.order (Int32.order, Int32.order))
@@ -511,9 +514,9 @@ module Range =
 
             let originalRange =
                 match m1.OriginalRange, m2.OriginalRange with
-                | Some r1, Some r2 when r1.FileIndex = r2.FileIndex ->
-                    Some(range (r1.FileIndex, r1.StartLine, r1.StartColumn, r2.EndLine, r2.EndColumn))
-                | _ -> None
+                | ValueSome r1, ValueSome r2 when r1.FileIndex = r2.FileIndex ->
+                    ValueSome(range (r1.FileIndex, r1.StartLine, r1.StartColumn, r2.EndLine, r2.EndColumn))
+                | _ -> ValueNone
 
             let m =
                 range(m1.FileIndex, start.StartLine, start.StartColumn, finish.EndLine, finish.EndColumn)
diff --git a/src/Compiler/Utilities/range.fsi b/src/Compiler/Utilities/range.fsi
index 994f09f1ede..ca983ac1305 100755
--- a/src/Compiler/Utilities/range.fsi
+++ b/src/Compiler/Utilities/range.fsi
@@ -108,11 +108,11 @@ type Range =
     member IsSynthetic: bool 
 
     /// The original range for the range
-    member OriginalRange: range option
+    member OriginalRange: range voption
 
     member HasOriginalRange: bool
             
-    member WithOriginalRange: originalRange: range option -> range
+    member WithOriginalRange: originalRange: range voption -> range
 
     /// Convert a range to be synthetic
     member internal MakeSynthetic: unit -> range

From 470b9933ea63b6b448b77681b2a25bc5ae1284ac Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Tue, 4 Feb 2025 19:28:38 +0800
Subject: [PATCH 20/57] fix tests

---
 .../CustomAttributes/CallerArgumentExpression.fs            | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
index a6c0d058161..2f7a079889c 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
@@ -23,7 +23,7 @@ with :? System.ArgumentException as ex ->
 
     [<Fact>]
     let ``Can define in F#`` () =
-        FSharp """
+        FSharp """namespace global
 module Program =
   open System.Runtime.CompilerServices
   type A() =
@@ -45,7 +45,7 @@ module Program =
 
     [<Fact>]
     let ``Can define in F# with F#-style optional arguments`` () =
-        FSharp """
+        FSharp """namespace global
 module Program =
   open System.Runtime.CompilerServices
   type A() =
@@ -72,7 +72,7 @@ module Program =
         
     [<Fact>]
     let ``Can define in F# - with #line`` () =
-        FSharp """
+        FSharp """namespace global
 module Program =
 # 1 "C:\\Program.fs"
   open System.Runtime.CompilerServices

From 477ed6ed025f53e804a9ae7a82618ec4e0a3d7de Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Tue, 4 Feb 2025 21:07:46 +0800
Subject: [PATCH 21/57] fix tests

---
 src/Compiler/Utilities/range.fs               |  2 +-
 .../CallerArgumentExpression.fs               | 82 +++++++++----------
 ...y_FSharp.Compiler.Service_Debug_net9.0.bsl |  5 +-
 ....Compiler.Service_Debug_netstandard2.0.bsl |  6 +-
 ...FSharp.Compiler.Service_Release_net9.0.bsl |  5 +-
 ...ompiler.Service_Release_netstandard2.0.bsl |  6 +-
 6 files changed, 53 insertions(+), 53 deletions(-)

diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs
index 2b94d97e25c..5a439db25a3 100755
--- a/src/Compiler/Utilities/range.fs
+++ b/src/Compiler/Utilities/range.fs
@@ -621,7 +621,7 @@ module internal FileContent =
 
         default _.GetLine(fileName: string, line: int) : string =
             match fileContentDict.TryGetValue fileName with
-            | true, lines when lines.Length > line -> lines[line - 1]
+            | true, lines when lines.Length >= line && line > 0 -> lines[line - 1]
             | _ -> String.Empty
 
         interface IFileContentGetLine with
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
index 2f7a079889c..03b46abd5e4 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
@@ -23,20 +23,18 @@ with :? System.ArgumentException as ex ->
 
     [<Fact>]
     let ``Can define in F#`` () =
-        FSharp """namespace global
-module Program =
-  open System.Runtime.CompilerServices
-  type A() =
-    static member aa (
-      a,
-      [<CallerMemberName; Optional; DefaultParameterValue "no value">]b: string, 
-      [<CallerLineNumber; Optional; DefaultParameterValue 0>]c: int, 
-      [<CallerFilePath; Optional; DefaultParameterValue "no value">]d: string, 
-      [<CallerArgumentExpressionAttribute("a"); Optional; DefaultParameterValue "no value">]e: string) = 
-      a,b,c,d,e
+        FSharp """open System.Runtime.CompilerServices
+open System.Runtime.InteropServices
+type A() =
+  static member aa (
+    a,
+    [<CallerMemberName; Optional; DefaultParameterValue "no value">]b: string, 
+    [<CallerLineNumber; Optional; DefaultParameterValue 0>]c: int, 
+    [<CallerArgumentExpressionAttribute("a"); Optional; DefaultParameterValue "no value">]e: string) = 
+    a,b,c,e
 
-  let stringABC = "abc"
-  assert (A.aa(stringABC) = ("abc", ".ctor", 14, "C:\Program.fs", "stringABC"))
+let stringABC = "abc"
+assert (A.aa(stringABC) = ("abc", ".cctor", 12, "stringABC"))
         """
         |> withLangVersionPreview
         |> compileAndRun
@@ -45,48 +43,44 @@ module Program =
 
     [<Fact>]
     let ``Can define in F# with F#-style optional arguments`` () =
-        FSharp """namespace global
-module Program =
-  open System.Runtime.CompilerServices
-  type A() =
-    static member aa (
-      a,
-      [<CallerMemberName>] ?b: string, 
-      [<CallerLineNumber>] ?c: int, 
-      [<CallerFilePath>] ?d: string, 
-      [<CallerArgumentExpressionAttribute("a")>] ?e: string) = 
-      let b = defaultArg b "no value"
-      let c = defaultArg c 0
-      let d = defaultArg d "no value"
-      let e = defaultArg e "no value"
-      a,b,c,d,e
+        FSharp """open System.Runtime.CompilerServices
+type A() =
+  static member aa (
+    a,
+    [<CallerMemberName>] ?b: string, 
+    [<CallerLineNumber>] ?c: int, 
+    [<CallerArgumentExpressionAttribute("a")>] ?e: string) = 
+    let b = defaultArg b "no value"
+    let c = defaultArg c 0
+    let e = defaultArg e "no value"
+    a,b,c,e
 
-  let stringABC = "abc"
-  assert (A.aa(stringABC) = ("abc", ".ctor", 18, "C:\Program.fs", "stringABC"))
+let stringABC = "abc"
+assert (A.aa(stringABC) = ("abc", ".cctor", 14, "stringABC"))
         """
         |> withLangVersionPreview
         |> compileAndRun
         |> shouldSucceed
         |> ignore
 
-        
     [<Fact>]
     let ``Can define in F# - with #line`` () =
-        FSharp """namespace global
-module Program =
+        FSharp """open System.Runtime.CompilerServices
+open System.Runtime.InteropServices
 # 1 "C:\\Program.fs"
-  open System.Runtime.CompilerServices
-  type A() =
-    static member aa (
-      a,
-      [<CallerMemberName; Optional; DefaultParameterValue "no value">]b: string, 
-      [<CallerLineNumber; Optional; DefaultParameterValue 0>]c: int, 
-      [<CallerFilePath; Optional; DefaultParameterValue "no value">]d: string, 
-      [<CallerArgumentExpressionAttribute("a"); Optional; DefaultParameterValue "no value">]e: string) = 
-      a,b,c,d,e
+type A() =
+  static member aa (
+    a,
+    [<CallerMemberName; Optional; DefaultParameterValue "no value">]b: string, 
+    [<CallerLineNumber; Optional; DefaultParameterValue 0>]c: int, 
+    [<CallerFilePath; Optional; DefaultParameterValue "no value">]d: string, 
+    [<CallerArgumentExpressionAttribute("a"); Optional; DefaultParameterValue "no value">]e: string) = 
+    a,b,c,d,e
 
-  let stringABC = "abc"
-  assert (A.aa(stringABC) = ("abc", ".ctor", 15, "C:\Program.fs", "stringABC"))
+let stringABC = "abc"
+assert (A.aa(stringABC) = ("abc", ".cctor", 11, "C:\\Program.fs", "stringABC"))
+# 1 "C:\\Program.fs"
+assert (A.aa(stringABC : string) = ("abc", ".cctor", 1, "C:\\Program.fs", "stringABC : string"))
         """
         |> withLangVersionPreview
         |> compileAndRun
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl
index 60c5f6e4b5f..baaacb7c383 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl
@@ -5,6 +5,7 @@
 [IL]: Error [UnmanagedPointer]: : FSharp.Compiler.IO.RawByteMemory::.ctor(uint8*, int32, object)][offset 0x00000009] Unmanaged pointers are not a verifiable type.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::get_Item(int32)][offset 0x0000001E][found Native Int] Expected ByRef on the stack.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::set_Item(int32, uint8)][offset 0x00000025][found Native Int] Expected ByRef on the stack.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.Range::ToString()][offset 0x00000021] Callvirt on a value type method.
 [IL]: Error [ReturnPtrToStack]: : Internal.Utilities.Text.Lexing.LexBuffer`1::get_LexemeView()][offset 0x00000019] Return type is ByRef, TypedReference, ArgHandle, or ArgIterator.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.Text.Lexing.UnicodeTables::scanUntilSentinel([FSharp.Compiler.Service]Internal.Utilities.Text.Lexing.LexBuffer`1<char>, int32)][offset 0x00000079][found Short] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Xml.XmlDoc::processLines([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>)][offset 0x00000031][found Char] Unexpected type on the stack.
@@ -21,7 +22,7 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x00000082][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3510-788::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001E5][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3519-788::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001E5][found Char] Unexpected type on the stack.
 [IL]: Error [UnmanagedPointer]: : FSharp.Compiler.Interactive.Shell+Utilities+pointerToNativeInt@110::Invoke(object)][offset 0x00000007] Unmanaged pointers are not a verifiable type.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharpCheckerResults+dataTipOfReferences@2205::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000084][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$ServiceLexing+clo@921-508::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<FSharp.Compiler.Parser+token,int32,int32>,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack.
@@ -59,7 +60,7 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x0000000B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x00000021][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000CD][found Char] Unexpected type on the stack.
-[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@546::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@579::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000037][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000043][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack.
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl
index 1e0df962a05..045a7e49d03 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl
@@ -5,6 +5,7 @@
 [IL]: Error [UnmanagedPointer]: : FSharp.Compiler.IO.RawByteMemory::.ctor(uint8*, int32, object)][offset 0x00000009] Unmanaged pointers are not a verifiable type.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::get_Item(int32)][offset 0x0000001E][found Native Int] Expected ByRef on the stack.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::set_Item(int32, uint8)][offset 0x00000025][found Native Int] Expected ByRef on the stack.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.Range::ToString()][offset 0x00000021] Callvirt on a value type method.
 [IL]: Error [ReturnPtrToStack]: : Internal.Utilities.Text.Lexing.LexBuffer`1::get_LexemeView()][offset 0x00000019] Return type is ByRef, TypedReference, ArgHandle, or ArgIterator.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.Text.Lexing.UnicodeTables::scanUntilSentinel([FSharp.Compiler.Service]Internal.Utilities.Text.Lexing.LexBuffer`1<char>, int32)][offset 0x00000079][found Short] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Xml.XmlDoc::processLines([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>)][offset 0x00000031][found Char] Unexpected type on the stack.
@@ -27,8 +28,9 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x00000082][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiStdinSyphon::GetLine(string, int32)][offset 0x00000039][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiStdinSyphon::GetLineNoPrune(string, int32)][offset 0x0000002B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3510-788::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001E5][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3519-788::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001E5][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiInteractionProcessor::CompletionsForPartialLID([FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompilerState, string)][offset 0x0000001B][found Char] Unexpected type on the stack.
 [IL]: Error [UnmanagedPointer]: : FSharp.Compiler.Interactive.Shell+Utilities+pointerToNativeInt@110::Invoke(object)][offset 0x00000007] Unmanaged pointers are not a verifiable type.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharpCheckerResults+dataTipOfReferences@2205::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000084][found Char] Unexpected type on the stack.
@@ -84,7 +86,7 @@
 [IL]: Error [StackUnexpected]: : Internal.Utilities.FSharpEnvironment+probePathForDotnetHost@321::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000028][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.SimulatedMSBuildReferenceResolver+Pipe #6 input at line 68@68::FSharp.Compiler.CodeAnalysis.ILegacyReferenceResolver.Resolve([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyResolutionEnvironment, [S.P.CoreLib]System.Tuple`2<string,string>[], string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>, string, string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>, string, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.Unit>, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<bool,Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.Unit>>>)][offset 0x0000034D][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000CD][found Char] Unexpected type on the stack.
-[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@546::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@579::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000037][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000043][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack.
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl
index 1a088c5a702..c9c04f67d6d 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl
@@ -5,6 +5,7 @@
 [IL]: Error [UnmanagedPointer]: : FSharp.Compiler.IO.RawByteMemory::.ctor(uint8*, int32, object)][offset 0x00000009] Unmanaged pointers are not a verifiable type.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::get_Item(int32)][offset 0x0000001A][found Native Int] Expected ByRef on the stack.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::set_Item(int32, uint8)][offset 0x0000001B][found Native Int] Expected ByRef on the stack.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.Range::ToString()][offset 0x0000001F] Callvirt on a value type method.
 [IL]: Error [ReturnPtrToStack]: : Internal.Utilities.Text.Lexing.LexBuffer`1::get_LexemeView()][offset 0x00000017] Return type is ByRef, TypedReference, ArgHandle, or ArgIterator.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.Text.Lexing.UnicodeTables::scanUntilSentinel([FSharp.Compiler.Service]Internal.Utilities.Text.Lexing.LexBuffer`1<char>, int32)][offset 0x0000008D][found Short] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Xml.XmlDoc::processLines([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>)][offset 0x0000002C][found Char] Unexpected type on the stack.
@@ -21,7 +22,7 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x00000082][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3510-832::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001C7][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3519-832::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001C7][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharpCheckerResults+GetReferenceResolutionStructuredToolTipText@2205::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000076][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$ServiceLexing+clo@921-529::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<FSharp.Compiler.Parser+token,int32,int32>,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$ServiceLexing+clo@921-529::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<FSharp.Compiler.Parser+token,int32,int32>,Microsoft.FSharp.Core.Unit>)][offset 0x0000003B][found Char] Unexpected type on the stack.
@@ -85,7 +86,7 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x0000000B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x00000021][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000B6][found Char] Unexpected type on the stack.
-[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@546::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@579::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000035][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000041][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack.
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl
index 48af8ec2f2f..8e063e9a9ae 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl
@@ -5,6 +5,7 @@
 [IL]: Error [UnmanagedPointer]: : FSharp.Compiler.IO.RawByteMemory::.ctor(uint8*, int32, object)][offset 0x00000009] Unmanaged pointers are not a verifiable type.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::get_Item(int32)][offset 0x0000001A][found Native Int] Expected ByRef on the stack.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::set_Item(int32, uint8)][offset 0x0000001B][found Native Int] Expected ByRef on the stack.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.Range::ToString()][offset 0x0000001F] Callvirt on a value type method.
 [IL]: Error [ReturnPtrToStack]: : Internal.Utilities.Text.Lexing.LexBuffer`1::get_LexemeView()][offset 0x00000017] Return type is ByRef, TypedReference, ArgHandle, or ArgIterator.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.Text.Lexing.UnicodeTables::scanUntilSentinel([FSharp.Compiler.Service]Internal.Utilities.Text.Lexing.LexBuffer`1<char>, int32)][offset 0x0000008D][found Short] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Xml.XmlDoc::processLines([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>)][offset 0x0000002C][found Char] Unexpected type on the stack.
@@ -27,8 +28,9 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x00000082][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiStdinSyphon::GetLine(string, int32)][offset 0x00000032][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiStdinSyphon::GetLineNoPrune(string, int32)][offset 0x0000002B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3510-832::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001C7][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3519-832::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001C7][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiInteractionProcessor::CompletionsForPartialLID([FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompilerState, string)][offset 0x00000024][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharpCheckerResults+GetReferenceResolutionStructuredToolTipText@2205::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000076][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.AssemblyContent+traverseMemberFunctionAndValues@176::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue)][offset 0x0000002B][found Char] Unexpected type on the stack.
@@ -111,7 +113,7 @@
 [IL]: Error [StackUnexpected]: : Internal.Utilities.FSharpEnvironment::probePathForDotnetHost@320([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x0000002A][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.SimulatedMSBuildReferenceResolver+SimulatedMSBuildResolver@68::FSharp.Compiler.CodeAnalysis.ILegacyReferenceResolver.Resolve([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyResolutionEnvironment, [S.P.CoreLib]System.Tuple`2<string,string>[], string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>, string, string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>, string, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.Unit>, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<bool,Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.Unit>>>)][offset 0x000002F5][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000B6][found Char] Unexpected type on the stack.
-[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@546::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@579::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000035][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000041][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack.

From 6fb65482ced07d7ddad40bb2c0dbcc78c56e8093 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Tue, 4 Feb 2025 22:53:38 +0800
Subject: [PATCH 22/57] fix

---
 src/Compiler/Utilities/range.fsi              |  4 ++-
 .../CallerArgumentExpression.fs               | 26 ++++++++++++-------
 2 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/src/Compiler/Utilities/range.fsi b/src/Compiler/Utilities/range.fsi
index ca983ac1305..344bd12d85f 100755
--- a/src/Compiler/Utilities/range.fsi
+++ b/src/Compiler/Utilities/range.fsi
@@ -282,6 +282,8 @@ module Line =
 module internal FileContent =
 
     /// Read all file contents
+    ///
+    /// Used by `getCodeText` to support `CallerArgumentExpression`
     val readFileContents: fileNames: string list -> unit
 
     type IFileContentGetLine =
@@ -295,7 +297,7 @@ module internal FileContent =
 
     /// Get a line string from already read files.
     ///
-    /// Used by `getCodeText` to support `CallerArgumentExpression` in F# Interactive 
+    /// Used by `getCodeText` to support `CallerArgumentExpression`
     val mutable getLineDynamic: IFileContentGetLine
 
     /// Get code text of the specific `range`
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
index 03b46abd5e4..6f0d1c973df 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
@@ -10,11 +10,14 @@ module CustomAttributes_CallerArgumentExpression =
     [<Fact>]
     let ``Can consume CallerArgumentExpression in BCL methods`` () =
         FSharp """module Program
-try System.ArgumentNullException.ThrowIfNullOrWhiteSpace(Seq.init 50 (fun _ -> " ")
-  (* comment *) 
-  |> String.concat " ")
-with :? System.ArgumentException as ex -> 
-  assert (ex.Message.Contains("(Parameter 'Seq.init 50 (fun _ -> \" \")\n  (* comment *) \n  |> String.concat \" \""))
+[<EntryPoint>]
+let main args =
+  try System.ArgumentNullException.ThrowIfNullOrWhiteSpace(Seq.init 50 (fun _ -> " ")
+    (* comment *) 
+    |> String.concat " ")
+  with :? System.ArgumentException as ex -> 
+    assert (ex.Message.Contains("(Parameter 'Seq.init 50 (fun _ -> \" \")\n  (* comment *) \n  |> String.concat \" \""))
+  0
 """
         |> withLangVersionPreview
         |> compileAndRun
@@ -23,7 +26,8 @@ with :? System.ArgumentException as ex ->
 
     [<Fact>]
     let ``Can define in F#`` () =
-        FSharp """open System.Runtime.CompilerServices
+        FSharp """module Program
+open System.Runtime.CompilerServices
 open System.Runtime.InteropServices
 type A() =
   static member aa (
@@ -34,7 +38,7 @@ type A() =
     a,b,c,e
 
 let stringABC = "abc"
-assert (A.aa(stringABC) = ("abc", ".cctor", 12, "stringABC"))
+assert (A.aa(stringABC) = ("abc", ".cctor", 13, "stringABC"))
         """
         |> withLangVersionPreview
         |> compileAndRun
@@ -43,7 +47,8 @@ assert (A.aa(stringABC) = ("abc", ".cctor", 12, "stringABC"))
 
     [<Fact>]
     let ``Can define in F# with F#-style optional arguments`` () =
-        FSharp """open System.Runtime.CompilerServices
+        FSharp """module Program
+open System.Runtime.CompilerServices
 type A() =
   static member aa (
     a,
@@ -56,7 +61,7 @@ type A() =
     a,b,c,e
 
 let stringABC = "abc"
-assert (A.aa(stringABC) = ("abc", ".cctor", 14, "stringABC"))
+assert (A.aa(stringABC) = ("abc", ".cctor", 15, "stringABC"))
         """
         |> withLangVersionPreview
         |> compileAndRun
@@ -65,7 +70,8 @@ assert (A.aa(stringABC) = ("abc", ".cctor", 14, "stringABC"))
 
     [<Fact>]
     let ``Can define in F# - with #line`` () =
-        FSharp """open System.Runtime.CompilerServices
+        FSharp """module Program
+open System.Runtime.CompilerServices
 open System.Runtime.InteropServices
 # 1 "C:\\Program.fs"
 type A() =

From c8ca45b99d0931d2cff688426ea4003f1a5ddef7 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Tue, 4 Feb 2025 23:39:03 +0800
Subject: [PATCH 23/57] test

---
 .../CustomAttributes/CallerArgumentExpression.fs              | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
index 6f0d1c973df..acc3797b481 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
@@ -20,6 +20,7 @@ let main args =
   0
 """
         |> withLangVersionPreview
+        |> asExe
         |> compileAndRun
         |> shouldSucceed
         |> ignore
@@ -41,6 +42,7 @@ let stringABC = "abc"
 assert (A.aa(stringABC) = ("abc", ".cctor", 13, "stringABC"))
         """
         |> withLangVersionPreview
+        |> asExe
         |> compileAndRun
         |> shouldSucceed
         |> ignore
@@ -64,6 +66,7 @@ let stringABC = "abc"
 assert (A.aa(stringABC) = ("abc", ".cctor", 15, "stringABC"))
         """
         |> withLangVersionPreview
+        |> asExe
         |> compileAndRun
         |> shouldSucceed
         |> ignore
@@ -89,6 +92,7 @@ assert (A.aa(stringABC) = ("abc", ".cctor", 11, "C:\\Program.fs", "stringABC"))
 assert (A.aa(stringABC : string) = ("abc", ".cctor", 1, "C:\\Program.fs", "stringABC : string"))
         """
         |> withLangVersionPreview
+        |> asExe
         |> compileAndRun
         |> shouldSucceed
         |> ignore

From b5f22fb1a7c28c5d31ca544fadf732d9579e99e1 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Wed, 5 Feb 2025 00:44:47 +0800
Subject: [PATCH 24/57] test

---
 .../CallerArgumentExpression.fs               | 21 +++++++---------
 ...vice.SurfaceArea.netstandard20.release.bsl | 24 ++++++++++++-------
 2 files changed, 24 insertions(+), 21 deletions(-)

diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
index acc3797b481..7ad856a9d4f 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
@@ -9,15 +9,12 @@ module CustomAttributes_CallerArgumentExpression =
 
     [<Fact>]
     let ``Can consume CallerArgumentExpression in BCL methods`` () =
-        FSharp """module Program
-[<EntryPoint>]
-let main args =
-  try System.ArgumentNullException.ThrowIfNullOrWhiteSpace(Seq.init 50 (fun _ -> " ")
-    (* comment *) 
-    |> String.concat " ")
-  with :? System.ArgumentException as ex -> 
-    assert (ex.Message.Contains("(Parameter 'Seq.init 50 (fun _ -> \" \")\n  (* comment *) \n  |> String.concat \" \""))
-  0
+        FSharp """
+try System.ArgumentNullException.ThrowIfNullOrWhiteSpace(Seq.init 50 (fun _ -> " ")
+  (* comment *) 
+  |> String.concat " ")
+with :? System.ArgumentException as ex -> 
+  assert (ex.Message.Contains("(Parameter 'Seq.init 50 (fun _ -> \" \")\n  (* comment *) \n  |> String.concat \" \""))
 """
         |> withLangVersionPreview
         |> asExe
@@ -27,7 +24,7 @@ let main args =
 
     [<Fact>]
     let ``Can define in F#`` () =
-        FSharp """module Program
+        FSharp """
 open System.Runtime.CompilerServices
 open System.Runtime.InteropServices
 type A() =
@@ -49,7 +46,7 @@ assert (A.aa(stringABC) = ("abc", ".cctor", 13, "stringABC"))
 
     [<Fact>]
     let ``Can define in F# with F#-style optional arguments`` () =
-        FSharp """module Program
+        FSharp """
 open System.Runtime.CompilerServices
 type A() =
   static member aa (
@@ -73,7 +70,7 @@ assert (A.aa(stringABC) = ("abc", ".cctor", 15, "stringABC"))
 
     [<Fact>]
     let ``Can define in F# - with #line`` () =
-        FSharp """module Program
+        FSharp """
 open System.Runtime.CompilerServices
 open System.Runtime.InteropServices
 # 1 "C:\\Program.fs"
diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl
index e85b3022c96..6304999c6a4 100644
--- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl
+++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl
@@ -2836,6 +2836,10 @@ FSharp.Compiler.Diagnostics.ExtendedData+FieldNotContainedDiagnosticExtendedData
 FSharp.Compiler.Diagnostics.ExtendedData+FieldNotContainedDiagnosticExtendedData: FSharp.Compiler.Symbols.FSharpField SignatureField
 FSharp.Compiler.Diagnostics.ExtendedData+FieldNotContainedDiagnosticExtendedData: FSharp.Compiler.Symbols.FSharpField get_ImplementationField()
 FSharp.Compiler.Diagnostics.ExtendedData+FieldNotContainedDiagnosticExtendedData: FSharp.Compiler.Symbols.FSharpField get_SignatureField()
+FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: System.String DiagnosticId
+FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: System.String UrlFormat
+FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: System.String get_DiagnosticId()
+FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: System.String get_UrlFormat()
 FSharp.Compiler.Diagnostics.ExtendedData+TypeMismatchDiagnosticExtendedData: DiagnosticContextInfo ContextInfo
 FSharp.Compiler.Diagnostics.ExtendedData+TypeMismatchDiagnosticExtendedData: DiagnosticContextInfo get_ContextInfo()
 FSharp.Compiler.Diagnostics.ExtendedData+TypeMismatchDiagnosticExtendedData: FSharp.Compiler.Symbols.FSharpDisplayContext DisplayContext
@@ -2854,13 +2858,9 @@ FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedDa
 FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+ExpressionIsAFunctionExtendedData
 FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+FieldNotContainedDiagnosticExtendedData
 FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+IFSharpDiagnosticExtendedData
+FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData
 FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+TypeMismatchDiagnosticExtendedData
 FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+ValueNotContainedDiagnosticExtendedData
-FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: System.String DiagnosticId
-FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: System.String UrlFormat
-FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: System.String get_DiagnosticId()
-FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: System.String get_UrlFormat()
-FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData
 FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Diagnostics.FSharpDiagnostic Create(FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity, System.String, Int32, FSharp.Compiler.Text.Range, Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.String])
 FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity Severity
 FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity get_Severity()
@@ -5390,6 +5390,7 @@ FSharp.Compiler.Symbols.FSharpGenericParameter: System.Collections.Generic.IList
 FSharp.Compiler.Symbols.FSharpGenericParameter: System.String Name
 FSharp.Compiler.Symbols.FSharpGenericParameter: System.String ToString()
 FSharp.Compiler.Symbols.FSharpGenericParameter: System.String get_Name()
+FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsAllowsRefStructConstraint
 FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsCoercesToConstraint
 FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsComparisonConstraint
 FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsDefaultsToConstraint
@@ -5398,13 +5399,13 @@ FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsEnumConstrai
 FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsEqualityConstraint
 FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsMemberConstraint
 FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsNonNullableValueTypeConstraint
+FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsNotSupportsNullConstraint
 FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsReferenceTypeConstraint
 FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsRequiresDefaultConstructorConstraint
 FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsSimpleChoiceConstraint
 FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsSupportsNullConstraint
 FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsUnmanagedConstraint
-FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsNotSupportsNullConstraint
-FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsAllowsRefStructConstraint
+FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsAllowsRefStructConstraint()
 FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsCoercesToConstraint()
 FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsComparisonConstraint()
 FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsDefaultsToConstraint()
@@ -5413,13 +5414,12 @@ FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsEnumCons
 FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsEqualityConstraint()
 FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsMemberConstraint()
 FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsNonNullableValueTypeConstraint()
+FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsNotSupportsNullConstraint()
 FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsReferenceTypeConstraint()
 FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsRequiresDefaultConstructorConstraint()
 FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsSimpleChoiceConstraint()
 FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsSupportsNullConstraint()
 FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsUnmanagedConstraint()
-FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsNotSupportsNullConstraint()
-FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsAllowsRefStructConstraint()
 FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: FSharp.Compiler.Symbols.FSharpGenericParameterDefaultsToConstraint DefaultsToConstraintData
 FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: FSharp.Compiler.Symbols.FSharpGenericParameterDefaultsToConstraint get_DefaultsToConstraintData()
 FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: FSharp.Compiler.Symbols.FSharpGenericParameterDelegateConstraint DelegateConstraintData
@@ -10884,7 +10884,9 @@ FSharp.Compiler.Text.PositionModule: System.String stringOfPos(FSharp.Compiler.T
 FSharp.Compiler.Text.PositionModule: System.Tuple`2[System.Int32,System.Int32] toZ(FSharp.Compiler.Text.Position)
 FSharp.Compiler.Text.PositionModule: Void outputPos(System.IO.TextWriter, FSharp.Compiler.Text.Position)
 FSharp.Compiler.Text.Range: Boolean Equals(System.Object)
+FSharp.Compiler.Text.Range: Boolean HasOriginalRange
 FSharp.Compiler.Text.Range: Boolean IsSynthetic
+FSharp.Compiler.Text.Range: Boolean get_HasOriginalRange()
 FSharp.Compiler.Text.Range: Boolean get_IsSynthetic()
 FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Position End
 FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Position Start
@@ -10892,6 +10894,7 @@ FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Position get_End()
 FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Position get_Start()
 FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Range EndRange
 FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Range StartRange
+FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Range WithOriginalRange(Microsoft.FSharp.Core.FSharpValueOption`1[FSharp.Compiler.Text.Range])
 FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Range Zero
 FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Range get_EndRange()
 FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Range get_StartRange()
@@ -10905,6 +10908,8 @@ FSharp.Compiler.Text.Range: Int32 get_EndColumn()
 FSharp.Compiler.Text.Range: Int32 get_EndLine()
 FSharp.Compiler.Text.Range: Int32 get_StartColumn()
 FSharp.Compiler.Text.Range: Int32 get_StartLine()
+FSharp.Compiler.Text.Range: Microsoft.FSharp.Core.FSharpValueOption`1[FSharp.Compiler.Text.Range] OriginalRange
+FSharp.Compiler.Text.Range: Microsoft.FSharp.Core.FSharpValueOption`1[FSharp.Compiler.Text.Range] get_OriginalRange()
 FSharp.Compiler.Text.Range: System.String FileName
 FSharp.Compiler.Text.Range: System.String ToString()
 FSharp.Compiler.Text.Range: System.String get_FileName()
@@ -10916,6 +10921,7 @@ FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range get_range0()
 FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range get_rangeCmdArgs()
 FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range get_rangeStartup()
 FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range mkFileIndexRange(Int32, FSharp.Compiler.Text.Position, FSharp.Compiler.Text.Position)
+FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range mkFileIndexRangeWithOriginRange(Int32, FSharp.Compiler.Text.Position, FSharp.Compiler.Text.Position, Int32, FSharp.Compiler.Text.Position, FSharp.Compiler.Text.Position)
 FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range mkFirstLineOfFile(System.String)
 FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range mkRange(System.String, FSharp.Compiler.Text.Position, FSharp.Compiler.Text.Position)
 FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range range0

From 271985bcf79fe805b309911c2af1f5ac576a41e7 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Wed, 5 Feb 2025 01:40:44 +0800
Subject: [PATCH 25/57] test

---
 .../CallerArgumentExpression.fs                | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
index 7ad856a9d4f..10d856b42b5 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
@@ -9,12 +9,12 @@ module CustomAttributes_CallerArgumentExpression =
 
     [<Fact>]
     let ``Can consume CallerArgumentExpression in BCL methods`` () =
-        FSharp """
+        FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
 try System.ArgumentNullException.ThrowIfNullOrWhiteSpace(Seq.init 50 (fun _ -> " ")
   (* comment *) 
   |> String.concat " ")
 with :? System.ArgumentException as ex -> 
-  assert (ex.Message.Contains("(Parameter 'Seq.init 50 (fun _ -> \" \")\n  (* comment *) \n  |> String.concat \" \""))
+  assertEqual true (ex.Message.Contains("(Parameter 'Seq.init 50 (fun _ -> \" \")\n  (* comment *) \n  |> String.concat \" \""))
 """
         |> withLangVersionPreview
         |> asExe
@@ -24,7 +24,7 @@ with :? System.ArgumentException as ex ->
 
     [<Fact>]
     let ``Can define in F#`` () =
-        FSharp """
+        FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
 open System.Runtime.CompilerServices
 open System.Runtime.InteropServices
 type A() =
@@ -36,7 +36,7 @@ type A() =
     a,b,c,e
 
 let stringABC = "abc"
-assert (A.aa(stringABC) = ("abc", ".cctor", 13, "stringABC"))
+assertEqual (A.aa(stringABC)) ("abc", ".cctor", 13, "stringABC")
         """
         |> withLangVersionPreview
         |> asExe
@@ -46,7 +46,7 @@ assert (A.aa(stringABC) = ("abc", ".cctor", 13, "stringABC"))
 
     [<Fact>]
     let ``Can define in F# with F#-style optional arguments`` () =
-        FSharp """
+        FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
 open System.Runtime.CompilerServices
 type A() =
   static member aa (
@@ -60,7 +60,7 @@ type A() =
     a,b,c,e
 
 let stringABC = "abc"
-assert (A.aa(stringABC) = ("abc", ".cctor", 15, "stringABC"))
+assertEqual (A.aa(stringABC)) ("abc", ".cctor", 15, "stringABC")
         """
         |> withLangVersionPreview
         |> asExe
@@ -70,7 +70,7 @@ assert (A.aa(stringABC) = ("abc", ".cctor", 15, "stringABC"))
 
     [<Fact>]
     let ``Can define in F# - with #line`` () =
-        FSharp """
+        FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
 open System.Runtime.CompilerServices
 open System.Runtime.InteropServices
 # 1 "C:\\Program.fs"
@@ -84,9 +84,9 @@ type A() =
     a,b,c,d,e
 
 let stringABC = "abc"
-assert (A.aa(stringABC) = ("abc", ".cctor", 11, "C:\\Program.fs", "stringABC"))
+assertEqual (A.aa(stringABC)) ("abc", ".cctor", 11, "C:\\Program.fs", "stringABC")
 # 1 "C:\\Program.fs"
-assert (A.aa(stringABC : string) = ("abc", ".cctor", 1, "C:\\Program.fs", "stringABC : string"))
+assertEqual (A.aa(stringABC : string)) ("abc", ".cctor", 1, "C:\\Program.fs", "stringABC : string")
         """
         |> withLangVersionPreview
         |> asExe

From 31e7bb2b3ebec61dca1c56cc551c2dc4edc4f964 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Wed, 26 Feb 2025 10:27:53 +0800
Subject: [PATCH 26/57] fix tests

---
 .../CustomAttributes/CallerArgumentExpression.fs    | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
index 10d856b42b5..162ebf21b25 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
@@ -10,7 +10,7 @@ module CustomAttributes_CallerArgumentExpression =
     [<Fact>]
     let ``Can consume CallerArgumentExpression in BCL methods`` () =
         FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
-try System.ArgumentNullException.ThrowIfNullOrWhiteSpace(Seq.init 50 (fun _ -> " ")
+try System.ArgumentException.ThrowIfNullOrWhiteSpace(Seq.init 50 (fun _ -> " ")
   (* comment *) 
   |> String.concat " ")
 with :? System.ArgumentException as ex -> 
@@ -48,6 +48,7 @@ assertEqual (A.aa(stringABC)) ("abc", ".cctor", 13, "stringABC")
     let ``Can define in F# with F#-style optional arguments`` () =
         FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
 open System.Runtime.CompilerServices
+open System.Runtime.InteropServices
 type A() =
   static member aa (
     a,
@@ -60,7 +61,7 @@ type A() =
     a,b,c,e
 
 let stringABC = "abc"
-assertEqual (A.aa(stringABC)) ("abc", ".cctor", 15, "stringABC")
+assertEqual (A.aa(stringABC)) ("abc", ".cctor", 16, "stringABC")
         """
         |> withLangVersionPreview
         |> asExe
@@ -73,7 +74,7 @@ assertEqual (A.aa(stringABC)) ("abc", ".cctor", 15, "stringABC")
         FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
 open System.Runtime.CompilerServices
 open System.Runtime.InteropServices
-# 1 "C:\\Program.fs"
+# 1 "test.fs"
 type A() =
   static member aa (
     a,
@@ -84,9 +85,9 @@ type A() =
     a,b,c,d,e
 
 let stringABC = "abc"
-assertEqual (A.aa(stringABC)) ("abc", ".cctor", 11, "C:\\Program.fs", "stringABC")
-# 1 "C:\\Program.fs"
-assertEqual (A.aa(stringABC : string)) ("abc", ".cctor", 1, "C:\\Program.fs", "stringABC : string")
+assertEqual (A.aa(stringABC)) ("abc", ".cctor", 11, System.IO.Path.Combine(__SOURCE_DIRECTORY__, "test.fs"), "stringABC")
+# 1 "test.fs"
+assertEqual (A.aa(stringABC : string)) ("abc", ".cctor", 1, System.IO.Path.Combine(__SOURCE_DIRECTORY__, "test.fs"), "stringABC : string")
         """
         |> withLangVersionPreview
         |> asExe

From 424b83cda590f1153b1064ec1fd898b7f685bb8c Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Wed, 26 Feb 2025 11:08:30 +0800
Subject: [PATCH 27/57] update baselines

---
 src/Compiler/xlf/FSComp.txt.cs.xlf            | 15 +++++++++++
 src/Compiler/xlf/FSComp.txt.de.xlf            | 15 +++++++++++
 src/Compiler/xlf/FSComp.txt.es.xlf            | 15 +++++++++++
 src/Compiler/xlf/FSComp.txt.fr.xlf            | 15 +++++++++++
 src/Compiler/xlf/FSComp.txt.it.xlf            | 15 +++++++++++
 ...vice.SurfaceArea.netstandard20.release.bsl | 25 +++++++++++--------
 ...y_FSharp.Compiler.Service_Debug_net9.0.bsl |  5 ++--
 ....Compiler.Service_Debug_netstandard2.0.bsl |  6 +++--
 ...FSharp.Compiler.Service_Release_net9.0.bsl |  5 ++--
 ...ompiler.Service_Release_netstandard2.0.bsl |  6 +++--
 10 files changed, 104 insertions(+), 18 deletions(-)

diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf
index 74894da5d02..51061bac6df 100644
--- a/src/Compiler/xlf/FSComp.txt.cs.xlf
+++ b/src/Compiler/xlf/FSComp.txt.cs.xlf
@@ -622,6 +622,11 @@
         <target state="translated">reprezentace struktury aktivních vzorů</target>
         <note />
       </trans-unit>
+      <trans-unit id="featureSupportCallerArgumentExpression">
+        <source>Support `CallerArgumentExpression`</source>
+        <target state="new">Support `CallerArgumentExpression`</target>
+        <note />
+      </trans-unit>
       <trans-unit id="featureSupportValueOptionsAsOptionalParameters">
         <source>Support ValueOption as valid type for optional member parameters</source>
         <target state="new">Support ValueOption as valid type for optional member parameters</target>
@@ -1352,6 +1357,16 @@
         <target state="translated">Atributy nejde použít pro rozšíření typů.</target>
         <note />
       </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <note />
+      </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionSelfReferential">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
         <source>This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead.</source>
         <target state="translated">Tento výraz záznamu kopírování a aktualizace mění všechna pole typu záznamu '{0}'. Zvažte použití syntaxe konstrukce záznamu.</target>
diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf
index 77409615867..d1e530b5c73 100644
--- a/src/Compiler/xlf/FSComp.txt.de.xlf
+++ b/src/Compiler/xlf/FSComp.txt.de.xlf
@@ -622,6 +622,11 @@
         <target state="translated">Strukturdarstellung für aktive Muster</target>
         <note />
       </trans-unit>
+      <trans-unit id="featureSupportCallerArgumentExpression">
+        <source>Support `CallerArgumentExpression`</source>
+        <target state="new">Support `CallerArgumentExpression`</target>
+        <note />
+      </trans-unit>
       <trans-unit id="featureSupportValueOptionsAsOptionalParameters">
         <source>Support ValueOption as valid type for optional member parameters</source>
         <target state="new">Support ValueOption as valid type for optional member parameters</target>
@@ -1352,6 +1357,16 @@
         <target state="translated">Attribute können nicht auf Typerweiterungen angewendet werden.</target>
         <note />
       </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <note />
+      </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionSelfReferential">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
         <source>This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead.</source>
         <target state="translated">Dieser Ausdruck zum Kopieren und Aktualisieren von Datensätzen ändert alle Felder des Datensatztyps "{0}". Erwägen Sie stattdessen die Verwendung der Datensatzerstellungssyntax.</target>
diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf
index 9f042384d39..f685a7f559b 100644
--- a/src/Compiler/xlf/FSComp.txt.es.xlf
+++ b/src/Compiler/xlf/FSComp.txt.es.xlf
@@ -622,6 +622,11 @@
         <target state="translated">representación de struct para modelos activos</target>
         <note />
       </trans-unit>
+      <trans-unit id="featureSupportCallerArgumentExpression">
+        <source>Support `CallerArgumentExpression`</source>
+        <target state="new">Support `CallerArgumentExpression`</target>
+        <note />
+      </trans-unit>
       <trans-unit id="featureSupportValueOptionsAsOptionalParameters">
         <source>Support ValueOption as valid type for optional member parameters</source>
         <target state="new">Support ValueOption as valid type for optional member parameters</target>
@@ -1352,6 +1357,16 @@
         <target state="translated">Los atributos no se pueden aplicar a las extensiones de tipo.</target>
         <note />
       </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <note />
+      </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionSelfReferential">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
         <source>This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead.</source>
         <target state="translated">Esta expresión de copia y actualización de registros cambia todos los campos de tipo de registro "{0}". Es preferible utilizar la sintaxis de construcción de registros.</target>
diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf
index 621286a8e21..5c68b8b8a3c 100644
--- a/src/Compiler/xlf/FSComp.txt.fr.xlf
+++ b/src/Compiler/xlf/FSComp.txt.fr.xlf
@@ -622,6 +622,11 @@
         <target state="translated">représentation de structure pour les modèles actifs</target>
         <note />
       </trans-unit>
+      <trans-unit id="featureSupportCallerArgumentExpression">
+        <source>Support `CallerArgumentExpression`</source>
+        <target state="new">Support `CallerArgumentExpression`</target>
+        <note />
+      </trans-unit>
       <trans-unit id="featureSupportValueOptionsAsOptionalParameters">
         <source>Support ValueOption as valid type for optional member parameters</source>
         <target state="new">Support ValueOption as valid type for optional member parameters</target>
@@ -1352,6 +1357,16 @@
         <target state="translated">Impossible d'appliquer des attributs aux extensions de type.</target>
         <note />
       </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <note />
+      </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionSelfReferential">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
         <source>This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead.</source>
         <target state="translated">Cette expression d'enregistrement de copie et de mise à jour modifie tous les champs du type d'enregistrement '{0}'. Envisagez d'utiliser la syntaxe de construction d'enregistrement à la place.</target>
diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf
index 1d7bdf56aa0..942a0738753 100644
--- a/src/Compiler/xlf/FSComp.txt.it.xlf
+++ b/src/Compiler/xlf/FSComp.txt.it.xlf
@@ -622,6 +622,11 @@
         <target state="translated">rappresentazione struct per criteri attivi</target>
         <note />
       </trans-unit>
+      <trans-unit id="featureSupportCallerArgumentExpression">
+        <source>Support `CallerArgumentExpression`</source>
+        <target state="new">Support `CallerArgumentExpression`</target>
+        <note />
+      </trans-unit>
       <trans-unit id="featureSupportValueOptionsAsOptionalParameters">
         <source>Support ValueOption as valid type for optional member parameters</source>
         <target state="new">Support ValueOption as valid type for optional member parameters</target>
@@ -1352,6 +1357,16 @@
         <target state="translated">Gli attributi non possono essere applicati a estensioni di tipo.</target>
         <note />
       </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <note />
+      </trans-unit>
+      <trans-unit id="tcCallerArgumentExpressionSelfReferential">
+        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
+        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
         <source>This copy-and-update record expression changes all fields of record type '{0}'. Consider using the record construction syntax instead.</source>
         <target state="translated">Questa espressione di record di copia e aggiornamento modifica tutti i campi del tipo di record '{0}'. Provare a usare la sintassi di costruzione dei record.</target>
diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl
index fabaa710607..34453a351ca 100644
--- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl
+++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl
@@ -2830,12 +2830,20 @@ FSharp.Compiler.Diagnostics.ExtendedData+DiagnosticContextInfo: Int32 GetHashCod
 FSharp.Compiler.Diagnostics.ExtendedData+DiagnosticContextInfo: Int32 Tag
 FSharp.Compiler.Diagnostics.ExtendedData+DiagnosticContextInfo: Int32 get_Tag()
 FSharp.Compiler.Diagnostics.ExtendedData+DiagnosticContextInfo: System.String ToString()
+FSharp.Compiler.Diagnostics.ExtendedData+ExperimentalExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] DiagnosticId
+FSharp.Compiler.Diagnostics.ExtendedData+ExperimentalExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] UrlFormat
+FSharp.Compiler.Diagnostics.ExtendedData+ExperimentalExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_DiagnosticId()
+FSharp.Compiler.Diagnostics.ExtendedData+ExperimentalExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_UrlFormat()
 FSharp.Compiler.Diagnostics.ExtendedData+ExpressionIsAFunctionExtendedData: FSharp.Compiler.Symbols.FSharpType ActualType
 FSharp.Compiler.Diagnostics.ExtendedData+ExpressionIsAFunctionExtendedData: FSharp.Compiler.Symbols.FSharpType get_ActualType()
 FSharp.Compiler.Diagnostics.ExtendedData+FieldNotContainedDiagnosticExtendedData: FSharp.Compiler.Symbols.FSharpField ImplementationField
 FSharp.Compiler.Diagnostics.ExtendedData+FieldNotContainedDiagnosticExtendedData: FSharp.Compiler.Symbols.FSharpField SignatureField
 FSharp.Compiler.Diagnostics.ExtendedData+FieldNotContainedDiagnosticExtendedData: FSharp.Compiler.Symbols.FSharpField get_ImplementationField()
 FSharp.Compiler.Diagnostics.ExtendedData+FieldNotContainedDiagnosticExtendedData: FSharp.Compiler.Symbols.FSharpField get_SignatureField()
+FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] DiagnosticId
+FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] UrlFormat
+FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_DiagnosticId()
+FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_UrlFormat()
 FSharp.Compiler.Diagnostics.ExtendedData+TypeMismatchDiagnosticExtendedData: DiagnosticContextInfo ContextInfo
 FSharp.Compiler.Diagnostics.ExtendedData+TypeMismatchDiagnosticExtendedData: DiagnosticContextInfo get_ContextInfo()
 FSharp.Compiler.Diagnostics.ExtendedData+TypeMismatchDiagnosticExtendedData: FSharp.Compiler.Symbols.FSharpDisplayContext DisplayContext
@@ -2851,22 +2859,13 @@ FSharp.Compiler.Diagnostics.ExtendedData+ValueNotContainedDiagnosticExtendedData
 FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+ArgumentsInSigAndImplMismatchExtendedData
 FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+DefinitionsInSigAndImplNotCompatibleAbbreviationsDifferExtendedData
 FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+DiagnosticContextInfo
+FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+ExperimentalExtendedData
 FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+ExpressionIsAFunctionExtendedData
 FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+FieldNotContainedDiagnosticExtendedData
 FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+IFSharpDiagnosticExtendedData
 FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData
 FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+TypeMismatchDiagnosticExtendedData
 FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+ValueNotContainedDiagnosticExtendedData
-FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] DiagnosticId
-FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] UrlFormat
-FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_DiagnosticId()
-FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_UrlFormat()
-FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData
-FSharp.Compiler.Diagnostics.ExtendedData+ExperimentalExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] DiagnosticId
-FSharp.Compiler.Diagnostics.ExtendedData+ExperimentalExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] UrlFormat
-FSharp.Compiler.Diagnostics.ExtendedData+ExperimentalExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_DiagnosticId()
-FSharp.Compiler.Diagnostics.ExtendedData+ExperimentalExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_UrlFormat()
-FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+ExperimentalExtendedData
 FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Diagnostics.FSharpDiagnostic Create(FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity, System.String, Int32, FSharp.Compiler.Text.Range, Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.String])
 FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity Severity
 FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity get_Severity()
@@ -10892,7 +10891,9 @@ FSharp.Compiler.Text.PositionModule: System.String stringOfPos(FSharp.Compiler.T
 FSharp.Compiler.Text.PositionModule: System.Tuple`2[System.Int32,System.Int32] toZ(FSharp.Compiler.Text.Position)
 FSharp.Compiler.Text.PositionModule: Void outputPos(System.IO.TextWriter, FSharp.Compiler.Text.Position)
 FSharp.Compiler.Text.Range: Boolean Equals(System.Object)
+FSharp.Compiler.Text.Range: Boolean HasOriginalRange
 FSharp.Compiler.Text.Range: Boolean IsSynthetic
+FSharp.Compiler.Text.Range: Boolean get_HasOriginalRange()
 FSharp.Compiler.Text.Range: Boolean get_IsSynthetic()
 FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Position End
 FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Position Start
@@ -10900,6 +10901,7 @@ FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Position get_End()
 FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Position get_Start()
 FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Range EndRange
 FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Range StartRange
+FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Range WithOriginalRange(Microsoft.FSharp.Core.FSharpValueOption`1[FSharp.Compiler.Text.Range])
 FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Range Zero
 FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Range get_EndRange()
 FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Range get_StartRange()
@@ -10913,6 +10915,8 @@ FSharp.Compiler.Text.Range: Int32 get_EndColumn()
 FSharp.Compiler.Text.Range: Int32 get_EndLine()
 FSharp.Compiler.Text.Range: Int32 get_StartColumn()
 FSharp.Compiler.Text.Range: Int32 get_StartLine()
+FSharp.Compiler.Text.Range: Microsoft.FSharp.Core.FSharpValueOption`1[FSharp.Compiler.Text.Range] OriginalRange
+FSharp.Compiler.Text.Range: Microsoft.FSharp.Core.FSharpValueOption`1[FSharp.Compiler.Text.Range] get_OriginalRange()
 FSharp.Compiler.Text.Range: System.String FileName
 FSharp.Compiler.Text.Range: System.String ToString()
 FSharp.Compiler.Text.Range: System.String get_FileName()
@@ -10924,6 +10928,7 @@ FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range get_range0()
 FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range get_rangeCmdArgs()
 FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range get_rangeStartup()
 FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range mkFileIndexRange(Int32, FSharp.Compiler.Text.Position, FSharp.Compiler.Text.Position)
+FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range mkFileIndexRangeWithOriginRange(Int32, FSharp.Compiler.Text.Position, FSharp.Compiler.Text.Position, Int32, FSharp.Compiler.Text.Position, FSharp.Compiler.Text.Position)
 FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range mkFirstLineOfFile(System.String)
 FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range mkRange(System.String, FSharp.Compiler.Text.Position, FSharp.Compiler.Text.Position)
 FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range range0
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl
index 4f429d04961..13db0f479fd 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl
@@ -5,6 +5,7 @@
 [IL]: Error [UnmanagedPointer]: : FSharp.Compiler.IO.RawByteMemory::.ctor(uint8*, int32, object)][offset 0x00000009] Unmanaged pointers are not a verifiable type.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::get_Item(int32)][offset 0x0000001E][found Native Int] Expected ByRef on the stack.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::set_Item(int32, uint8)][offset 0x00000025][found Native Int] Expected ByRef on the stack.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.Range::ToString()][offset 0x00000021] Callvirt on a value type method.
 [IL]: Error [ReturnPtrToStack]: : Internal.Utilities.Text.Lexing.LexBuffer`1::get_LexemeView()][offset 0x00000019] Return type is ByRef, TypedReference, ArgHandle, or ArgIterator.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.Text.Lexing.UnicodeTables::scanUntilSentinel([FSharp.Compiler.Service]Internal.Utilities.Text.Lexing.LexBuffer`1<char>, int32)][offset 0x00000079][found Short] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Xml.XmlDoc::processLines([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>)][offset 0x00000031][found Char] Unexpected type on the stack.
@@ -21,7 +22,7 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x00000082][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3516-802::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001E5][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3525-802::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001E5][found Char] Unexpected type on the stack.
 [IL]: Error [UnmanagedPointer]: : FSharp.Compiler.Interactive.Shell+Utilities+pointerToNativeInt@110::Invoke(object)][offset 0x00000007] Unmanaged pointers are not a verifiable type.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharpCheckerResults+dataTipOfReferences@2205::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000084][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$ServiceLexing+clo@921-509::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<FSharp.Compiler.Parser+token,int32,int32>,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack.
@@ -59,7 +60,7 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x0000000B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x00000021][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000CD][found Char] Unexpected type on the stack.
-[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@558::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@591::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000037][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000043][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack.
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl
index 2ec0116a1af..74d8bba9461 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl
@@ -5,6 +5,7 @@
 [IL]: Error [UnmanagedPointer]: : FSharp.Compiler.IO.RawByteMemory::.ctor(uint8*, int32, object)][offset 0x00000009] Unmanaged pointers are not a verifiable type.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::get_Item(int32)][offset 0x0000001E][found Native Int] Expected ByRef on the stack.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::set_Item(int32, uint8)][offset 0x00000025][found Native Int] Expected ByRef on the stack.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.Range::ToString()][offset 0x00000021] Callvirt on a value type method.
 [IL]: Error [ReturnPtrToStack]: : Internal.Utilities.Text.Lexing.LexBuffer`1::get_LexemeView()][offset 0x00000019] Return type is ByRef, TypedReference, ArgHandle, or ArgIterator.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.Text.Lexing.UnicodeTables::scanUntilSentinel([FSharp.Compiler.Service]Internal.Utilities.Text.Lexing.LexBuffer`1<char>, int32)][offset 0x00000079][found Short] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Xml.XmlDoc::processLines([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>)][offset 0x00000031][found Char] Unexpected type on the stack.
@@ -27,8 +28,9 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x00000082][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiStdinSyphon::GetLine(string, int32)][offset 0x00000039][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiStdinSyphon::GetLineNoPrune(string, int32)][offset 0x0000002B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3516-802::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001E5][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3525-802::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001E5][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiInteractionProcessor::CompletionsForPartialLID([FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompilerState, string)][offset 0x0000001B][found Char] Unexpected type on the stack.
 [IL]: Error [UnmanagedPointer]: : FSharp.Compiler.Interactive.Shell+Utilities+pointerToNativeInt@110::Invoke(object)][offset 0x00000007] Unmanaged pointers are not a verifiable type.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharpCheckerResults+dataTipOfReferences@2205::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000084][found Char] Unexpected type on the stack.
@@ -84,7 +86,7 @@
 [IL]: Error [StackUnexpected]: : Internal.Utilities.FSharpEnvironment+probePathForDotnetHost@322::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000028][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.SimulatedMSBuildReferenceResolver+Pipe #6 input at line 68@68::FSharp.Compiler.CodeAnalysis.ILegacyReferenceResolver.Resolve([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyResolutionEnvironment, [S.P.CoreLib]System.Tuple`2<string,string>[], string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>, string, string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>, string, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.Unit>, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<bool,Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.Unit>>>)][offset 0x0000034D][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000CD][found Char] Unexpected type on the stack.
-[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@558::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@591::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000037][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000043][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack.
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl
index 48210dddd5c..f7e59f4de97 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl
@@ -5,6 +5,7 @@
 [IL]: Error [UnmanagedPointer]: : FSharp.Compiler.IO.RawByteMemory::.ctor(uint8*, int32, object)][offset 0x00000009] Unmanaged pointers are not a verifiable type.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::get_Item(int32)][offset 0x0000001A][found Native Int] Expected ByRef on the stack.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::set_Item(int32, uint8)][offset 0x0000001B][found Native Int] Expected ByRef on the stack.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.Range::ToString()][offset 0x0000001F] Callvirt on a value type method.
 [IL]: Error [ReturnPtrToStack]: : Internal.Utilities.Text.Lexing.LexBuffer`1::get_LexemeView()][offset 0x00000017] Return type is ByRef, TypedReference, ArgHandle, or ArgIterator.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.Text.Lexing.UnicodeTables::scanUntilSentinel([FSharp.Compiler.Service]Internal.Utilities.Text.Lexing.LexBuffer`1<char>, int32)][offset 0x0000008D][found Short] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Xml.XmlDoc::processLines([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>)][offset 0x0000002C][found Char] Unexpected type on the stack.
@@ -21,7 +22,7 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x00000082][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3516-846::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001C7][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3525-846::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001C7][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharpCheckerResults+GetReferenceResolutionStructuredToolTipText@2205::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000076][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$ServiceLexing+clo@921-530::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<FSharp.Compiler.Parser+token,int32,int32>,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$ServiceLexing+clo@921-530::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<FSharp.Compiler.Parser+token,int32,int32>,Microsoft.FSharp.Core.Unit>)][offset 0x0000003B][found Char] Unexpected type on the stack.
@@ -85,7 +86,7 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x0000000B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x00000021][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000B6][found Char] Unexpected type on the stack.
-[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@558::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@591::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000035][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000041][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack.
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl
index 2df2cf0fbd9..737cce948c6 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl
@@ -5,6 +5,7 @@
 [IL]: Error [UnmanagedPointer]: : FSharp.Compiler.IO.RawByteMemory::.ctor(uint8*, int32, object)][offset 0x00000009] Unmanaged pointers are not a verifiable type.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::get_Item(int32)][offset 0x0000001A][found Native Int] Expected ByRef on the stack.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::set_Item(int32, uint8)][offset 0x0000001B][found Native Int] Expected ByRef on the stack.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.Range::ToString()][offset 0x0000001F] Callvirt on a value type method.
 [IL]: Error [ReturnPtrToStack]: : Internal.Utilities.Text.Lexing.LexBuffer`1::get_LexemeView()][offset 0x00000017] Return type is ByRef, TypedReference, ArgHandle, or ArgIterator.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.Text.Lexing.UnicodeTables::scanUntilSentinel([FSharp.Compiler.Service]Internal.Utilities.Text.Lexing.LexBuffer`1<char>, int32)][offset 0x0000008D][found Short] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Xml.XmlDoc::processLines([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>)][offset 0x0000002C][found Char] Unexpected type on the stack.
@@ -27,8 +28,9 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x00000082][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiStdinSyphon::GetLine(string, int32)][offset 0x00000032][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiStdinSyphon::GetLineNoPrune(string, int32)][offset 0x0000002B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3516-846::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001C7][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3525-846::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001C7][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiInteractionProcessor::CompletionsForPartialLID([FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompilerState, string)][offset 0x00000024][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharpCheckerResults+GetReferenceResolutionStructuredToolTipText@2205::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000076][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.AssemblyContent+traverseMemberFunctionAndValues@176::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue)][offset 0x0000002B][found Char] Unexpected type on the stack.
@@ -111,7 +113,7 @@
 [IL]: Error [StackUnexpected]: : Internal.Utilities.FSharpEnvironment::probePathForDotnetHost@321([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x0000002A][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.SimulatedMSBuildReferenceResolver+SimulatedMSBuildResolver@68::FSharp.Compiler.CodeAnalysis.ILegacyReferenceResolver.Resolve([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyResolutionEnvironment, [S.P.CoreLib]System.Tuple`2<string,string>[], string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>, string, string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>, string, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.Unit>, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<bool,Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.Unit>>>)][offset 0x000002F5][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000B6][found Char] Unexpected type on the stack.
-[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@558::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@591::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000035][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000041][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack.

From 77697cd1260cb2eaee651dcb95632d8719062f21 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Wed, 26 Feb 2025 13:19:19 +0800
Subject: [PATCH 28/57] fix tests

---
 .../CustomAttributes/CallerArgumentExpression.fs          | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
index 162ebf21b25..24bec9f202b 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
@@ -7,7 +7,7 @@ open FSharp.Test.Compiler
 
 module CustomAttributes_CallerArgumentExpression =
 
-    [<Fact>]
+    [<FactForNETCOREAPP>]
     let ``Can consume CallerArgumentExpression in BCL methods`` () =
         FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
 try System.ArgumentException.ThrowIfNullOrWhiteSpace(Seq.init 50 (fun _ -> " ")
@@ -22,7 +22,7 @@ with :? System.ArgumentException as ex ->
         |> shouldSucceed
         |> ignore
 
-    [<Fact>]
+    [<FactForNETCOREAPP>]
     let ``Can define in F#`` () =
         FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
 open System.Runtime.CompilerServices
@@ -44,7 +44,7 @@ assertEqual (A.aa(stringABC)) ("abc", ".cctor", 13, "stringABC")
         |> shouldSucceed
         |> ignore
 
-    [<Fact>]
+    [<FactForNETCOREAPP>]
     let ``Can define in F# with F#-style optional arguments`` () =
         FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
 open System.Runtime.CompilerServices
@@ -69,7 +69,7 @@ assertEqual (A.aa(stringABC)) ("abc", ".cctor", 16, "stringABC")
         |> shouldSucceed
         |> ignore
 
-    [<Fact>]
+    [<FactForNETCOREAPP>]
     let ``Can define in F# - with #line`` () =
         FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
 open System.Runtime.CompilerServices

From 1e43eff8b31bb2994b76bcdd18aa147dd6a409ce Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Wed, 26 Feb 2025 17:01:27 +0800
Subject: [PATCH 29/57] test

---
 .../CustomAttributes/CallerArgumentExpression.fs                 | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
index 24bec9f202b..1d0cdf2d00b 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
@@ -4,6 +4,7 @@ namespace Conformance.BasicGrammarElements
 
 open Xunit
 open FSharp.Test.Compiler
+open FSharp.Test
 
 module CustomAttributes_CallerArgumentExpression =
 

From 52a0fc0f82fb55b6d57dd55d3506f4ebe02b29f1 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Tue, 11 Mar 2025 11:17:27 +0800
Subject: [PATCH 30/57] fix named arguments didn't trigger the feature

---
 src/Compiler/Checking/MethodCalls.fs          | 58 +++++++++----------
 .../CallerArgumentExpression.fs               | 14 +++++
 2 files changed, 41 insertions(+), 31 deletions(-)

diff --git a/src/Compiler/Checking/MethodCalls.fs b/src/Compiler/Checking/MethodCalls.fs
index 7f27b5ddc14..ac13b880bf7 100644
--- a/src/Compiler/Checking/MethodCalls.fs
+++ b/src/Compiler/Checking/MethodCalls.fs
@@ -1437,9 +1437,19 @@ let AdjustCallerArgExpr tcVal (g: TcGlobals) amap infoReader ad isOutArg calledA
 /// matter what order they are applied in as long as they are all composed together.
 let emptyPreBinder (e: Expr) = e
 
+let tryPickArgumentCodeText assignedArgs paramName =
+    assignedArgs
+    |> List.tryPick (fun { CalledArg=called; CallerArg=caller } -> 
+    match called.NameOpt with
+    | Some x when x.idText = paramName ->
+        let code = FileContent.getCodeText caller.Range
+        if System.String.IsNullOrEmpty code then None
+        else Some code
+    | _ -> None)
+
 /// Get the expression that must be inserted on the caller side for a CallerSide optional arg,
 /// i.e. one where there is no corresponding caller arg.
-let rec GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g (calledArg: CalledArg) currCalledArgTy currDfltVal eCallerMemberName mMethExpr unnamedArgs =
+let rec GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g (calledArg: CalledArg) currCalledArgTy currDfltVal eCallerMemberName mMethExpr assignedArgs =
     match currDfltVal with
     | MissingValue -> 
         // Add an I_nop if this is an initonly field to make sure we never recognize it as an lvalue. See mkExprAddrOfExpr. 
@@ -1456,7 +1466,7 @@ let rec GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g (calledArg: C
             let ctorArgs = [Expr.Const (tcFieldInit mMethExpr fieldInit, mMethExpr, inst)]
             emptyPreBinder, Expr.Op (TOp.ILCall (false, false, true, true, NormalValUse, false, false, ctor, [inst], [], [currCalledArgTy]), [], ctorArgs, mMethExpr)
         | ByrefTy g inst ->
-            GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g calledArg inst (PassByRef(inst, currDfltVal)) eCallerMemberName mMethExpr unnamedArgs
+            GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g calledArg inst (PassByRef(inst, currDfltVal)) eCallerMemberName mMethExpr assignedArgs
         | _ ->
             match calledArg.CallerInfo, eCallerMemberName with
             | CallerLineNumber, _ when typeEquiv g currCalledArgTy g.int_ty ->
@@ -1468,17 +1478,11 @@ let rec GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g (calledArg: C
                 emptyPreBinder, Expr.Const (Const.String callerName, mMethExpr, currCalledArgTy)
             
             | CallerArgumentExpression param, _ when g.langVersion.SupportsFeature LanguageFeature.SupportCallerArgumentExpression && typeEquiv g currCalledArgTy g.string_ty ->
-                let str =
-                    unnamedArgs
-                    |> List.tryPick (fun { CalledArg=called; CallerArg=caller } -> 
-                        match called.NameOpt with
-                        | Some x when x.idText = param ->
-                            let code = FileContent.getCodeText caller.Range
-                            if System.String.IsNullOrEmpty code then None
-                            else Some (Const.String code)
-                        | _ -> None)
-                    |> Option.defaultWith (fun _ -> tcFieldInit mMethExpr fieldInit)
-                emptyPreBinder, Expr.Const (str, mMethExpr, currCalledArgTy)
+                let stringConst =
+                    match tryPickArgumentCodeText assignedArgs param with
+                    | Some code -> Const.String code
+                    | None -> tcFieldInit mMethExpr fieldInit
+                emptyPreBinder, Expr.Const (stringConst, mMethExpr, currCalledArgTy)
             
             | _ ->
                 emptyPreBinder, Expr.Const (tcFieldInit mMethExpr fieldInit, mMethExpr, currCalledArgTy)
@@ -1503,13 +1507,13 @@ let rec GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g (calledArg: C
 
     | PassByRef (ty, dfltVal2) ->
         let v, _ = mkCompGenLocal mMethExpr "defaultByrefArg" ty
-        let wrapper2, rhs = GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g calledArg currCalledArgTy dfltVal2 eCallerMemberName mMethExpr unnamedArgs
+        let wrapper2, rhs = GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g calledArg currCalledArgTy dfltVal2 eCallerMemberName mMethExpr assignedArgs
         (wrapper2 >> mkCompGenLet mMethExpr v rhs), mkValAddr mMethExpr false (mkLocalValRef v)
 
 /// Get the expression that must be inserted on the caller side for a CalleeSide optional arg where
 /// no caller argument has been provided. Normally this is 'None', however CallerMemberName and friends
 /// can be used with 'CalleeSide' optional arguments
-let GetDefaultExpressionForCalleeSideOptionalArg g (calledArg: CalledArg) eCallerMemberName (mMethExpr: range) unnamedArgs =
+let GetDefaultExpressionForCalleeSideOptionalArg g (calledArg: CalledArg) eCallerMemberName (mMethExpr: range) assignedArgs =
     let calledArgTy = calledArg.CalledArgumentType
     let calledNonOptTy = tryDestOptionalTy g calledArgTy
 
@@ -1526,18 +1530,10 @@ let GetDefaultExpressionForCalleeSideOptionalArg g (calledArg: CalledArg) eCalle
         mkSome g calledNonOptTy memberNameExpr mMethExpr
 
     | CallerArgumentExpression param, _ when g.langVersion.SupportsFeature LanguageFeature.SupportCallerArgumentExpression && typeEquiv g calledNonOptTy g.string_ty ->
-        let exprOpt =
-            unnamedArgs
-            |> List.tryPick (fun { CalledArg=called; CallerArg=caller } -> 
-                match called.NameOpt with
-                | Some x when x.idText = param ->
-                    let code = FileContent.getCodeText caller.Range
-                    if System.String.IsNullOrEmpty code then None
-                    else Some (Expr.Const(Const.String code, mMethExpr, calledNonOptTy))
-                | _ -> None)
-
-        match exprOpt with
-        | Some expr -> mkSome g calledNonOptTy expr mMethExpr
+        match tryPickArgumentCodeText assignedArgs param with
+        | Some code -> 
+            let expr = Expr.Const(Const.String code, mMethExpr, calledNonOptTy)
+            mkSome g calledNonOptTy expr mMethExpr
         | None -> mkNone g calledNonOptTy mMethExpr
 
     | _ ->
@@ -1546,7 +1542,7 @@ let GetDefaultExpressionForCalleeSideOptionalArg g (calledArg: CalledArg) eCalle
 
 /// Get the expression that must be inserted on the caller side for an optional arg where
 /// no caller argument has been provided. 
-let GetDefaultExpressionForOptionalArg tcFieldInit g (calledArg: CalledArg) eCallerMemberName mItem (mMethExpr: range) unnamedArgs =
+let GetDefaultExpressionForOptionalArg tcFieldInit g (calledArg: CalledArg) eCallerMemberName mItem (mMethExpr: range) assignedArgs =
     let calledArgTy = calledArg.CalledArgumentType
     let preBinder, expr = 
         match calledArg.OptArgInfo with 
@@ -1554,10 +1550,10 @@ let GetDefaultExpressionForOptionalArg tcFieldInit g (calledArg: CalledArg) eCal
             error(InternalError("Unexpected NotOptional", mItem))
 
         | CallerSide dfltVal ->
-            GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g calledArg calledArgTy dfltVal eCallerMemberName mMethExpr unnamedArgs
+            GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g calledArg calledArgTy dfltVal eCallerMemberName mMethExpr assignedArgs
 
         | CalleeSide ->
-            emptyPreBinder, GetDefaultExpressionForCalleeSideOptionalArg g calledArg eCallerMemberName mMethExpr unnamedArgs
+            emptyPreBinder, GetDefaultExpressionForCalleeSideOptionalArg g calledArg eCallerMemberName mMethExpr assignedArgs
 
     // Combine the variable allocators (if any)
     let callerArg = CallerArg(calledArgTy, mMethExpr, false, expr)
@@ -1675,7 +1671,7 @@ let AdjustCallerArgsForOptionals tcVal tcFieldInit eCallerMemberName (infoReader
     // i.e. there is no corresponding caller arg.
     let optArgs, optArgPreBinder = 
         (emptyPreBinder, calledMeth.UnnamedCalledOptArgs) ||> List.mapFold (fun preBinder calledArg -> 
-            let preBinder2, arg = GetDefaultExpressionForOptionalArg tcFieldInit g calledArg eCallerMemberName mItem mMethExpr unnamedArgs
+            let preBinder2, arg = GetDefaultExpressionForOptionalArg tcFieldInit g calledArg eCallerMemberName mItem mMethExpr (assignedNamedArgs @ unnamedArgs)
             arg, (preBinder >> preBinder2))
 
     let adjustedNormalUnnamedArgs = List.map (AdjustCallerArgForOptional tcVal tcFieldInit eCallerMemberName infoReader ad) unnamedArgs
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
index 1d0cdf2d00b..ec3ddab4539 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
@@ -16,6 +16,13 @@ try System.ArgumentException.ThrowIfNullOrWhiteSpace(Seq.init 50 (fun _ -> " ")
   |> String.concat " ")
 with :? System.ArgumentException as ex -> 
   assertEqual true (ex.Message.Contains("(Parameter 'Seq.init 50 (fun _ -> \" \")\n  (* comment *) \n  |> String.concat \" \""))
+  
+
+try System.ArgumentException.ThrowIfNullOrWhiteSpace(argument = (Seq.init 11 (fun _ -> " ")
+  (* comment *) 
+  |> String.concat " "))
+with :? System.ArgumentException as ex -> 
+  assertEqual true (ex.Message.Contains("(Parameter '(Seq.init 11 (fun _ -> \" \")\n  (* comment *) \n  |> String.concat \" \")"))
 """
         |> withLangVersionPreview
         |> asExe
@@ -38,6 +45,7 @@ type A() =
 
 let stringABC = "abc"
 assertEqual (A.aa(stringABC)) ("abc", ".cctor", 13, "stringABC")
+assertEqual (A.aa(a = stringABC)) ("abc", ".cctor", 14, "stringABC")
         """
         |> withLangVersionPreview
         |> asExe
@@ -63,6 +71,7 @@ type A() =
 
 let stringABC = "abc"
 assertEqual (A.aa(stringABC)) ("abc", ".cctor", 16, "stringABC")
+assertEqual (A.aa(a = stringABC)) ("abc", ".cctor", 17, "stringABC")
         """
         |> withLangVersionPreview
         |> asExe
@@ -75,6 +84,9 @@ assertEqual (A.aa(stringABC)) ("abc", ".cctor", 16, "stringABC")
         FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
 open System.Runtime.CompilerServices
 open System.Runtime.InteropServices
+
+let path = System.IO.Path.Combine(__SOURCE_DIRECTORY__, "test.fs")
+
 # 1 "test.fs"
 type A() =
   static member aa (
@@ -89,6 +101,8 @@ let stringABC = "abc"
 assertEqual (A.aa(stringABC)) ("abc", ".cctor", 11, System.IO.Path.Combine(__SOURCE_DIRECTORY__, "test.fs"), "stringABC")
 # 1 "test.fs"
 assertEqual (A.aa(stringABC : string)) ("abc", ".cctor", 1, System.IO.Path.Combine(__SOURCE_DIRECTORY__, "test.fs"), "stringABC : string")
+# 1 "test.fs"
+assertEqual (A.aa(a = (stringABC : string))) ("abc", ".cctor", 1, System.IO.Path.Combine(__SOURCE_DIRECTORY__, "test.fs"), "(stringABC : string)")
         """
         |> withLangVersionPreview
         |> asExe

From 24a949425233aa61bed7d29bbe35e079f84b3be7 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Tue, 11 Mar 2025 12:12:39 +0800
Subject: [PATCH 31/57] baseline

---
 .../ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl       | 5 +++--
 ...lverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl | 6 ++++--
 .../ilverify_FSharp.Compiler.Service_Release_net9.0.bsl     | 5 +++--
 ...erify_FSharp.Compiler.Service_Release_netstandard2.0.bsl | 6 ++++--
 4 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl
index ad200989d8c..c186d50cdcd 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl
@@ -5,6 +5,7 @@
 [IL]: Error [UnmanagedPointer]: : FSharp.Compiler.IO.RawByteMemory::.ctor(uint8*, int32, object)][offset 0x00000009] Unmanaged pointers are not a verifiable type.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::get_Item(int32)][offset 0x0000001E][found Native Int] Expected ByRef on the stack.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::set_Item(int32, uint8)][offset 0x00000025][found Native Int] Expected ByRef on the stack.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.Range::ToString()][offset 0x00000021] Callvirt on a value type method.
 [IL]: Error [ReturnPtrToStack]: : Internal.Utilities.Text.Lexing.LexBuffer`1::get_LexemeView()][offset 0x00000019] Return type is ByRef, TypedReference, ArgHandle, or ArgIterator.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.Text.Lexing.UnicodeTables::scanUntilSentinel([FSharp.Compiler.Service]Internal.Utilities.Text.Lexing.LexBuffer`1<char>, int32)][offset 0x00000079][found Short] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Xml.XmlDoc::processLines([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>)][offset 0x00000031][found Char] Unexpected type on the stack.
@@ -21,7 +22,7 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x00000082][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3516-805::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001E5][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3525-805::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001E5][found Char] Unexpected type on the stack.
 [IL]: Error [UnmanagedPointer]: : FSharp.Compiler.Interactive.Shell+Utilities+pointerToNativeInt@110::Invoke(object)][offset 0x00000007] Unmanaged pointers are not a verifiable type.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharpCheckerResults+dataTipOfReferences@2205::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000084][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$ServiceLexing+clo@921-509::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<FSharp.Compiler.Parser+token,int32,int32>,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack.
@@ -59,7 +60,7 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x0000000B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x00000021][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000CD][found Char] Unexpected type on the stack.
-[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@558::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@591::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000037][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000043][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack.
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl
index c23aae09751..7e1976ee6db 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl
@@ -5,6 +5,7 @@
 [IL]: Error [UnmanagedPointer]: : FSharp.Compiler.IO.RawByteMemory::.ctor(uint8*, int32, object)][offset 0x00000009] Unmanaged pointers are not a verifiable type.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::get_Item(int32)][offset 0x0000001E][found Native Int] Expected ByRef on the stack.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::set_Item(int32, uint8)][offset 0x00000025][found Native Int] Expected ByRef on the stack.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.Range::ToString()][offset 0x00000021] Callvirt on a value type method.
 [IL]: Error [ReturnPtrToStack]: : Internal.Utilities.Text.Lexing.LexBuffer`1::get_LexemeView()][offset 0x00000019] Return type is ByRef, TypedReference, ArgHandle, or ArgIterator.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.Text.Lexing.UnicodeTables::scanUntilSentinel([FSharp.Compiler.Service]Internal.Utilities.Text.Lexing.LexBuffer`1<char>, int32)][offset 0x00000079][found Short] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Xml.XmlDoc::processLines([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>)][offset 0x00000031][found Char] Unexpected type on the stack.
@@ -27,8 +28,9 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x00000082][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiStdinSyphon::GetLine(string, int32)][offset 0x00000039][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiStdinSyphon::GetLineNoPrune(string, int32)][offset 0x0000002B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3516-805::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001E5][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3525-805::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001E5][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiInteractionProcessor::CompletionsForPartialLID([FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompilerState, string)][offset 0x0000001B][found Char] Unexpected type on the stack.
 [IL]: Error [UnmanagedPointer]: : FSharp.Compiler.Interactive.Shell+Utilities+pointerToNativeInt@110::Invoke(object)][offset 0x00000007] Unmanaged pointers are not a verifiable type.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharpCheckerResults+dataTipOfReferences@2205::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000084][found Char] Unexpected type on the stack.
@@ -84,7 +86,7 @@
 [IL]: Error [StackUnexpected]: : Internal.Utilities.FSharpEnvironment+probePathForDotnetHost@322::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000028][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.SimulatedMSBuildReferenceResolver+Pipe #6 input at line 68@68::FSharp.Compiler.CodeAnalysis.ILegacyReferenceResolver.Resolve([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyResolutionEnvironment, [S.P.CoreLib]System.Tuple`2<string,string>[], string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>, string, string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>, string, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.Unit>, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<bool,Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.Unit>>>)][offset 0x0000034D][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000CD][found Char] Unexpected type on the stack.
-[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@558::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@591::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000037][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000043][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack.
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl
index 853566a3c47..dbff4c2f01f 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl
@@ -5,6 +5,7 @@
 [IL]: Error [UnmanagedPointer]: : FSharp.Compiler.IO.RawByteMemory::.ctor(uint8*, int32, object)][offset 0x00000009] Unmanaged pointers are not a verifiable type.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::get_Item(int32)][offset 0x0000001A][found Native Int] Expected ByRef on the stack.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::set_Item(int32, uint8)][offset 0x0000001B][found Native Int] Expected ByRef on the stack.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.Range::ToString()][offset 0x0000001F] Callvirt on a value type method.
 [IL]: Error [ReturnPtrToStack]: : Internal.Utilities.Text.Lexing.LexBuffer`1::get_LexemeView()][offset 0x00000017] Return type is ByRef, TypedReference, ArgHandle, or ArgIterator.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.Text.Lexing.UnicodeTables::scanUntilSentinel([FSharp.Compiler.Service]Internal.Utilities.Text.Lexing.LexBuffer`1<char>, int32)][offset 0x0000008D][found Short] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Xml.XmlDoc::processLines([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>)][offset 0x0000002C][found Char] Unexpected type on the stack.
@@ -21,7 +22,7 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x00000082][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3516-849::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001C7][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3525-849::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001C7][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharpCheckerResults+GetReferenceResolutionStructuredToolTipText@2205::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000076][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$ServiceLexing+clo@921-530::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<FSharp.Compiler.Parser+token,int32,int32>,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$ServiceLexing+clo@921-530::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<FSharp.Compiler.Parser+token,int32,int32>,Microsoft.FSharp.Core.Unit>)][offset 0x0000003B][found Char] Unexpected type on the stack.
@@ -85,7 +86,7 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x0000000B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x00000021][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000B6][found Char] Unexpected type on the stack.
-[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@558::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@591::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000035][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000041][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack.
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl
index 356b98ede2b..c8ea20d4186 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl
@@ -5,6 +5,7 @@
 [IL]: Error [UnmanagedPointer]: : FSharp.Compiler.IO.RawByteMemory::.ctor(uint8*, int32, object)][offset 0x00000009] Unmanaged pointers are not a verifiable type.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::get_Item(int32)][offset 0x0000001A][found Native Int] Expected ByRef on the stack.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::set_Item(int32, uint8)][offset 0x0000001B][found Native Int] Expected ByRef on the stack.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.Range::ToString()][offset 0x0000001F] Callvirt on a value type method.
 [IL]: Error [ReturnPtrToStack]: : Internal.Utilities.Text.Lexing.LexBuffer`1::get_LexemeView()][offset 0x00000017] Return type is ByRef, TypedReference, ArgHandle, or ArgIterator.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.Text.Lexing.UnicodeTables::scanUntilSentinel([FSharp.Compiler.Service]Internal.Utilities.Text.Lexing.LexBuffer`1<char>, int32)][offset 0x0000008D][found Short] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Xml.XmlDoc::processLines([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>)][offset 0x0000002C][found Char] Unexpected type on the stack.
@@ -27,8 +28,9 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x00000082][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiStdinSyphon::GetLine(string, int32)][offset 0x00000032][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiStdinSyphon::GetLineNoPrune(string, int32)][offset 0x0000002B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3516-849::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001C7][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3525-849::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001C7][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiInteractionProcessor::CompletionsForPartialLID([FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompilerState, string)][offset 0x00000024][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharpCheckerResults+GetReferenceResolutionStructuredToolTipText@2205::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000076][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.AssemblyContent+traverseMemberFunctionAndValues@176::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue)][offset 0x0000002B][found Char] Unexpected type on the stack.
@@ -111,7 +113,7 @@
 [IL]: Error [StackUnexpected]: : Internal.Utilities.FSharpEnvironment::probePathForDotnetHost@321([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x0000002A][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.SimulatedMSBuildReferenceResolver+SimulatedMSBuildResolver@68::FSharp.Compiler.CodeAnalysis.ILegacyReferenceResolver.Resolve([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyResolutionEnvironment, [S.P.CoreLib]System.Tuple`2<string,string>[], string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>, string, string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>, string, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.Unit>, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<bool,Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.Unit>>>)][offset 0x000002F5][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000B6][found Char] Unexpected type on the stack.
-[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@558::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@591::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000035][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000041][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack.

From 31125f5d6ec4a610d62e9d46c0fe50714e86542f Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Fri, 14 Mar 2025 00:21:53 +0800
Subject: [PATCH 32/57] add new tests; improve err msg

---
 src/Compiler/Checking/PostInferenceChecks.fs  | 66 +++++++--------
 src/Compiler/FSComp.txt                       |  4 +-
 src/Compiler/xlf/FSComp.txt.cs.xlf            |  8 +-
 src/Compiler/xlf/FSComp.txt.de.xlf            |  8 +-
 src/Compiler/xlf/FSComp.txt.es.xlf            |  8 +-
 src/Compiler/xlf/FSComp.txt.fr.xlf            |  8 +-
 src/Compiler/xlf/FSComp.txt.it.xlf            |  8 +-
 src/Compiler/xlf/FSComp.txt.ja.xlf            |  8 +-
 src/Compiler/xlf/FSComp.txt.ko.xlf            |  8 +-
 src/Compiler/xlf/FSComp.txt.pl.xlf            |  8 +-
 src/Compiler/xlf/FSComp.txt.pt-BR.xlf         |  8 +-
 src/Compiler/xlf/FSComp.txt.ru.xlf            |  8 +-
 src/Compiler/xlf/FSComp.txt.tr.xlf            |  8 +-
 src/Compiler/xlf/FSComp.txt.zh-Hans.xlf       |  8 +-
 src/Compiler/xlf/FSComp.txt.zh-Hant.xlf       |  8 +-
 .../CallerArgumentExpression.fs               | 84 +++++++++++++++++++
 .../ErrorMessages/UnsupportedAttributes.fs    |  9 +-
 17 files changed, 172 insertions(+), 95 deletions(-)

diff --git a/src/Compiler/Checking/PostInferenceChecks.fs b/src/Compiler/Checking/PostInferenceChecks.fs
index 0e36061e520..be701cd9d41 100644
--- a/src/Compiler/Checking/PostInferenceChecks.fs
+++ b/src/Compiler/Checking/PostInferenceChecks.fs
@@ -2400,22 +2400,36 @@ let CheckEntityDefn cenv env (tycon: Entity) =
                 errorR(Error(FSComp.SR.chkCurriedMethodsCantHaveOutParams(), m))
 
             if numCurriedArgSets = 1 then
-                let paramNames =
-                    paramDatas 
-                    |> List.concat
-                    |> List.choose (fun (ParamData(_, _, _, _, _, nameOpt, _, _)) -> nameOpt)
+                let errorIfNotStringTy m ty callerInfo = 
+                    if not (typeEquiv g g.string_ty ty) then
+                        errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfo |> string, "string", NicePrint.minimalStringOfType cenv.denv ty), m))
+                        
+                let errorIfNotStringOptionTy m ty callerInfo =
+                    if not ((isOptionTy g ty) && (typeEquiv g g.string_ty (destOptionTy g ty))) then
+                        errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfo |> string, "string", NicePrint.minimalStringOfType cenv.denv (destOptionTy g ty)), m))
+
+                let paramNames = HashSet()
+                paramDatas
+                |> List.iterSquared (fun (ParamData(_, _, _, _, _, nameOpt, _, _)) ->
+                    nameOpt |> Option.iter (fun name -> paramNames.Add name.idText |> ignore))
 
-                let checkCallerArgumentExpression name (nameOpt: Ident option) =
+                let checkArgOfCallerArgumentExpression m arg (nameOpt: Ident option) =
                     match nameOpt with
-                    | Some ident when name = ident.idText -> 
-                        warning(Error(FSComp.SR.tcCallerArgumentExpressionSelfReferential(name), m))
-                    | _ when paramNames |> List.forall (fun i -> name <> i.idText) -> 
-                        warning(Error(FSComp.SR.tcCallerArgumentExpressionHasInvalidParameterName(name), m))
+                    | Some ident when arg = ident.idText -> 
+                        warning(Error(FSComp.SR.tcCallerArgumentExpressionSelfReferential(), m))
+                    | _ when not (paramNames.Contains arg) -> 
+                        warning(Error(FSComp.SR.tcCallerArgumentExpressionHasInvalidParameterName(), m))
                     | _ -> ()
 
                 paramDatas
                 |> List.iterSquared (fun (ParamData(_, isInArg, _, optArgInfo, callerInfo, nameOpt, _, ty)) ->
                     ignore isInArg
+
+                    let m =
+                        match nameOpt with
+                        | Some name -> name.idRange
+                        | None -> m
+
                     match (optArgInfo, callerInfo) with
                     | _, NoCallerInfo -> ()
                     | NotOptional, _ -> errorR(Error(FSComp.SR.tcCallerInfoNotOptional(callerInfo |> string), m))
@@ -2425,30 +2439,16 @@ let CheckEntityDefn cenv env (tycon: Entity) =
                     | CalleeSide, CallerLineNumber ->
                         if not ((isOptionTy g ty) && (typeEquiv g g.int32_ty (destOptionTy g ty))) then
                             errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfo |> string, "int", NicePrint.minimalStringOfType cenv.denv (destOptionTy g ty)), m))
-                    | CallerSide _, CallerFilePath ->
-                        if not (typeEquiv g g.string_ty ty) then
-                            errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfo |> string, "string", NicePrint.minimalStringOfType cenv.denv ty), m))
-                    | CalleeSide, CallerFilePath ->
-                        if not ((isOptionTy g ty) && (typeEquiv g g.string_ty (destOptionTy g ty))) then
-                            errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfo |> string, "string", NicePrint.minimalStringOfType cenv.denv (destOptionTy g ty)), m))
-                    | CallerSide _, CallerMemberName ->
-                        if not (typeEquiv g g.string_ty ty) then
-                            errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfo |> string, "string", NicePrint.minimalStringOfType cenv.denv ty), m))
-                    | CalleeSide, CallerMemberName ->
-                        if not ((isOptionTy g ty) && (typeEquiv g g.string_ty (destOptionTy g ty))) then
-                            errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfo |> string, "string", NicePrint.minimalStringOfType cenv.denv (destOptionTy g ty)), m))
-                    
-                    | CallerSide _, CallerArgumentExpression name ->
-                        if not (typeEquiv g g.string_ty ty) then
-                            errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfo |> string, "string", NicePrint.minimalStringOfType cenv.denv ty), m))
-
-                        checkCallerArgumentExpression name nameOpt
-
-                    | CalleeSide, CallerArgumentExpression name ->
-                        if not ((isOptionTy g ty) && (typeEquiv g g.string_ty (destOptionTy g ty))) then
-                            errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfo |> string, "string", NicePrint.minimalStringOfType cenv.denv (destOptionTy g ty)), m))
-
-                        checkCallerArgumentExpression name nameOpt
+                    | CallerSide _, (CallerFilePath | CallerMemberName) -> errorIfNotStringTy m ty callerInfo
+                    | CalleeSide, (CallerFilePath | CallerMemberName) -> errorIfNotStringOptionTy m ty callerInfo
+                    | CallerSide _, CallerArgumentExpression arg ->
+                        checkLanguageFeatureError g.langVersion LanguageFeature.SupportCallerArgumentExpression m
+                        errorIfNotStringTy m ty callerInfo
+                        checkArgOfCallerArgumentExpression m arg nameOpt
+                    | CalleeSide, CallerArgumentExpression arg ->
+                        checkLanguageFeatureError g.langVersion LanguageFeature.SupportCallerArgumentExpression m
+                        errorIfNotStringOptionTy m ty callerInfo
+                        checkArgOfCallerArgumentExpression m arg nameOpt
                 )
 
         for pinfo in immediateProps do
diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt
index 9d02d63c5ce..63a53e7dad3 100644
--- a/src/Compiler/FSComp.txt
+++ b/src/Compiler/FSComp.txt
@@ -1799,5 +1799,5 @@ featureDeprecatePlacesWhereSeqCanBeOmitted,"Deprecate places where 'seq' can be
 featureSupportValueOptionsAsOptionalParameters,"Support ValueOption as valid type for optional member parameters"
 featureSupportWarnWhenUnitPassedToObjArg,"Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`."
 featureSupportCallerArgumentExpression,"Support `CallerArgumentExpression`"
-3875,tcCallerArgumentExpressionSelfReferential,"This CallerArgumentExpression with argument '%s' will have no effect because it's self-referential."
-3875,tcCallerArgumentExpressionHasInvalidParameterName,"This CallerArgumentExpression with argument '%s' will have no effect because it's applied with an invalid parameter name."
+3875,tcCallerArgumentExpressionSelfReferential,"The CallerArgumentExpression on this parameter will have no effect because it's self-referential."
+3875,tcCallerArgumentExpressionHasInvalidParameterName,"The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name."
diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf
index e3e0bf6ef35..4bfdfcd169a 100644
--- a/src/Compiler/xlf/FSComp.txt.cs.xlf
+++ b/src/Compiler/xlf/FSComp.txt.cs.xlf
@@ -1368,13 +1368,13 @@
         <note />
       </trans-unit>
       <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
-        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
-        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <source>The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name.</target>
         <note />
       </trans-unit>
       <trans-unit id="tcCallerArgumentExpressionSelfReferential">
-        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
-        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <source>The CallerArgumentExpression on this parameter will have no effect because it's self-referential.</source>
+        <target state="new">The CallerArgumentExpression on this parameter will have no effect because it's self-referential.</target>
         <note />
       </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf
index 8d1f9276025..f17ffc16cf5 100644
--- a/src/Compiler/xlf/FSComp.txt.de.xlf
+++ b/src/Compiler/xlf/FSComp.txt.de.xlf
@@ -1368,13 +1368,13 @@
         <note />
       </trans-unit>
       <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
-        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
-        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <source>The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name.</target>
         <note />
       </trans-unit>
       <trans-unit id="tcCallerArgumentExpressionSelfReferential">
-        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
-        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <source>The CallerArgumentExpression on this parameter will have no effect because it's self-referential.</source>
+        <target state="new">The CallerArgumentExpression on this parameter will have no effect because it's self-referential.</target>
         <note />
       </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf
index e86aaaeb54b..481e70bcb61 100644
--- a/src/Compiler/xlf/FSComp.txt.es.xlf
+++ b/src/Compiler/xlf/FSComp.txt.es.xlf
@@ -1368,13 +1368,13 @@
         <note />
       </trans-unit>
       <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
-        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
-        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <source>The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name.</target>
         <note />
       </trans-unit>
       <trans-unit id="tcCallerArgumentExpressionSelfReferential">
-        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
-        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <source>The CallerArgumentExpression on this parameter will have no effect because it's self-referential.</source>
+        <target state="new">The CallerArgumentExpression on this parameter will have no effect because it's self-referential.</target>
         <note />
       </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf
index f5178e740e8..dc09b017ef6 100644
--- a/src/Compiler/xlf/FSComp.txt.fr.xlf
+++ b/src/Compiler/xlf/FSComp.txt.fr.xlf
@@ -1368,13 +1368,13 @@
         <note />
       </trans-unit>
       <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
-        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
-        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <source>The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name.</target>
         <note />
       </trans-unit>
       <trans-unit id="tcCallerArgumentExpressionSelfReferential">
-        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
-        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <source>The CallerArgumentExpression on this parameter will have no effect because it's self-referential.</source>
+        <target state="new">The CallerArgumentExpression on this parameter will have no effect because it's self-referential.</target>
         <note />
       </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf
index da4fe0cf6d4..9871c03dd56 100644
--- a/src/Compiler/xlf/FSComp.txt.it.xlf
+++ b/src/Compiler/xlf/FSComp.txt.it.xlf
@@ -1368,13 +1368,13 @@
         <note />
       </trans-unit>
       <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
-        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
-        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <source>The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name.</target>
         <note />
       </trans-unit>
       <trans-unit id="tcCallerArgumentExpressionSelfReferential">
-        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
-        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <source>The CallerArgumentExpression on this parameter will have no effect because it's self-referential.</source>
+        <target state="new">The CallerArgumentExpression on this parameter will have no effect because it's self-referential.</target>
         <note />
       </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf
index 02c0c4000ae..fceebe13b2c 100644
--- a/src/Compiler/xlf/FSComp.txt.ja.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ja.xlf
@@ -1368,13 +1368,13 @@
         <note />
       </trans-unit>
       <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
-        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
-        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <source>The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name.</target>
         <note />
       </trans-unit>
       <trans-unit id="tcCallerArgumentExpressionSelfReferential">
-        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
-        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <source>The CallerArgumentExpression on this parameter will have no effect because it's self-referential.</source>
+        <target state="new">The CallerArgumentExpression on this parameter will have no effect because it's self-referential.</target>
         <note />
       </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf
index 1d2032c6450..0d063580dbc 100644
--- a/src/Compiler/xlf/FSComp.txt.ko.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ko.xlf
@@ -1368,13 +1368,13 @@
         <note />
       </trans-unit>
       <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
-        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
-        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <source>The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name.</target>
         <note />
       </trans-unit>
       <trans-unit id="tcCallerArgumentExpressionSelfReferential">
-        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
-        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <source>The CallerArgumentExpression on this parameter will have no effect because it's self-referential.</source>
+        <target state="new">The CallerArgumentExpression on this parameter will have no effect because it's self-referential.</target>
         <note />
       </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf
index 71efe506b81..d74c66459f0 100644
--- a/src/Compiler/xlf/FSComp.txt.pl.xlf
+++ b/src/Compiler/xlf/FSComp.txt.pl.xlf
@@ -1368,13 +1368,13 @@
         <note />
       </trans-unit>
       <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
-        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
-        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <source>The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name.</target>
         <note />
       </trans-unit>
       <trans-unit id="tcCallerArgumentExpressionSelfReferential">
-        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
-        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <source>The CallerArgumentExpression on this parameter will have no effect because it's self-referential.</source>
+        <target state="new">The CallerArgumentExpression on this parameter will have no effect because it's self-referential.</target>
         <note />
       </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
index c816465efea..88ee21f19d3 100644
--- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
+++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
@@ -1368,13 +1368,13 @@
         <note />
       </trans-unit>
       <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
-        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
-        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <source>The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name.</target>
         <note />
       </trans-unit>
       <trans-unit id="tcCallerArgumentExpressionSelfReferential">
-        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
-        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <source>The CallerArgumentExpression on this parameter will have no effect because it's self-referential.</source>
+        <target state="new">The CallerArgumentExpression on this parameter will have no effect because it's self-referential.</target>
         <note />
       </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf
index 942615773e2..0826b26c6c1 100644
--- a/src/Compiler/xlf/FSComp.txt.ru.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ru.xlf
@@ -1368,13 +1368,13 @@
         <note />
       </trans-unit>
       <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
-        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
-        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <source>The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name.</target>
         <note />
       </trans-unit>
       <trans-unit id="tcCallerArgumentExpressionSelfReferential">
-        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
-        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <source>The CallerArgumentExpression on this parameter will have no effect because it's self-referential.</source>
+        <target state="new">The CallerArgumentExpression on this parameter will have no effect because it's self-referential.</target>
         <note />
       </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf
index 0c7ecc3b8c0..6ce660c6191 100644
--- a/src/Compiler/xlf/FSComp.txt.tr.xlf
+++ b/src/Compiler/xlf/FSComp.txt.tr.xlf
@@ -1368,13 +1368,13 @@
         <note />
       </trans-unit>
       <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
-        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
-        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <source>The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name.</target>
         <note />
       </trans-unit>
       <trans-unit id="tcCallerArgumentExpressionSelfReferential">
-        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
-        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <source>The CallerArgumentExpression on this parameter will have no effect because it's self-referential.</source>
+        <target state="new">The CallerArgumentExpression on this parameter will have no effect because it's self-referential.</target>
         <note />
       </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
index ff859dbf685..9c6d632af32 100644
--- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
+++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
@@ -1368,13 +1368,13 @@
         <note />
       </trans-unit>
       <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
-        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
-        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <source>The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name.</target>
         <note />
       </trans-unit>
       <trans-unit id="tcCallerArgumentExpressionSelfReferential">
-        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
-        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <source>The CallerArgumentExpression on this parameter will have no effect because it's self-referential.</source>
+        <target state="new">The CallerArgumentExpression on this parameter will have no effect because it's self-referential.</target>
         <note />
       </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
index 270d867f88e..68d7523eee5 100644
--- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
+++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
@@ -1368,13 +1368,13 @@
         <note />
       </trans-unit>
       <trans-unit id="tcCallerArgumentExpressionHasInvalidParameterName">
-        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</source>
-        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's applied with an invalid parameter name.</target>
+        <source>The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name.</source>
+        <target state="new">The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name.</target>
         <note />
       </trans-unit>
       <trans-unit id="tcCallerArgumentExpressionSelfReferential">
-        <source>This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</source>
-        <target state="new">This CallerArgumentExpression with argument '{0}' will have no effect because it's self-referential.</target>
+        <source>The CallerArgumentExpression on this parameter will have no effect because it's self-referential.</source>
+        <target state="new">The CallerArgumentExpression on this parameter will have no effect because it's self-referential.</target>
         <note />
       </trans-unit>
       <trans-unit id="tcCopyAndUpdateRecordChangesAllFields">
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
index ec3ddab4539..6d0e99fb79b 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
@@ -110,3 +110,87 @@ assertEqual (A.aa(a = (stringABC : string))) ("abc", ".cctor", 1, System.IO.Path
         |> shouldSucceed
         |> ignore
 
+    [<FactForNETCOREAPP>]
+    let ``Can receive special parameter names`` () =
+      FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
+open System.Runtime.CompilerServices
+
+type A() =
+  static member B (``ab c``, [<CallerArgumentExpression "ab c">]?n) =
+    defaultArg n "no value"
+      
+assertEqual (A.B("abc")) "\"abc\""
+        """
+        |> withLangVersionPreview
+        |> asExe
+        |> compileAndRun
+        |> shouldSucceed
+        |> ignore
+        
+    [<FactForNETCOREAPP>]
+    let ``Warn when cannot find the referenced parameter`` () =
+      FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
+open System.Runtime.CompilerServices
+
+type A() =
+  static member B (``ab c``, [<CallerArgumentExpression "abc">]?n) =
+    defaultArg n "no value"
+    
+assertEqual (A.B("abc")) "no value"
+        """
+        |> withLangVersionPreview
+        |> asExe
+        |> compileAndRun
+        |> shouldSucceed
+        |> withSingleDiagnostic (Warning 3875,Line 5, Col 65, Line 5, Col 66, "The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name.")
+        
+    [<FactForNETCOREAPP>]
+    let ``Warn when self referenced`` () =
+      FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
+open System.Runtime.CompilerServices
+
+type A() =
+  static member B (``ab c``, [<CallerArgumentExpression "n">]?n) =
+    defaultArg n "no value"
+    
+assertEqual (A.B("abc")) "no value"
+        """
+        |> withLangVersionPreview
+        |> asExe
+        |> compileAndRun
+        |> shouldSucceed
+        |> withSingleDiagnostic (Warning 3875,Line 5, Col 63 , Line 5, Col 64, "The CallerArgumentExpression on this parameter will have no effect because it's self-referential.")
+        
+    [<FactForNETCOREAPP>]
+    let ``Error when not attached to optional parameters`` () =
+      FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
+open System.Runtime.CompilerServices
+
+type A() =
+  static member B (``ab c``, [<CallerArgumentExpression "ab c">] n) =
+    defaultArg n "no value"
+        """
+        |> withLangVersionPreview
+        |> typecheck
+        |> shouldFail
+        |> withSingleDiagnostic (Error 1247,Line 5, Col 66, Line 5, Col 67, "'CallerArgumentExpression \"ab c\"' can only be applied to optional arguments")
+
+    [<FactForNETCOREAPP>]
+    let ``Error when parameters type not matched`` () =
+      FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
+open System.Runtime.CompilerServices
+open System.Runtime.InteropServices
+
+type A() =
+  static member B (``ab c``, [<CallerArgumentExpression "ab c">]?n) =
+    defaultArg n 123
+  static member C (``ab c``, [<CallerArgumentExpression "ab c"; Optional; DefaultParameterValue 0>] n: int) =
+    n
+        """
+        |> withLangVersionPreview
+        |> typecheck
+        |> shouldFail
+        |> withDiagnostics [
+          (Error 1246,Line 6, Col 66, Line 6, Col 67, "'CallerArgumentExpression \"ab c\"' must be applied to an argument of type 'string', but has been applied to an argument of type 'int'")
+          (Error 1246,Line 8, Col 101, Line 8, Col 102, "'CallerArgumentExpression \"ab c\"' must be applied to an argument of type 'string', but has been applied to an argument of type 'int'")
+        ]
\ No newline at end of file
diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnsupportedAttributes.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnsupportedAttributes.fs
index 8f11db7aa58..295e5115c49 100644
--- a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnsupportedAttributes.fs
+++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnsupportedAttributes.fs
@@ -15,7 +15,7 @@ open System.Runtime.CompilerServices
 let f (w, [<CallerArgumentExpression "w">] x : string) = ()
 let [<ModuleInitializer>] g () = ()
 type C() =
-    member _.F (w, [<System.Runtime.CompilerServices.CallerArgumentExpression "w">] x : string) = ()
+
     [<System.Runtime.CompilerServices.ModuleInitializer>]
     member _.G() = ()
         """
@@ -30,13 +30,6 @@ type C() =
                         EndColumn = 24 }
               Message =
                "This attribute is currently unsupported by the F# compiler. Applying it will not achieve its intended effect." }
-            { Error = Error 1247
-              Range = { StartLine = 6
-                        StartColumn = 14
-                        EndLine = 6
-                        EndColumn = 15 }
-              Message =
-               "'CallerArgumentExpression \"w\"' can only be applied to optional arguments" }
             { Error = Warning 202
               Range = { StartLine = 7
                         StartColumn = 7

From 49c46b1c92c2f6da31848e4183e5064c7010b3ed Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Fri, 14 Mar 2025 01:16:41 +0800
Subject: [PATCH 33/57] adjust code; add and update tests

---
 src/Compiler/SyntaxTree/ParseHelpers.fs       | 20 ++++------
 src/Compiler/Utilities/range.fs               |  4 --
 src/Compiler/Utilities/range.fsi              |  2 -
 .../CallerArgumentExpression.fs               | 40 +++++++++++++++----
 .../Imported/CallerInfo/E_CallerFilePath.fs   |  6 +--
 .../Imported/CallerInfo/E_CallerLineNumber.fs |  6 +--
 .../Imported/CallerInfo/E_CallerMemberName.fs |  6 +--
 .../Imported/CallerInfo/E_MultipleAttrs.fs    |  8 ++--
 8 files changed, 54 insertions(+), 38 deletions(-)

diff --git a/src/Compiler/SyntaxTree/ParseHelpers.fs b/src/Compiler/SyntaxTree/ParseHelpers.fs
index 3b2bc297e28..7169b4d2234 100644
--- a/src/Compiler/SyntaxTree/ParseHelpers.fs
+++ b/src/Compiler/SyntaxTree/ParseHelpers.fs
@@ -45,24 +45,20 @@ let posOfLexOriginalPosition (p: Position) = mkPos p.OriginalLine p.Column
 
 /// Get an F# compiler range from a lexer range
 let mkSynRange (p1: Position) (p2: Position) =
-    let p2' =
+    let range =
         if p1.FileIndex = p2.FileIndex then
-            p2
+            mkFileIndexRange p1.FileIndex (posOfLexPosition p1) (posOfLexPosition p2)
         else
             // This means we had a #line directive in the middle of this syntax element.
-            (p1.ShiftColumnBy 1)
+            mkFileIndexRange p1.FileIndex (posOfLexPosition p1) (posOfLexPosition (p1.ShiftColumnBy 1))
 
-    // TODO need tests
+    // Check if the start position is affected by a #line directive
     if p1.OriginalFileIndex <> p1.FileIndex || p1.OriginalLine <> p1.Line then
-        mkFileIndexRangeWithOriginRange
-            p1.FileIndex
-            (posOfLexPosition p1)
-            (posOfLexPosition p2')
-            p1.OriginalFileIndex
-            (posOfLexOriginalPosition p1)
-            (posOfLexOriginalPosition p2)
+        mkFileIndexRange (p1.OriginalFileIndex) (posOfLexOriginalPosition p1) (posOfLexOriginalPosition p2)
+        |> ValueSome
+        |> range.WithOriginalRange
     else
-        mkFileIndexRange p1.FileIndex (posOfLexPosition p1) (posOfLexPosition p2')
+        range
 
 type LexBuffer<'Char> with
 
diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs
index dfa2b443312..a156568dcdd 100755
--- a/src/Compiler/Utilities/range.fs
+++ b/src/Compiler/Utilities/range.fs
@@ -469,10 +469,6 @@ module Range =
 
     let mkFileIndexRange fileIndex startPos endPos = range (fileIndex, startPos, endPos)
 
-    let mkFileIndexRangeWithOriginRange fileIndex startPos endPos fileIndex2 startPos2 endPos2 =
-        range(fileIndex, startPos, endPos)
-            .WithOriginalRange(ValueSome(range (fileIndex2, startPos2, endPos2)))
-
     let posOrder =
         let pairOrder = Pair.order (Int32.order, Int32.order)
         let lineAndColumn = fun (p: pos) -> p.Line, p.Column
diff --git a/src/Compiler/Utilities/range.fsi b/src/Compiler/Utilities/range.fsi
index 344bd12d85f..ee425d77cc8 100755
--- a/src/Compiler/Utilities/range.fsi
+++ b/src/Compiler/Utilities/range.fsi
@@ -198,8 +198,6 @@ module Range =
     /// This view of range marks uses file indexes explicitly 
     val mkFileIndexRange: FileIndex -> pos -> pos -> range
 
-    val mkFileIndexRangeWithOriginRange: FileIndex -> pos -> pos -> FileIndex -> pos -> pos -> range
-
     /// This view hides the use of file indexes and just uses filenames 
     val mkRange: string -> pos -> pos -> range
 
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
index 6d0e99fb79b..eb44abe4ce5 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
@@ -128,20 +128,47 @@ assertEqual (A.B("abc")) "\"abc\""
         |> ignore
         
     [<FactForNETCOREAPP>]
-    let ``Warn when cannot find the referenced parameter`` () =
+    let ``#line can be inserted in the argument`` () =
       FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
 open System.Runtime.CompilerServices
 
 type A() =
-  static member B (``ab c``, [<CallerArgumentExpression "abc">]?n) =
+  static member B (``ab c``, [<CallerArgumentExpression "ab c">]?n) =
     defaultArg n "no value"
-    
-assertEqual (A.B("abc")) "no value"
+
+A.B("abc"
+#line 1
+: string)
+|> assertEqual "\"abc\"
+#line 1
+: string"
+
+
+A.B((+) 1
+#line 1
+        123)
+|> assertEqual "(+) 1
+#line 1
+        123"
         """
         |> withLangVersionPreview
         |> asExe
         |> compileAndRun
         |> shouldSucceed
+        |> ignore
+        
+    [<FactForNETCOREAPP>]
+    let ``Warn when cannot find the referenced parameter`` () =
+      FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
+open System.Runtime.CompilerServices
+
+type A() =
+  static member B (``ab c``, [<CallerArgumentExpression "abc">]?n) =
+    defaultArg n "no value"
+        """
+        |> withLangVersionPreview
+        |> typecheck
+        |> shouldFail
         |> withSingleDiagnostic (Warning 3875,Line 5, Col 65, Line 5, Col 66, "The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name.")
         
     [<FactForNETCOREAPP>]
@@ -156,9 +183,8 @@ type A() =
 assertEqual (A.B("abc")) "no value"
         """
         |> withLangVersionPreview
-        |> asExe
-        |> compileAndRun
-        |> shouldSucceed
+        |> typecheck
+        |> shouldFail
         |> withSingleDiagnostic (Warning 3875,Line 5, Col 63 , Line 5, Col 64, "The CallerArgumentExpression on this parameter will have no effect because it's self-referential.")
         
     [<FactForNETCOREAPP>]
diff --git a/tests/fsharpqa/Source/Conformance/SpecialAttributesAndTypes/Imported/CallerInfo/E_CallerFilePath.fs b/tests/fsharpqa/Source/Conformance/SpecialAttributesAndTypes/Imported/CallerInfo/E_CallerFilePath.fs
index d6e160d39af..05277194dae 100644
--- a/tests/fsharpqa/Source/Conformance/SpecialAttributesAndTypes/Imported/CallerInfo/E_CallerFilePath.fs
+++ b/tests/fsharpqa/Source/Conformance/SpecialAttributesAndTypes/Imported/CallerInfo/E_CallerFilePath.fs
@@ -1,6 +1,6 @@
-//<Expects id="FS1246" span="(9,19-9,45)" status="error">'CallerFilePath' must be applied to an argument of type 'string', but has been applied to an argument of type 'int'</Expects>
-//<Expects id="FS1247" span="(12,19-12,47)" status="error">'CallerFilePath' can only be applied to optional arguments</Expects>
-//<Expects id="FS1247" span="(15,19-15,47)" status="error">'CallerFilePath' can only be applied to optional arguments</Expects>
+//<Expects id="FS1246" span="(9,66-9,70)" status="error">'CallerFilePath' must be applied to an argument of type 'string', but has been applied to an argument of type 'int'</Expects>
+//<Expects id="FS1247" span="(12,67-12,71)" status="error">'CallerFilePath' can only be applied to optional arguments</Expects>
+//<Expects id="FS1247" span="(15,67-15,71)" status="error">'CallerFilePath' can only be applied to optional arguments</Expects>
 namespace Test
 
 open System.Runtime.CompilerServices
diff --git a/tests/fsharpqa/Source/Conformance/SpecialAttributesAndTypes/Imported/CallerInfo/E_CallerLineNumber.fs b/tests/fsharpqa/Source/Conformance/SpecialAttributesAndTypes/Imported/CallerInfo/E_CallerLineNumber.fs
index 1d66da69961..0ea6504f070 100644
--- a/tests/fsharpqa/Source/Conformance/SpecialAttributesAndTypes/Imported/CallerInfo/E_CallerLineNumber.fs
+++ b/tests/fsharpqa/Source/Conformance/SpecialAttributesAndTypes/Imported/CallerInfo/E_CallerLineNumber.fs
@@ -1,6 +1,6 @@
-//<Expects id="FS1246" span="(9,19-9,44)" status="error">'CallerLineNumber' must be applied to an argument of type 'int', but has been applied to an argument of type 'string'</Expects>
-//<Expects id="FS1247" span="(12,19-12,49)" status="error">'CallerLineNumber' can only be applied to optional arguments</Expects>
-//<Expects id="FS1247" span="(15,19-15,49)" status="error">'CallerLineNumber' can only be applied to optional arguments</Expects>
+//<Expects id="FS1246" span="(9,67-9,71)" status="error">'CallerLineNumber' must be applied to an argument of type 'int', but has been applied to an argument of type 'string'</Expects>
+//<Expects id="FS1247" span="(12,71-12,75)" status="error">'CallerLineNumber' can only be applied to optional arguments</Expects>
+//<Expects id="FS1247" span="(15,71-15,75)" status="error">'CallerLineNumber' can only be applied to optional arguments</Expects>
 namespace Test
 
 open System.Runtime.CompilerServices
diff --git a/tests/fsharpqa/Source/Conformance/SpecialAttributesAndTypes/Imported/CallerInfo/E_CallerMemberName.fs b/tests/fsharpqa/Source/Conformance/SpecialAttributesAndTypes/Imported/CallerInfo/E_CallerMemberName.fs
index 9749e1e1508..c25f4bbd229 100644
--- a/tests/fsharpqa/Source/Conformance/SpecialAttributesAndTypes/Imported/CallerInfo/E_CallerMemberName.fs
+++ b/tests/fsharpqa/Source/Conformance/SpecialAttributesAndTypes/Imported/CallerInfo/E_CallerMemberName.fs
@@ -1,6 +1,6 @@
-//<Expects id="FS1246" span="(9,19-9,47)" status="error">'CallerMemberName' must be applied to an argument of type 'string', but has been applied to an argument of type 'int'</Expects>
-//<Expects id="FS1247" span="(12,19-12,49)" status="error">'CallerMemberName' can only be applied to optional arguments</Expects>
-//<Expects id="FS1247" span="(15,19-15,49)" status="error">'CallerMemberName' can only be applied to optional arguments</Expects>
+//<Expects id="FS1246" span="(9,70-9,74)" status="error">'CallerMemberName' must be applied to an argument of type 'string', but has been applied to an argument of type 'int'</Expects>
+//<Expects id="FS1247" span="(12,71-12,75)" status="error">'CallerMemberName' can only be applied to optional arguments</Expects>
+//<Expects id="FS1247" span="(15,71-15,75)" status="error">'CallerMemberName' can only be applied to optional arguments</Expects>
 namespace Test
 
 open System.Runtime.CompilerServices
diff --git a/tests/fsharpqa/Source/Conformance/SpecialAttributesAndTypes/Imported/CallerInfo/E_MultipleAttrs.fs b/tests/fsharpqa/Source/Conformance/SpecialAttributesAndTypes/Imported/CallerInfo/E_MultipleAttrs.fs
index fda49ca239f..96bd7ee575f 100644
--- a/tests/fsharpqa/Source/Conformance/SpecialAttributesAndTypes/Imported/CallerInfo/E_MultipleAttrs.fs
+++ b/tests/fsharpqa/Source/Conformance/SpecialAttributesAndTypes/Imported/CallerInfo/E_MultipleAttrs.fs
@@ -1,7 +1,7 @@
-//<Expects id="FS1246" span="(11,19-11,20)" status="error">'CallerFilePath' must be applied to an argument of type 'string', but has been applied to an argument of type 'int'</Expects>
-//<Expects id="FS1246" span="(14,19-14,20)" status="error">'CallerFilePath' must be applied to an argument of type 'string', but has been applied to an argument of type 'int'</Expects>
-//<Expects id="FS1246" span="(17,19-17,20)" status="error">'CallerLineNumber' must be applied to an argument of type 'int', but has been applied to an argument of type 'string'</Expects>
-//<Expects id="FS1246" span="(20,19-20,20)" status="error">'CallerLineNumber' must be applied to an argument of type 'int', but has been applied to an argument of type 'string'</Expects>
+//<Expects id="FS1246" span="(11,62-11,63)" status="error">'CallerFilePath' must be applied to an argument of type 'string', but has been applied to an argument of type 'int'</Expects>
+//<Expects id="FS1246" span="(14,62-14,63)" status="error">'CallerFilePath' must be applied to an argument of type 'string', but has been applied to an argument of type 'int'</Expects>
+//<Expects id="FS1246" span="(17,62-17,63)" status="error">'CallerLineNumber' must be applied to an argument of type 'int', but has been applied to an argument of type 'string'</Expects>
+//<Expects id="FS1246" span="(20,62-20,63)" status="error">'CallerLineNumber' must be applied to an argument of type 'int', but has been applied to an argument of type 'string'</Expects>
 
 namespace Test
 

From 983f180d98b4fc1d916519dbf656f69857560d45 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Fri, 14 Mar 2025 01:28:22 +0800
Subject: [PATCH 34/57] baseline

---
 .../ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl  | 2 +-
 .../ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl   | 2 +-
 .../ilverify_FSharp.Compiler.Service_Release_net9.0.bsl         | 2 +-
 .../ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl
index c186d50cdcd..eee60b473b5 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl
@@ -60,7 +60,7 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x0000000B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x00000021][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000CD][found Char] Unexpected type on the stack.
-[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@591::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@587::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000037][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000043][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack.
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl
index 7e1976ee6db..94da97ffef1 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl
@@ -86,7 +86,7 @@
 [IL]: Error [StackUnexpected]: : Internal.Utilities.FSharpEnvironment+probePathForDotnetHost@322::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000028][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.SimulatedMSBuildReferenceResolver+Pipe #6 input at line 68@68::FSharp.Compiler.CodeAnalysis.ILegacyReferenceResolver.Resolve([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyResolutionEnvironment, [S.P.CoreLib]System.Tuple`2<string,string>[], string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>, string, string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>, string, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.Unit>, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<bool,Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.Unit>>>)][offset 0x0000034D][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000CD][found Char] Unexpected type on the stack.
-[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@591::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@587::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000037][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000043][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack.
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl
index dbff4c2f01f..5e704c774b1 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl
@@ -86,7 +86,7 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x0000000B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x00000021][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000B6][found Char] Unexpected type on the stack.
-[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@591::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@587::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000035][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000041][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack.
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl
index c8ea20d4186..2f4fbf1cd2d 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl
@@ -113,7 +113,7 @@
 [IL]: Error [StackUnexpected]: : Internal.Utilities.FSharpEnvironment::probePathForDotnetHost@321([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x0000002A][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.SimulatedMSBuildReferenceResolver+SimulatedMSBuildResolver@68::FSharp.Compiler.CodeAnalysis.ILegacyReferenceResolver.Resolve([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyResolutionEnvironment, [S.P.CoreLib]System.Tuple`2<string,string>[], string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>, string, string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>, string, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.Unit>, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<bool,Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.Unit>>>)][offset 0x000002F5][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000B6][found Char] Unexpected type on the stack.
-[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@591::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@587::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000035][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000041][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack.

From cf2085bb2ff59e4d35af3f8be0055b8215684dbd Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Fri, 14 Mar 2025 09:09:20 +0800
Subject: [PATCH 35/57] fix test

---
 src/Compiler/SyntaxTree/ParseHelpers.fs              | 12 +++++++++---
 src/Compiler/Utilities/range.fs                      |  3 +++
 ...ler.Service.SurfaceArea.netstandard20.release.bsl |  1 -
 3 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/src/Compiler/SyntaxTree/ParseHelpers.fs b/src/Compiler/SyntaxTree/ParseHelpers.fs
index 7169b4d2234..aa4e7bfd96b 100644
--- a/src/Compiler/SyntaxTree/ParseHelpers.fs
+++ b/src/Compiler/SyntaxTree/ParseHelpers.fs
@@ -52,9 +52,15 @@ let mkSynRange (p1: Position) (p2: Position) =
             // This means we had a #line directive in the middle of this syntax element.
             mkFileIndexRange p1.FileIndex (posOfLexPosition p1) (posOfLexPosition (p1.ShiftColumnBy 1))
 
-    // Check if the start position is affected by a #line directive
-    if p1.OriginalFileIndex <> p1.FileIndex || p1.OriginalLine <> p1.Line then
-        mkFileIndexRange (p1.OriginalFileIndex) (posOfLexOriginalPosition p1) (posOfLexOriginalPosition p2)
+    // Check if the start or end position is affected by a #line directive
+    if
+        p1.FileIndex <> p2.FileIndex
+        || p1.OriginalFileIndex <> p1.FileIndex
+        || p1.OriginalLine <> p1.Line
+        || p2.OriginalFileIndex <> p2.FileIndex
+        || p2.OriginalLine <> p2.Line
+    then
+        mkFileIndexRange p1.OriginalFileIndex (posOfLexOriginalPosition p1) (posOfLexOriginalPosition p2)
         |> ValueSome
         |> range.WithOriginalRange
     else
diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs
index a156568dcdd..a62e684f244 100755
--- a/src/Compiler/Utilities/range.fs
+++ b/src/Compiler/Utilities/range.fs
@@ -522,6 +522,9 @@ module Range =
 
             let originalRange =
                 match m1.OriginalRange, m2.OriginalRange with
+                // #line is inside the syntax block
+                | ValueNone, ValueSome r2 when m1.FileIndex = r2.FileIndex -> 
+                    ValueSome(range(m1.FileIndex, m1.StartLine, m1.StartColumn, r2.EndLine, r2.EndColumn))
                 | ValueSome r1, ValueSome r2 when r1.FileIndex = r2.FileIndex ->
                     ValueSome(range (r1.FileIndex, r1.StartLine, r1.StartColumn, r2.EndLine, r2.EndColumn))
                 | _ -> ValueNone
diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl
index 34453a351ca..16ee08ccf59 100644
--- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl
+++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl
@@ -10928,7 +10928,6 @@ FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range get_range0()
 FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range get_rangeCmdArgs()
 FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range get_rangeStartup()
 FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range mkFileIndexRange(Int32, FSharp.Compiler.Text.Position, FSharp.Compiler.Text.Position)
-FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range mkFileIndexRangeWithOriginRange(Int32, FSharp.Compiler.Text.Position, FSharp.Compiler.Text.Position, Int32, FSharp.Compiler.Text.Position, FSharp.Compiler.Text.Position)
 FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range mkFirstLineOfFile(System.String)
 FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range mkRange(System.String, FSharp.Compiler.Text.Position, FSharp.Compiler.Text.Position)
 FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range range0

From 52a4d53326862c5c4c969cded51a3d208c8e3733 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Fri, 14 Mar 2025 09:14:22 +0800
Subject: [PATCH 36/57] fmt

---
 src/Compiler/Utilities/range.fs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs
index a62e684f244..c081c1157bc 100755
--- a/src/Compiler/Utilities/range.fs
+++ b/src/Compiler/Utilities/range.fs
@@ -523,8 +523,8 @@ module Range =
             let originalRange =
                 match m1.OriginalRange, m2.OriginalRange with
                 // #line is inside the syntax block
-                | ValueNone, ValueSome r2 when m1.FileIndex = r2.FileIndex -> 
-                    ValueSome(range(m1.FileIndex, m1.StartLine, m1.StartColumn, r2.EndLine, r2.EndColumn))
+                | ValueNone, ValueSome r2 when m1.FileIndex = r2.FileIndex ->
+                    ValueSome(range (m1.FileIndex, m1.StartLine, m1.StartColumn, r2.EndLine, r2.EndColumn))
                 | ValueSome r1, ValueSome r2 when r1.FileIndex = r2.FileIndex ->
                     ValueSome(range (r1.FileIndex, r1.StartLine, r1.StartColumn, r2.EndLine, r2.EndColumn))
                 | _ -> ValueNone

From 6e6dd39de4e800442e1c6cf8c5e0e760177ce4bb Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Sat, 15 Mar 2025 13:04:17 +0800
Subject: [PATCH 37/57] Support for user defined
 CallerArgumentExpressionAttribute

---
 src/Compiler/Checking/infos.fs | 34 +++++++++++++++++++++-------------
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/src/Compiler/Checking/infos.fs b/src/Compiler/Checking/infos.fs
index a52622b9539..07735f72260 100644
--- a/src/Compiler/Checking/infos.fs
+++ b/src/Compiler/Checking/infos.fs
@@ -318,7 +318,18 @@ let CrackParamAttribsInfo g (ty: TType, argInfo: ArgReprInfo) =
     let isCallerLineNumberArg = HasFSharpAttribute g g.attrib_CallerLineNumberAttribute argInfo.Attribs
     let isCallerFilePathArg = HasFSharpAttribute g g.attrib_CallerFilePathAttribute argInfo.Attribs
     let isCallerMemberNameArg = HasFSharpAttribute g g.attrib_CallerMemberNameAttribute argInfo.Attribs
-    let callerArgumentExpressionArg = TryFindFSharpAttributeOpt g g.attrib_CallerArgumentExpressionAttribute argInfo.Attribs
+    let callerArgumentExpressionArg = 
+        TryFindFSharpAttributeOpt g g.attrib_CallerArgumentExpressionAttribute argInfo.Attribs
+        // find user defined CallerArgumentExpressionAttribute
+        |> Option.orElseWith (fun () -> 
+            argInfo.Attribs
+            |> List.tryFind (fun (Attrib(tcref2, _, _, _, _, _, _)) -> 
+                match tcref2.TryDeref with
+                | ValueNone -> false
+                | ValueSome x ->
+                    x.CompilationPath.MangledPath = ["System"; "Runtime"; "CompilerServices"] && 
+                    x.CompiledName = "CallerArgumentExpressionAttribute")
+        )
 
     let callerInfo =
         match isCallerLineNumberArg, isCallerFilePathArg, isCallerMemberNameArg, callerArgumentExpressionArg with
@@ -1284,21 +1295,18 @@ type MethInfo =
                  let isCallerLineNumberArg = TryFindILAttribute g.attrib_CallerLineNumberAttribute attrs
                  let isCallerFilePathArg = TryFindILAttribute g.attrib_CallerFilePathAttribute attrs
                  let isCallerMemberNameArg = TryFindILAttribute g.attrib_CallerMemberNameAttribute attrs
-                 let isCallerArgumentExpressionArg = TryFindILAttributeOpt g.attrib_CallerArgumentExpressionAttribute attrs
+                 let isCallerArgumentExpressionArg =
+                     g.attrib_CallerArgumentExpressionAttribute
+                     |> Option.bind (fun (AttribInfo(tref, _)) -> TryDecodeILAttribute tref attrs)
 
                  let callerInfo =
                     match isCallerLineNumberArg, isCallerFilePathArg, isCallerMemberNameArg, isCallerArgumentExpressionArg with
-                    | false, false, false, false -> NoCallerInfo
-                    | true, false, false, false -> CallerLineNumber
-                    | false, true, false, false -> CallerFilePath
-                    | false, false, true, false -> CallerMemberName            
-                    | false, false, false, true ->
-                        match g.attrib_CallerArgumentExpressionAttribute with
-                        | Some (AttribInfo(tref,_)) ->
-                            match TryDecodeILAttribute tref attrs with
-                            | Some ([ILAttribElem.String (Some name) ], _) -> CallerArgumentExpression(name)
-                            | _ -> NoCallerInfo
-                        | None -> NoCallerInfo
+                    | false, false, false, None -> NoCallerInfo
+                    | true, false, false, None -> CallerLineNumber
+                    | false, true, false, None -> CallerFilePath
+                    | false, false, true, None -> CallerMemberName            
+                    | false, false, false, Some ([ILAttribElem.String (Some name) ], _) -> CallerArgumentExpression(name)
+                    | false, false, false, _ -> NoCallerInfo
                     | _, _, _, _ ->
                         // if multiple caller info attributes are specified, pick the "wrong" one here
                         // so that we get an error later

From 9c5d9178a191c40aa6194eeb7915f6e91401127f Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Sat, 15 Mar 2025 13:04:53 +0800
Subject: [PATCH 38/57] replace the way get substring text

---
 src/Compiler/Interactive/fsi.fs               | 32 +++++++-
 src/Compiler/Utilities/range.fs               | 75 ++++++++++++-------
 src/Compiler/Utilities/range.fsi              |  8 +-
 .../CompilerDirectives/Line.fs                |  4 +-
 4 files changed, 84 insertions(+), 35 deletions(-)

diff --git a/src/Compiler/Interactive/fsi.fs b/src/Compiler/Interactive/fsi.fs
index ad51c9cd597..24997e5b066 100644
--- a/src/Compiler/Interactive/fsi.fs
+++ b/src/Compiler/Interactive/fsi.fs
@@ -4684,11 +4684,35 @@ type FsiEvaluationSession
     do
         FileContent.getLineDynamic <-
             { new FileContent.DefaultFileContentGetLine() with
-                override _.GetLine(fileName: string, line: int) : string =
-                    if fileName = stdinMockFileName then
-                        fsiStdinSyphon.GetLineNoPrune fileName line
+                override _.GetRangeText(range) : string =
+                    if range.FileName = stdinMockFileName then
+                        if range.StartLine = range.EndLine then
+                            let line = fsiStdinSyphon.GetLineNoPrune stdinMockFileName range.StartLine
+                            let start = min range.StartColumn (line.Length - 1)
+                            line.[start .. range.EndColumn - 1]
+                        else
+                            let result = StringBuilder()
+
+                            for i in range.StartLine .. range.EndLine do
+                                let line = (fsiStdinSyphon.GetLineNoPrune stdinMockFileName i).AsSpan()
+
+                                let line =
+                                    if i = range.StartLine then
+                                        let start = min range.StartColumn (line.Length - 1)
+                                        line.Slice(start)
+                                    elif i = range.EndLine then
+                                        let len = min range.EndColumn line.Length
+                                        line.Slice(0, len)
+                                    else
+                                        line
+
+                                result.Append(line) |> ignore
+                                if i = range.EndLine then
+                                    result.Append(Environment.NewLine) |> ignore
+
+                            result.ToString()
                     else
-                        base.GetLine(fileName, line)
+                        base.GetRangeText(range)
             }
 
     let fsiConsoleInput = FsiConsoleInput(fsi, fsiOptions, inReader, outWriter)
diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs
index c081c1157bc..ab521303241 100755
--- a/src/Compiler/Utilities/range.fs
+++ b/src/Compiler/Utilities/range.fs
@@ -615,46 +615,71 @@ module Range =
             mkRange file (mkPos 1 0) (mkPos 1 80)
 
 module internal FileContent =
-    let private fileContentDict = ConcurrentDictionary<string, string array>()
+    let private fileContentDict = ConcurrentDictionary<string, string>()
 
     let readFileContents (fileNames: string list) =
         for fileName in fileNames do
             if FileSystem.FileExistsShim fileName then
                 use fileStream = FileSystem.OpenFileForReadShim(fileName)
-                fileContentDict[fileName] <- fileStream.ReadAllLines()
+                fileContentDict[fileName] <- fileStream.ReadAllText()
+
+    let substring (input: string) (startLine, startCol) (endLine, endCol) =
+        let findLineEnd lineStart =
+            if lineStart >= input.Length then
+                input.Length - 1
+            else
+                let idx = input.IndexOfAny([| '\r'; '\n' |], lineStart)
+
+                if idx = -1 then
+                    input.Length - 1
+                elif input.[idx] = '\r' && idx + 1 < input.Length && input.[idx + 1] = '\n' then
+                    idx + 1
+                else
+                    idx
+
+        if startLine < 1 || startLine > endLine || startCol < 0 || endCol < 0 then
+            ""
+        else
+            let result = System.Text.StringBuilder()
+
+            let rec loop lineCount startIndex endIndex =
+                if lineCount > endLine then
+                    result.ToString()
+                elif lineCount < startLine then
+                    loop (lineCount + 1) (endIndex + 1) (findLineEnd (endIndex + 1))
+                elif lineCount = startLine && startLine = endLine then
+                    input.[startCol..endCol]
+                elif lineCount = startLine then
+                    if startCol < endIndex - startIndex + 1 then
+                        result.Append(input.AsSpan(startIndex + startCol, endIndex - startIndex + 1 - startCol))
+                        |> ignore
+
+                    loop (lineCount + 1) (endIndex + 1) (findLineEnd (endIndex + 1))
+                elif lineCount = endLine then
+                    let len = min endCol (endIndex - startIndex + 1)
+                    result.Append(input.AsSpan(startIndex, len)).ToString()
+                else
+                    result.Append(input.AsSpan(startIndex, endIndex - startIndex + 1)) |> ignore
+                    loop (lineCount + 1) (endIndex + 1) (findLineEnd (endIndex + 1))
+
+            loop 1 0 (findLineEnd 0)
 
     type IFileContentGetLine =
-        abstract GetLine: fileName: string * line: int -> string
+        abstract GetRangeText: range: range -> string
 
     type DefaultFileContentGetLine() =
+        abstract GetRangeText: range: range -> string
 
-        abstract GetLine: fileName: string * line: int -> string
-
-        default _.GetLine(fileName: string, line: int) : string =
-            match fileContentDict.TryGetValue fileName with
-            | true, lines when lines.Length >= line && line > 0 -> lines[line - 1]
+        default _.GetRangeText(range: range) : string =
+            match fileContentDict.TryGetValue range.FileName with
+            | true, text -> substring text (range.StartLine, range.StartColumn) (range.EndLine, range.EndColumn)
             | _ -> String.Empty
 
         interface IFileContentGetLine with
-            member this.GetLine(fileName: string, line: int) : string = this.GetLine(fileName, line)
+            member this.GetRangeText(range: range) : string = this.GetRangeText(range)
 
     let mutable getLineDynamic = DefaultFileContentGetLine() :> IFileContentGetLine
 
     let getCodeText (m: range) =
         let m = if m.HasOriginalRange then m.OriginalRange.Value else m
-
-        let filename, startLine, endLine = m.FileName, m.StartLine, m.EndLine
-        let endCol = m.EndColumn - 1
-        let startCol = m.StartColumn - 1
-
-        let s =
-            [| for i in startLine..endLine -> getLineDynamic.GetLine(filename, i) |]
-            |> String.concat "\n"
-
-        if String.IsNullOrEmpty s then
-            s
-        else
-            try
-                s.Substring(startCol + 1, s.LastIndexOf("\n", StringComparison.Ordinal) + 1 - startCol + endCol)
-            with ex ->
-                raise (System.AggregateException($"ex: {ex}; (s: {s}, startCol: {startCol}, endCol: {endCol})", ex))
+        getLineDynamic.GetRangeText(m)
diff --git a/src/Compiler/Utilities/range.fsi b/src/Compiler/Utilities/range.fsi
index ee425d77cc8..5487905c9d4 100755
--- a/src/Compiler/Utilities/range.fsi
+++ b/src/Compiler/Utilities/range.fsi
@@ -279,18 +279,18 @@ module Line =
 /// Store code file content. Use to implement `CallerArgumentExpression`
 module internal FileContent =
 
-    /// Read all file contents
+    /// Read all file contents.
     ///
     /// Used by `getCodeText` to support `CallerArgumentExpression`
     val readFileContents: fileNames: string list -> unit
 
     type IFileContentGetLine =
-        abstract GetLine: fileName: string * line: int -> string
+        abstract GetRangeText: range: range -> string
         
     type DefaultFileContentGetLine =
         new: unit -> DefaultFileContentGetLine
-        abstract GetLine: fileName: string * line: int -> string
-        override GetLine: fileName: string * line: int -> string
+        abstract GetRangeText: range: range -> string
+        override GetRangeText: range: range -> string
         interface IFileContentGetLine
 
     /// Get a line string from already read files.
diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Line.fs b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Line.fs
index 161a1c45211..226f2a2b0fb 100644
--- a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Line.fs
+++ b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Line.fs
@@ -52,8 +52,8 @@ printfn ""
 
     [<Theory>]
     [<InlineData(1, case1, "xyz.fs:(1,0--3,1) (from: (3,0--5,1))")>]
-    [<InlineData(2, case2, "Line.fs:(2,0--2,1)")>]
-    [<InlineData(3, case3, "Line.fs:(2,0--2,1)")>]
+    [<InlineData(2, case2, "Line.fs:(2,0--2,1) (from: (2,0--5,1)")>]
+    [<InlineData(3, case3, "Line.fs:(2,0--2,1) (from: (2,0--4,1))")>]
     let ``check expr range interacting with line directive`` (case, source, expectedRange) =
         let parseResults = parse source
         if parseResults.ParseHadErrors then failwith "unexpected: parse error"

From 795c64a3447cc7903b28e834391912083dcded15 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Sat, 15 Mar 2025 13:05:12 +0800
Subject: [PATCH 39/57] test

---
 .../CallerArgumentExpression.fs               | 102 +++++++++++-------
 1 file changed, 63 insertions(+), 39 deletions(-)

diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
index eb44abe4ce5..f0dec9bc4c8 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
@@ -31,7 +31,7 @@ with :? System.ArgumentException as ex ->
         |> ignore
 
     [<FactForNETCOREAPP>]
-    let ``Can define in F#`` () =
+    let ``Can define methods using CallerArgumentExpression in F#`` () =
         FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
 open System.Runtime.CompilerServices
 open System.Runtime.InteropServices
@@ -54,7 +54,7 @@ assertEqual (A.aa(a = stringABC)) ("abc", ".cctor", 14, "stringABC")
         |> ignore
 
     [<FactForNETCOREAPP>]
-    let ``Can define in F# with F#-style optional arguments`` () =
+    let ``Can define methods using CallerArgumentExpression F# with F#-style optional arguments`` () =
         FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
 open System.Runtime.CompilerServices
 open System.Runtime.InteropServices
@@ -111,7 +111,7 @@ assertEqual (A.aa(a = (stringABC : string))) ("abc", ".cctor", 1, System.IO.Path
         |> ignore
 
     [<FactForNETCOREAPP>]
-    let ``Can receive special parameter names`` () =
+    let ``Can define methods using CallerArgumentExpression receiving special parameter names`` () =
       FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
 open System.Runtime.CompilerServices
 
@@ -150,6 +150,14 @@ A.B((+) 1
 |> assertEqual "(+) 1
 #line 1
         123"
+        
+
+A.B(#line 1
+  (+) 1
+        123)
+|> assertEqual "(+) 1
+        123"
+        
         """
         |> withLangVersionPreview
         |> asExe
@@ -158,56 +166,33 @@ A.B((+) 1
         |> ignore
         
     [<FactForNETCOREAPP>]
-    let ``Warn when cannot find the referenced parameter`` () =
-      FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
-open System.Runtime.CompilerServices
-
-type A() =
-  static member B (``ab c``, [<CallerArgumentExpression "abc">]?n) =
-    defaultArg n "no value"
-        """
-        |> withLangVersionPreview
-        |> typecheck
-        |> shouldFail
-        |> withSingleDiagnostic (Warning 3875,Line 5, Col 65, Line 5, Col 66, "The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name.")
-        
-    [<FactForNETCOREAPP>]
-    let ``Warn when self referenced`` () =
+    let ``test Warns when cannot find the referenced parameter`` () =
       FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
 open System.Runtime.CompilerServices
 
 type A() =
-  static member B (``ab c``, [<CallerArgumentExpression "n">]?n) =
+  static member A (``ab c``, [<CallerArgumentExpression "abc">]?n) =
     defaultArg n "no value"
-    
-assertEqual (A.B("abc")) "no value"
-        """
-        |> withLangVersionPreview
-        |> typecheck
-        |> shouldFail
-        |> withSingleDiagnostic (Warning 3875,Line 5, Col 63 , Line 5, Col 64, "The CallerArgumentExpression on this parameter will have no effect because it's self-referential.")
-        
-    [<FactForNETCOREAPP>]
-    let ``Error when not attached to optional parameters`` () =
-      FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
-open System.Runtime.CompilerServices
-
-type A() =
-  static member B (``ab c``, [<CallerArgumentExpression "ab c">] n) =
+  static member B (``ab c``, [<CallerArgumentExpression "n">]  ?n) =
     defaultArg n "no value"
         """
         |> withLangVersionPreview
         |> typecheck
         |> shouldFail
-        |> withSingleDiagnostic (Error 1247,Line 5, Col 66, Line 5, Col 67, "'CallerArgumentExpression \"ab c\"' can only be applied to optional arguments")
+        |> withDiagnostics [
+          (Warning 3875,Line 5, Col 65, Line 5, Col 66, "The CallerArgumentExpression on this parameter will have no effect because it's applied with an invalid parameter name.")
+          (Warning 3875,Line 7, Col 65 , Line 7, Col 66, "The CallerArgumentExpression on this parameter will have no effect because it's self-referential.")
+        ]
 
     [<FactForNETCOREAPP>]
-    let ``Error when parameters type not matched`` () =
+    let ``test Errors`` () =
       FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
 open System.Runtime.CompilerServices
 open System.Runtime.InteropServices
 
 type A() =
+  static member A (``ab c``, [<CallerArgumentExpression "ab c">] n) =
+    defaultArg n "no value"
   static member B (``ab c``, [<CallerArgumentExpression "ab c">]?n) =
     defaultArg n 123
   static member C (``ab c``, [<CallerArgumentExpression "ab c"; Optional; DefaultParameterValue 0>] n: int) =
@@ -217,6 +202,45 @@ type A() =
         |> typecheck
         |> shouldFail
         |> withDiagnostics [
-          (Error 1246,Line 6, Col 66, Line 6, Col 67, "'CallerArgumentExpression \"ab c\"' must be applied to an argument of type 'string', but has been applied to an argument of type 'int'")
-          (Error 1246,Line 8, Col 101, Line 8, Col 102, "'CallerArgumentExpression \"ab c\"' must be applied to an argument of type 'string', but has been applied to an argument of type 'int'")
-        ]
\ No newline at end of file
+          (Error 1247,Line 6, Col 66, Line 6, Col 67, "'CallerArgumentExpression \"ab c\"' can only be applied to optional arguments")
+          (Error 1246,Line 8, Col 66, Line 8, Col 67, "'CallerArgumentExpression \"ab c\"' must be applied to an argument of type 'string', but has been applied to an argument of type 'int'")
+          (Error 1246,Line 10, Col 101, Line 10, Col 102, "'CallerArgumentExpression \"ab c\"' must be applied to an argument of type 'string', but has been applied to an argument of type 'int'")
+        ]
+        
+    [<Fact>]
+    let ``Can self define CallerArgumentExpression`` () =
+      FSharp """namespace System.Runtime.CompilerServices
+
+open System
+
+[<AttributeUsage(AttributeTargets.Parameter, AllowMultiple=false, Inherited=false)>]
+type CallerArgumentExpressionAttribute(parameterName: string) =
+  inherit Attribute()
+
+  member val ParameterName = parameterName
+  
+namespace global
+module A =
+  let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
+  open System.Runtime.CompilerServices
+
+  type A() =
+    static member B (``ab c``, [<CallerArgumentExpression "ab c">]?n) =
+      defaultArg n "no value"
+      
+  A.B("abc"
+#line 1
+  : string)
+  |> assertEqual "\"abc\"
+#line 1
+  : string"
+  
+  A.B "abc" |> assertEqual "\"abc\""  
+  A.B ("abc": string) |> assertEqual "\"abc\": string"
+"""
+        |> withLangVersionPreview
+        |> asExe
+        |> compileAndRun
+        |> shouldSucceed
+        |> ignore
+        
\ No newline at end of file

From 98d8708a9d77870640c3b0bfc497cc6d555f8c77 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Sat, 15 Mar 2025 16:11:21 +0800
Subject: [PATCH 40/57] fix build remove
 `StringBuilder.Append(ReadOnlySpan<Char>)`

---
 src/Compiler/Interactive/fsi.fs | 3 ++-
 src/Compiler/Utilities/range.fs | 6 +++---
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/Compiler/Interactive/fsi.fs b/src/Compiler/Interactive/fsi.fs
index 24997e5b066..85667152cb9 100644
--- a/src/Compiler/Interactive/fsi.fs
+++ b/src/Compiler/Interactive/fsi.fs
@@ -4706,7 +4706,8 @@ type FsiEvaluationSession
                                     else
                                         line
 
-                                result.Append(line) |> ignore
+                                result.Append(line.ToString()) |> ignore
+
                                 if i = range.EndLine then
                                     result.Append(Environment.NewLine) |> ignore
 
diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs
index ab521303241..b3267622b97 100755
--- a/src/Compiler/Utilities/range.fs
+++ b/src/Compiler/Utilities/range.fs
@@ -651,15 +651,15 @@ module internal FileContent =
                     input.[startCol..endCol]
                 elif lineCount = startLine then
                     if startCol < endIndex - startIndex + 1 then
-                        result.Append(input.AsSpan(startIndex + startCol, endIndex - startIndex + 1 - startCol))
+                        result.Append(input.Substring(startIndex + startCol, endIndex - startIndex + 1 - startCol))
                         |> ignore
 
                     loop (lineCount + 1) (endIndex + 1) (findLineEnd (endIndex + 1))
                 elif lineCount = endLine then
                     let len = min endCol (endIndex - startIndex + 1)
-                    result.Append(input.AsSpan(startIndex, len)).ToString()
+                    result.Append(input.Substring(startIndex, len)).ToString()
                 else
-                    result.Append(input.AsSpan(startIndex, endIndex - startIndex + 1)) |> ignore
+                    result.Append(input.Substring(startIndex, endIndex - startIndex + 1)) |> ignore
                     loop (lineCount + 1) (endIndex + 1) (findLineEnd (endIndex + 1))
 
             loop 1 0 (findLineEnd 0)

From d68a6f703d60acc78d6360931a92fa22116ce3fd Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Sat, 15 Mar 2025 19:32:56 +0800
Subject: [PATCH 41/57] fix test

---
 src/Compiler/Checking/PostInferenceChecks.fs | 4 ++--
 src/Compiler/SyntaxTree/SyntaxTree.fs        | 4 +++-
 src/Compiler/Utilities/range.fs              | 2 +-
 3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/src/Compiler/Checking/PostInferenceChecks.fs b/src/Compiler/Checking/PostInferenceChecks.fs
index be701cd9d41..6c641a951a3 100644
--- a/src/Compiler/Checking/PostInferenceChecks.fs
+++ b/src/Compiler/Checking/PostInferenceChecks.fs
@@ -2442,11 +2442,11 @@ let CheckEntityDefn cenv env (tycon: Entity) =
                     | CallerSide _, (CallerFilePath | CallerMemberName) -> errorIfNotStringTy m ty callerInfo
                     | CalleeSide, (CallerFilePath | CallerMemberName) -> errorIfNotStringOptionTy m ty callerInfo
                     | CallerSide _, CallerArgumentExpression arg ->
-                        checkLanguageFeatureError g.langVersion LanguageFeature.SupportCallerArgumentExpression m
+                        checkLanguageFeatureAndRecover g.langVersion LanguageFeature.SupportCallerArgumentExpression m
                         errorIfNotStringTy m ty callerInfo
                         checkArgOfCallerArgumentExpression m arg nameOpt
                     | CalleeSide, CallerArgumentExpression arg ->
-                        checkLanguageFeatureError g.langVersion LanguageFeature.SupportCallerArgumentExpression m
+                        checkLanguageFeatureAndRecover g.langVersion LanguageFeature.SupportCallerArgumentExpression m
                         errorIfNotStringOptionTy m ty callerInfo
                         checkArgOfCallerArgumentExpression m arg nameOpt
                 )
diff --git a/src/Compiler/SyntaxTree/SyntaxTree.fs b/src/Compiler/SyntaxTree/SyntaxTree.fs
index bd918e8848a..72c96110949 100644
--- a/src/Compiler/SyntaxTree/SyntaxTree.fs
+++ b/src/Compiler/SyntaxTree/SyntaxTree.fs
@@ -777,7 +777,9 @@ type SynExpr =
         match e with
         | SynExpr.Paren(_, leftParenRange, rightParenRange, r) ->
             match rightParenRange with
-            | Some rightParenRange when leftParenRange.FileIndex <> rightParenRange.FileIndex -> leftParenRange
+            | Some rightParenRange when leftParenRange.FileIndex <> rightParenRange.FileIndex ->
+                if r.HasOriginalRange then r
+                else leftParenRange
             | _ -> r
         | SynExpr.Quote(range = m)
         | SynExpr.Const(range = m)
diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs
index b3267622b97..f3f8ff04465 100755
--- a/src/Compiler/Utilities/range.fs
+++ b/src/Compiler/Utilities/range.fs
@@ -648,7 +648,7 @@ module internal FileContent =
                 elif lineCount < startLine then
                     loop (lineCount + 1) (endIndex + 1) (findLineEnd (endIndex + 1))
                 elif lineCount = startLine && startLine = endLine then
-                    input.[startCol..endCol]
+                    input.[startIndex + startCol.. startIndex + endCol - 1]
                 elif lineCount = startLine then
                     if startCol < endIndex - startIndex + 1 then
                         result.Append(input.Substring(startIndex + startCol, endIndex - startIndex + 1 - startCol))

From 9ac37e6a07f23b0d13444b68b0298b63b2e7a9c2 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Sat, 15 Mar 2025 20:06:02 +0800
Subject: [PATCH 42/57] test

---
 tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Line.fs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Line.fs b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Line.fs
index 226f2a2b0fb..5d5cb49afa5 100644
--- a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Line.fs
+++ b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Line.fs
@@ -52,7 +52,7 @@ printfn ""
 
     [<Theory>]
     [<InlineData(1, case1, "xyz.fs:(1,0--3,1) (from: (3,0--5,1))")>]
-    [<InlineData(2, case2, "Line.fs:(2,0--2,1) (from: (2,0--5,1)")>]
+    [<InlineData(2, case2, "Line.fs:(2,0--2,1) (from: (2,0--5,1))")>]
     [<InlineData(3, case3, "Line.fs:(2,0--2,1) (from: (2,0--4,1))")>]
     let ``check expr range interacting with line directive`` (case, source, expectedRange) =
         let parseResults = parse source

From 262ed24bb676beb0f1eb6454d0c7064624b65832 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Mon, 17 Mar 2025 20:44:55 +0800
Subject: [PATCH 43/57] revert the modify to `range`

---
 src/Compiler/Facilities/prim-lexing.fs        | 16 +++----
 src/Compiler/Facilities/prim-lexing.fsi       |  2 -
 src/Compiler/SyntaxTree/ParseHelpers.fs       | 24 ++--------
 src/Compiler/SyntaxTree/SyntaxTree.fs         |  4 +-
 src/Compiler/Utilities/range.fs               | 44 +++----------------
 src/Compiler/Utilities/range.fsi              |  7 ---
 .../CompilerDirectives/Line.fs                |  6 +--
 7 files changed, 20 insertions(+), 83 deletions(-)

diff --git a/src/Compiler/Facilities/prim-lexing.fs b/src/Compiler/Facilities/prim-lexing.fs
index 55b72c7490f..c305052587c 100644
--- a/src/Compiler/Facilities/prim-lexing.fs
+++ b/src/Compiler/Facilities/prim-lexing.fs
@@ -210,17 +210,15 @@ open System.Collections.Generic
 [<Struct>]
 type internal Position =
     val FileIndex: int
-    val OriginalFileIndex: int
     val Line: int
     val OriginalLine: int
     val AbsoluteOffset: int
     val StartOfLineAbsoluteOffset: int
     member x.Column = x.AbsoluteOffset - x.StartOfLineAbsoluteOffset
 
-    new(fileIndex: int, originalFileIndex: int, line: int, originalLine: int, startOfLineAbsoluteOffset: int, absoluteOffset: int) =
+    new(fileIndex: int, line: int, originalLine: int, startOfLineAbsoluteOffset: int, absoluteOffset: int) =
         {
             FileIndex = fileIndex
-            OriginalFileIndex = originalFileIndex
             Line = line
             OriginalLine = originalLine
             AbsoluteOffset = absoluteOffset
@@ -228,25 +226,25 @@ type internal Position =
         }
 
     member x.NextLine =
-        Position(x.FileIndex, x.OriginalFileIndex, x.Line + 1, x.OriginalLine + 1, x.AbsoluteOffset, x.AbsoluteOffset)
+        Position(x.FileIndex, x.Line + 1, x.OriginalLine + 1, x.AbsoluteOffset, x.AbsoluteOffset)
 
     member x.EndOfToken n =
-        Position(x.FileIndex, x.OriginalFileIndex, x.Line, x.OriginalLine, x.StartOfLineAbsoluteOffset, x.AbsoluteOffset + n)
+        Position(x.FileIndex, x.Line, x.OriginalLine, x.StartOfLineAbsoluteOffset, x.AbsoluteOffset + n)
 
     member x.ShiftColumnBy by =
-        Position(x.FileIndex, x.OriginalFileIndex, x.Line, x.OriginalLine, x.StartOfLineAbsoluteOffset, x.AbsoluteOffset + by)
+        Position(x.FileIndex, x.Line, x.OriginalLine, x.StartOfLineAbsoluteOffset, x.AbsoluteOffset + by)
 
     member x.ColumnMinusOne =
-        Position(x.FileIndex, x.OriginalFileIndex, x.Line, x.OriginalLine, x.StartOfLineAbsoluteOffset, x.StartOfLineAbsoluteOffset - 1)
+        Position(x.FileIndex, x.Line, x.OriginalLine, x.StartOfLineAbsoluteOffset, x.StartOfLineAbsoluteOffset - 1)
 
     member x.ApplyLineDirective(fileIdx, line) =
-        Position(fileIdx, x.OriginalFileIndex, line, x.OriginalLine + 1, x.AbsoluteOffset, x.AbsoluteOffset)
+        Position(fileIdx, line, x.OriginalLine + 1, x.AbsoluteOffset, x.AbsoluteOffset)
 
     override p.ToString() = $"({p.Line},{p.Column})"
 
     static member Empty = Position()
 
-    static member FirstLine fileIdx = Position(fileIdx, fileIdx, 1, 1, 0, 0)
+    static member FirstLine fileIdx = Position(fileIdx, 1, 1, 0, 0)
 
 type internal LexBufferFiller<'Char> = LexBuffer<'Char> -> unit
 
diff --git a/src/Compiler/Facilities/prim-lexing.fsi b/src/Compiler/Facilities/prim-lexing.fsi
index b58c3e26ef7..ff13f96c9e1 100644
--- a/src/Compiler/Facilities/prim-lexing.fsi
+++ b/src/Compiler/Facilities/prim-lexing.fsi
@@ -72,8 +72,6 @@ type internal Position =
     /// The file index for the file associated with the input stream, use <c>fileOfFileIndex</c> to decode
     val FileIndex: int
 
-    val OriginalFileIndex: int
-
     /// The line number in the input stream, assuming fresh positions have been updated
     /// for the new line by modifying the EndPos property of the LexBuffer.
     val Line: int
diff --git a/src/Compiler/SyntaxTree/ParseHelpers.fs b/src/Compiler/SyntaxTree/ParseHelpers.fs
index aa4e7bfd96b..1c0428eb835 100644
--- a/src/Compiler/SyntaxTree/ParseHelpers.fs
+++ b/src/Compiler/SyntaxTree/ParseHelpers.fs
@@ -41,30 +41,14 @@ let warningStringOfPos (p: pos) = warningStringOfCoords p.Line p.Column
 
 /// Get an F# compiler position from a lexer position
 let posOfLexPosition (p: Position) = mkPos p.Line p.Column
-let posOfLexOriginalPosition (p: Position) = mkPos p.OriginalLine p.Column
 
 /// Get an F# compiler range from a lexer range
 let mkSynRange (p1: Position) (p2: Position) =
-    let range =
-        if p1.FileIndex = p2.FileIndex then
-            mkFileIndexRange p1.FileIndex (posOfLexPosition p1) (posOfLexPosition p2)
-        else
-            // This means we had a #line directive in the middle of this syntax element.
-            mkFileIndexRange p1.FileIndex (posOfLexPosition p1) (posOfLexPosition (p1.ShiftColumnBy 1))
-
-    // Check if the start or end position is affected by a #line directive
-    if
-        p1.FileIndex <> p2.FileIndex
-        || p1.OriginalFileIndex <> p1.FileIndex
-        || p1.OriginalLine <> p1.Line
-        || p2.OriginalFileIndex <> p2.FileIndex
-        || p2.OriginalLine <> p2.Line
-    then
-        mkFileIndexRange p1.OriginalFileIndex (posOfLexOriginalPosition p1) (posOfLexOriginalPosition p2)
-        |> ValueSome
-        |> range.WithOriginalRange
+    if p1.FileIndex = p2.FileIndex then
+        mkFileIndexRange p1.FileIndex (posOfLexPosition p1) (posOfLexPosition p2)
     else
-        range
+        // This means we had a #line directive in the middle of this syntax element.
+        mkFileIndexRange p1.FileIndex (posOfLexPosition p1) (posOfLexPosition (p1.ShiftColumnBy 1))
 
 type LexBuffer<'Char> with
 
diff --git a/src/Compiler/SyntaxTree/SyntaxTree.fs b/src/Compiler/SyntaxTree/SyntaxTree.fs
index 72c96110949..bd918e8848a 100644
--- a/src/Compiler/SyntaxTree/SyntaxTree.fs
+++ b/src/Compiler/SyntaxTree/SyntaxTree.fs
@@ -777,9 +777,7 @@ type SynExpr =
         match e with
         | SynExpr.Paren(_, leftParenRange, rightParenRange, r) ->
             match rightParenRange with
-            | Some rightParenRange when leftParenRange.FileIndex <> rightParenRange.FileIndex ->
-                if r.HasOriginalRange then r
-                else leftParenRange
+            | Some rightParenRange when leftParenRange.FileIndex <> rightParenRange.FileIndex -> leftParenRange
             | _ -> r
         | SynExpr.Quote(range = m)
         | SynExpr.Const(range = m)
diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs
index f3f8ff04465..b33608168a8 100755
--- a/src/Compiler/Utilities/range.fs
+++ b/src/Compiler/Utilities/range.fs
@@ -262,12 +262,10 @@ module FileIndex =
     let commandLineArgsFileName = "commandLineArgs"
 
 [<Struct; CustomEquality; NoComparison>]
-[<System.Diagnostics.DebuggerDisplay("{OriginalRange} -> ({StartLine},{StartColumn}-{EndLine},{EndColumn}) {ShortFileName} -> {DebugCode}")>]
-type Range private (code1: int64, code2: int64, originalRange: struct (int64 * int64) voption) =
+[<System.Diagnostics.DebuggerDisplay("({StartLine},{StartColumn}-{EndLine},{EndColumn}) {ShortFileName} -> {DebugCode}")>]
+type Range(code1: int64, code2: int64) =
     static member Zero = range (0L, 0L)
 
-    new(code1, code2) = range (code1, code2, ValueNone)
-
     new(fIdx, bl, bc, el, ec) =
         let code1 =
             ((int64 fIdx) &&& fileIndexMask)
@@ -388,28 +386,8 @@ type Range private (code1: int64, code2: int64, originalRange: struct (int64 * i
         let code2 = code2 &&& ~~~(debugPointKindMask ||| isSyntheticMask)
         hash code1 + hash code2
 
-    member _.OriginalRange =
-        originalRange
-        |> ValueOption.map (fun struct (code1, code2) -> range (code1, code2))
-
     override r.ToString() =
-        let fromText =
-            if r.HasOriginalRange then
-                $" (from: %s{r.OriginalRange.Value.ToString()})"
-            else
-                String.Empty
-
-        sprintf "(%d,%d--%d,%d)%s" r.StartLine r.StartColumn r.EndLine r.EndColumn fromText
-
-    member m.IsZero = m.Equals range.Zero
-
-    member _.WithOriginalRange(originalRange: range voption) =
-        range (code1, code2, originalRange |> ValueOption.map (fun m -> struct (m.Code1, m.Code2)))
-
-    member this.HasOriginalRange =
-        match this.OriginalRange with
-        | ValueSome range2 when not range2.IsZero -> true
-        | _ -> false
+        sprintf "(%d,%d--%d,%d)" r.StartLine r.StartColumn r.EndLine r.EndColumn
 
 and range = Range
 
@@ -520,18 +498,8 @@ module Range =
                 else
                     m2
 
-            let originalRange =
-                match m1.OriginalRange, m2.OriginalRange with
-                // #line is inside the syntax block
-                | ValueNone, ValueSome r2 when m1.FileIndex = r2.FileIndex ->
-                    ValueSome(range (m1.FileIndex, m1.StartLine, m1.StartColumn, r2.EndLine, r2.EndColumn))
-                | ValueSome r1, ValueSome r2 when r1.FileIndex = r2.FileIndex ->
-                    ValueSome(range (r1.FileIndex, r1.StartLine, r1.StartColumn, r2.EndLine, r2.EndColumn))
-                | _ -> ValueNone
-
             let m =
-                range(m1.FileIndex, start.StartLine, start.StartColumn, finish.EndLine, finish.EndColumn)
-                    .WithOriginalRange(originalRange)
+                range (m1.FileIndex, start.StartLine, start.StartColumn, finish.EndLine, finish.EndColumn)
 
             if m1.IsSynthetic || m2.IsSynthetic then
                 m.MakeSynthetic()
@@ -680,6 +648,4 @@ module internal FileContent =
 
     let mutable getLineDynamic = DefaultFileContentGetLine() :> IFileContentGetLine
 
-    let getCodeText (m: range) =
-        let m = if m.HasOriginalRange then m.OriginalRange.Value else m
-        getLineDynamic.GetRangeText(m)
+    let getCodeText (m: range) = getLineDynamic.GetRangeText(m)
diff --git a/src/Compiler/Utilities/range.fsi b/src/Compiler/Utilities/range.fsi
index 5487905c9d4..a354e705c1b 100755
--- a/src/Compiler/Utilities/range.fsi
+++ b/src/Compiler/Utilities/range.fsi
@@ -107,13 +107,6 @@ type Range =
     /// service operations like dot-completion.
     member IsSynthetic: bool 
 
-    /// The original range for the range
-    member OriginalRange: range voption
-
-    member HasOriginalRange: bool
-            
-    member WithOriginalRange: originalRange: range voption -> range
-
     /// Convert a range to be synthetic
     member internal MakeSynthetic: unit -> range
 
diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Line.fs b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Line.fs
index 5d5cb49afa5..105670d1adb 100644
--- a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Line.fs
+++ b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Line.fs
@@ -51,9 +51,9 @@ printfn ""
     """
 
     [<Theory>]
-    [<InlineData(1, case1, "xyz.fs:(1,0--3,1) (from: (3,0--5,1))")>]
-    [<InlineData(2, case2, "Line.fs:(2,0--2,1) (from: (2,0--5,1))")>]
-    [<InlineData(3, case3, "Line.fs:(2,0--2,1) (from: (2,0--4,1))")>]
+    [<InlineData(1, case1, "xyz.fs:(1,0--3,1)")>]
+    [<InlineData(2, case2, "Line.fs:(2,0--2,1)")>]
+    [<InlineData(3, case3, "Line.fs:(2,0--2,1)")>]
     let ``check expr range interacting with line directive`` (case, source, expectedRange) =
         let parseResults = parse source
         if parseResults.ParseHadErrors then failwith "unexpected: parse error"

From 9c24123a5bdba11dcd4762df1f630abe09dc6387 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Mon, 17 Mar 2025 22:50:20 +0800
Subject: [PATCH 44/57] fix test and add new test

---
 src/Compiler/Interactive/fsi.fs               |  43 +----
 src/Compiler/Utilities/range.fs               |  97 ++++++-----
 src/Compiler/Utilities/range.fsi              |  18 +-
 .../CallerArgumentExpression.fs               | 163 ++++++++++++------
 4 files changed, 186 insertions(+), 135 deletions(-)

diff --git a/src/Compiler/Interactive/fsi.fs b/src/Compiler/Interactive/fsi.fs
index 85667152cb9..32c1e12eaaa 100644
--- a/src/Compiler/Interactive/fsi.fs
+++ b/src/Compiler/Interactive/fsi.fs
@@ -807,6 +807,9 @@ type internal FsiValuePrinter(fsi: FsiEvaluationSessionHostConfig, outWriter: Te
 type internal FsiStdinSyphon(errorWriter: TextWriter) =
     let syphonText = StringBuilder()
 
+    /// Get the current syphon text
+    member _.SyphonText = syphonText.ToString()
+
     /// Clears the syphon text
     member _.Reset() = syphonText.Clear() |> ignore
 
@@ -837,15 +840,6 @@ type internal FsiStdinSyphon(errorWriter: TextWriter) =
             let lines = text.Split '\n'
             if 0 < i && i <= lines.Length then lines[i - 1] else ""
 
-    /// Gets the indicated line in the syphon text
-    member _.GetLineNoPrune fileName i =
-        if fileName <> stdinMockFileName then
-            ""
-        else
-            let text = syphonText.ToString()
-            let lines = text.Split '\n'
-            if 0 < i && i <= lines.Length then lines[i - 1] else ""
-
     /// Display the given error.
     member syphon.PrintDiagnostic(tcConfig: TcConfig, diagnostic: PhasedDiagnostic) =
         ignoreAllErrors (fun () ->
@@ -4682,36 +4676,11 @@ type FsiEvaluationSession
             fsiConsolePrompt.PrintAhead()
 
     do
-        FileContent.getLineDynamic <-
-            { new FileContent.DefaultFileContentGetLine() with
+        FileContent.getRangeTextDynamic <-
+            { new FileContent.DefaultGetRangeText() with
                 override _.GetRangeText(range) : string =
                     if range.FileName = stdinMockFileName then
-                        if range.StartLine = range.EndLine then
-                            let line = fsiStdinSyphon.GetLineNoPrune stdinMockFileName range.StartLine
-                            let start = min range.StartColumn (line.Length - 1)
-                            line.[start .. range.EndColumn - 1]
-                        else
-                            let result = StringBuilder()
-
-                            for i in range.StartLine .. range.EndLine do
-                                let line = (fsiStdinSyphon.GetLineNoPrune stdinMockFileName i).AsSpan()
-
-                                let line =
-                                    if i = range.StartLine then
-                                        let start = min range.StartColumn (line.Length - 1)
-                                        line.Slice(start)
-                                    elif i = range.EndLine then
-                                        let len = min range.EndColumn line.Length
-                                        line.Slice(0, len)
-                                    else
-                                        line
-
-                                result.Append(line.ToString()) |> ignore
-
-                                if i = range.EndLine then
-                                    result.Append(Environment.NewLine) |> ignore
-
-                            result.ToString()
+                        FileContent.substring fsiStdinSyphon.SyphonText range
                     else
                         base.GetRangeText(range)
             }
diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs
index b33608168a8..e0d557e6642 100755
--- a/src/Compiler/Utilities/range.fs
+++ b/src/Compiler/Utilities/range.fs
@@ -588,64 +588,81 @@ module internal FileContent =
     let readFileContents (fileNames: string list) =
         for fileName in fileNames do
             if FileSystem.FileExistsShim fileName then
-                use fileStream = FileSystem.OpenFileForReadShim(fileName)
-                fileContentDict[fileName] <- fileStream.ReadAllText()
+                try
+                    use fileStream = FileSystem.OpenFileForReadShim(fileName)
+                    fileContentDict[fileName] <- fileStream.ReadAllText()
+                with _ ->
+                    ()
+
+    let private seperators = [| '\r'; '\n' |]
+
+    /// Find the index of the nearest line separator in the given string and offset.
+    let findLineEnd (input: string) lineStart =
+        if lineStart >= input.Length then
+            input.Length - 1
+        else
+            let idx = input.IndexOfAny(seperators, lineStart)
 
-    let substring (input: string) (startLine, startCol) (endLine, endCol) =
-        let findLineEnd lineStart =
-            if lineStart >= input.Length then
+            if idx = -1 then
                 input.Length - 1
+            elif input.[idx] = '\r' && idx + 1 < input.Length && input.[idx + 1] = '\n' then
+                idx + 1
             else
-                let idx = input.IndexOfAny([| '\r'; '\n' |], lineStart)
+                idx
 
-                if idx = -1 then
-                    input.Length - 1
-                elif input.[idx] = '\r' && idx + 1 < input.Length && input.[idx + 1] = '\n' then
-                    idx + 1
-                else
-                    idx
+    let substring (input: string) (range: range) =
+        let startLine, startCol = range.StartLine, range.StartColumn
+        let endLine, endCol = range.EndLine, range.EndColumn
 
-        if startLine < 1 || startLine > endLine || startCol < 0 || endCol < 0 then
-            ""
+        if
+            startLine < 1
+            || (startLine = endLine && startCol > endCol)
+            || startLine > endLine
+            || startCol < 0
+            || endCol < 0
+        then
+            System.String.Empty
         else
-            let result = System.Text.StringBuilder()
+            // Here the loop was splited into two functions to avoid the non necessary allocation of the StringBuilder
 
-            let rec loop lineCount startIndex endIndex =
-                if lineCount > endLine then
-                    result.ToString()
-                elif lineCount < startLine then
-                    loop (lineCount + 1) (endIndex + 1) (findLineEnd (endIndex + 1))
-                elif lineCount = startLine && startLine = endLine then
-                    input.[startIndex + startCol.. startIndex + endCol - 1]
-                elif lineCount = startLine then
-                    if startCol < endIndex - startIndex + 1 then
-                        result.Append(input.Substring(startIndex + startCol, endIndex - startIndex + 1 - startCol))
-                        |> ignore
-
-                    loop (lineCount + 1) (endIndex + 1) (findLineEnd (endIndex + 1))
+            let rec loopEnd (result: System.Text.StringBuilder) lineCount (startIndex, endIndex) =
+                if lineCount < endLine then
+                    result.Append(input.Substring(startIndex, endIndex - startIndex + 1)) |> ignore
+                    loopEnd result (lineCount + 1) (endIndex + 1, findLineEnd input (endIndex + 1))
                 elif lineCount = endLine then
                     let len = min endCol (endIndex - startIndex + 1)
                     result.Append(input.Substring(startIndex, len)).ToString()
                 else
-                    result.Append(input.Substring(startIndex, endIndex - startIndex + 1)) |> ignore
-                    loop (lineCount + 1) (endIndex + 1) (findLineEnd (endIndex + 1))
+                    result.ToString()
+
+            let rec loopStart lineCount (startIndex, endIndex) =
+                if lineCount < startLine then
+                    loopStart (lineCount + 1) (endIndex + 1, findLineEnd input (endIndex + 1))
+                elif lineCount = startLine && startLine = endLine then
+                    let endCol = min (endCol - 1) endIndex
+                    input.Substring(startIndex + startCol, endCol - startCol + 1)
+                else
+                    let result = System.Text.StringBuilder()
 
-            loop 1 0 (findLineEnd 0)
+                    if lineCount = startLine then
+                        if startCol < endIndex - startIndex + 1 then
+                            result.Append(input.Substring(startIndex + startCol, endIndex - startIndex + 1 - startCol))
+                            |> ignore
 
-    type IFileContentGetLine =
-        abstract GetRangeText: range: range -> string
+                        loopEnd result (lineCount + 1) (endIndex + 1, findLineEnd input (endIndex + 1))
+                    else
+                        loopEnd result lineCount (startIndex, endIndex)
 
-    type DefaultFileContentGetLine() =
+            loopStart 1 (0, findLineEnd input 0)
+
+    type DefaultGetRangeText() =
         abstract GetRangeText: range: range -> string
 
         default _.GetRangeText(range: range) : string =
             match fileContentDict.TryGetValue range.FileName with
-            | true, text -> substring text (range.StartLine, range.StartColumn) (range.EndLine, range.EndColumn)
+            | true, text -> substring text range
             | _ -> String.Empty
 
-        interface IFileContentGetLine with
-            member this.GetRangeText(range: range) : string = this.GetRangeText(range)
-
-    let mutable getLineDynamic = DefaultFileContentGetLine() :> IFileContentGetLine
+    let mutable getRangeTextDynamic = DefaultGetRangeText()
 
-    let getCodeText (m: range) = getLineDynamic.GetRangeText(m)
+    let getCodeText (m: range) = getRangeTextDynamic.GetRangeText(m)
diff --git a/src/Compiler/Utilities/range.fsi b/src/Compiler/Utilities/range.fsi
index a354e705c1b..48620a9ceb4 100755
--- a/src/Compiler/Utilities/range.fsi
+++ b/src/Compiler/Utilities/range.fsi
@@ -269,27 +269,25 @@ module Line =
     /// Convert a line number from one-based line counting (used internally in the F# compiler and in F# error messages) to zero-based line counting (used by Visual Studio)
     val toZ: int -> Line0 
 
-/// Store code file content. Use to implement `CallerArgumentExpression`
+/// Store code file content. Used to implement `CallerArgumentExpression`
 module internal FileContent =
 
     /// Read all file contents.
     ///
     /// Used by `getCodeText` to support `CallerArgumentExpression`
     val readFileContents: fileNames: string list -> unit
-
-    type IFileContentGetLine =
-        abstract GetRangeText: range: range -> string
+    
+    val substring: input: string -> range: range -> string    
         
-    type DefaultFileContentGetLine =
-        new: unit -> DefaultFileContentGetLine
+    type DefaultGetRangeText =
+        new: unit -> DefaultGetRangeText
         abstract GetRangeText: range: range -> string
         override GetRangeText: range: range -> string
-        interface IFileContentGetLine
 
-    /// Get a line string from already read files.
+    /// Get the code text of the specific `range` from already read files.
     ///
     /// Used by `getCodeText` to support `CallerArgumentExpression`
-    val mutable getLineDynamic: IFileContentGetLine
+    val mutable getRangeTextDynamic: DefaultGetRangeText
 
-    /// Get code text of the specific `range`
+    /// Get the code text of the specific `range`
     val getCodeText: range -> string
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
index f0dec9bc4c8..aa2b2a075c3 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
@@ -31,7 +31,7 @@ with :? System.ArgumentException as ex ->
         |> ignore
 
     [<FactForNETCOREAPP>]
-    let ``Can define methods using CallerArgumentExpression in F#`` () =
+    let ``Can define methods using CallerArgumentExpression with C#-style optional arguments`` () =
         FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
 open System.Runtime.CompilerServices
 open System.Runtime.InteropServices
@@ -54,7 +54,7 @@ assertEqual (A.aa(a = stringABC)) ("abc", ".cctor", 14, "stringABC")
         |> ignore
 
     [<FactForNETCOREAPP>]
-    let ``Can define methods using CallerArgumentExpression F# with F#-style optional arguments`` () =
+    let ``Can define methods using CallerArgumentExpression with F#-style optional arguments`` () =
         FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
 open System.Runtime.CompilerServices
 open System.Runtime.InteropServices
@@ -79,7 +79,7 @@ assertEqual (A.aa(a = stringABC)) ("abc", ".cctor", 17, "stringABC")
         |> shouldSucceed
         |> ignore
 
-    [<FactForNETCOREAPP>]
+    [<FactForNETCOREAPP(Skip = "Currently cannot get the original text range with #line")>]
     let ``Can define in F# - with #line`` () =
         FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
 open System.Runtime.CompilerServices
@@ -96,45 +96,17 @@ type A() =
     [<CallerFilePath; Optional; DefaultParameterValue "no value">]d: string, 
     [<CallerArgumentExpressionAttribute("a"); Optional; DefaultParameterValue "no value">]e: string) = 
     a,b,c,d,e
+    
+  static member B (``ab c``, [<CallerArgumentExpression "ab c">]?n) =
+    defaultArg n "no value"
 
 let stringABC = "abc"
-assertEqual (A.aa(stringABC)) ("abc", ".cctor", 11, System.IO.Path.Combine(__SOURCE_DIRECTORY__, "test.fs"), "stringABC")
+assertEqual (A.aa(stringABC)) ("abc", ".cctor", 11, path, "stringABC")
 # 1 "test.fs"
-assertEqual (A.aa(stringABC : string)) ("abc", ".cctor", 1, System.IO.Path.Combine(__SOURCE_DIRECTORY__, "test.fs"), "stringABC : string")
+assertEqual (A.aa(stringABC : string)) ("abc", ".cctor", 1, path, "stringABC : string")
 # 1 "test.fs"
-assertEqual (A.aa(a = (stringABC : string))) ("abc", ".cctor", 1, System.IO.Path.Combine(__SOURCE_DIRECTORY__, "test.fs"), "(stringABC : string)")
-        """
-        |> withLangVersionPreview
-        |> asExe
-        |> compileAndRun
-        |> shouldSucceed
-        |> ignore
+assertEqual (A.aa(a = (stringABC : string))) ("abc", ".cctor", 1, path, "(stringABC : string)")
 
-    [<FactForNETCOREAPP>]
-    let ``Can define methods using CallerArgumentExpression receiving special parameter names`` () =
-      FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
-open System.Runtime.CompilerServices
-
-type A() =
-  static member B (``ab c``, [<CallerArgumentExpression "ab c">]?n) =
-    defaultArg n "no value"
-      
-assertEqual (A.B("abc")) "\"abc\""
-        """
-        |> withLangVersionPreview
-        |> asExe
-        |> compileAndRun
-        |> shouldSucceed
-        |> ignore
-        
-    [<FactForNETCOREAPP>]
-    let ``#line can be inserted in the argument`` () =
-      FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
-open System.Runtime.CompilerServices
-
-type A() =
-  static member B (``ab c``, [<CallerArgumentExpression "ab c">]?n) =
-    defaultArg n "no value"
 
 A.B("abc"
 #line 1
@@ -150,14 +122,30 @@ A.B((+) 1
 |> assertEqual "(+) 1
 #line 1
         123"
-        
+
 
 A.B(#line 1
   (+) 1
         123)
 |> assertEqual "(+) 1
         123"
-        
+        """
+        |> withLangVersionPreview
+        |> asExe
+        |> compileAndRun
+        |> shouldSucceed
+        |> ignore
+
+    [<FactForNETCOREAPP>]
+    let ``Can define methods using CallerArgumentExpression receiving special parameter names`` () =
+      FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
+open System.Runtime.CompilerServices
+
+type A() =
+  static member B (``ab c``, [<CallerArgumentExpression "ab c">]?n) =
+    defaultArg n "no value"
+      
+assertEqual (A.B("abc")) "\"abc\""
         """
         |> withLangVersionPreview
         |> asExe
@@ -166,7 +154,7 @@ A.B(#line 1
         |> ignore
         
     [<FactForNETCOREAPP>]
-    let ``test Warns when cannot find the referenced parameter`` () =
+    let ``test Warns when cannot find the referenced parameter or self-referential`` () =
       FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
 open System.Runtime.CompilerServices
 
@@ -227,20 +215,99 @@ module A =
   type A() =
     static member B (``ab c``, [<CallerArgumentExpression "ab c">]?n) =
       defaultArg n "no value"
-      
-  A.B("abc"
-#line 1
-  : string)
-  |> assertEqual "\"abc\"
-#line 1
-  : string"
   
   A.B "abc" |> assertEqual "\"abc\""  
   A.B ("abc": string) |> assertEqual "\"abc\": string"
+  A.B ("abc": (* comments *) string) |> assertEqual "\"abc\": (* comments *) string"
+"""
+        |> withLangVersionPreview
+        |> asExe
+        |> compileAndRun
+        |> shouldSucceed
+        |> ignore
+        
+    [<FactForNETCOREAPP>]
+    let ``Can use with Computation Expression`` =
+      FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
+open System.Runtime.CompilerServices
+open System.Runtime.InteropServices
+
+type Builder() =
+    member self.Bind(
+        x, f,
+        [<CallerArgumentExpression "x">] ?exp : string,
+        [<CallerArgumentExpression "f">] ?exp2 : string) =
+        (f x, $"f={exp2.Value}, x={exp.Value}")
+
+    member self.Return(x, [<CallerArgumentExpression "x">] ?exp : string) =
+        (x, $"x={exp.Value}")
+
+let b = Builder()
+b { do! () } |> assertEqual (((), "x=do!"), "f=do!, x=()")
+b { let! a = 123 in return a } |> assertEqual ((123, "x=a"), "f=return a, x=123")
+
+b {
+    let! a = 123
+    let! b = 456
+    return a + b
+} |> assertEqual
+  (((579, "x=a + b"), "f=return a + b, x=456"),
+   "f=let! b = 456
+    return a + b, x=123")
+"""
+        |> withLangVersionPreview
+        |> asExe
+        |> compileAndRun
+        |> shouldSucceed
+        |> ignore
+      
+   
+    [<FactForNETCOREAPP>]
+    let ``Can use with Delegate and Quotation`` =
+      FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
+open System.Runtime.CompilerServices
+open System.Runtime.InteropServices
+
+type A =
+  delegate of
+    a: int *
+    [<CallerArgumentExpression "a">] ?expr: string *
+    [<CallerArgumentExpression "a"; Optional; DefaultParameterValue "">] expr2: string
+      -> string * string option
+let a = A (fun a expr expr2 -> expr2, expr)
+a.Invoke(123 - 7) |> assertEqual ("123 - 7", Some "123 - 7")
+
+open Microsoft.FSharp.Quotations.Patterns
+match <@ a.Invoke(123 - 7) @> with
+| Call(_, _, [_; Value (:? (string * string option) as value, _)]) -> assertEqual ("123 - 7", Some "123 - 7") value
+| _ -> failwith "fail"
+"""
+        |> withLangVersionPreview
+        |> asExe
+        |> compileAndRun
+        |> shouldSucceed
+        |> ignore
+      
+   
+    [<FactForNETCOREAPP>]
+    let ``Can use with Interface and Object Expression`` =
+      FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
+open System.Runtime.CompilerServices
+open System.Runtime.InteropServices
+
+type Interface1 =
+  abstract member M:
+    a: int *
+    [<CallerArgumentExpression "a">] ?expr: string *
+    [<CallerArgumentExpression "a"; Optional; DefaultParameterValue "">] expr2: string
+      -> string * string option
+
+{new Interface1 with
+    member this.M(a, expr, expr2) = expr2, expr}.M(123 - 7) |> assertEqual ("123 - 7", Some "123 - 7")
 """
         |> withLangVersionPreview
         |> asExe
         |> compileAndRun
         |> shouldSucceed
         |> ignore
-        
\ No newline at end of file
+      
\ No newline at end of file

From 2e7121d98f31eaf0b2edf24cc9028c8727dd541f Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Thu, 20 Mar 2025 21:13:23 +0800
Subject: [PATCH 45/57] add a new test

---
 src/Compiler/Checking/MethodCalls.fs          |  1 +
 .../CallerArgumentExpression.fs               | 31 ++++++++++++++++---
 2 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/src/Compiler/Checking/MethodCalls.fs b/src/Compiler/Checking/MethodCalls.fs
index ac13b880bf7..ae3150e59ba 100644
--- a/src/Compiler/Checking/MethodCalls.fs
+++ b/src/Compiler/Checking/MethodCalls.fs
@@ -1437,6 +1437,7 @@ let AdjustCallerArgExpr tcVal (g: TcGlobals) amap infoReader ad isOutArg calledA
 /// matter what order they are applied in as long as they are all composed together.
 let emptyPreBinder (e: Expr) = e
 
+/// Try to pick the code text of an argument with the given parameter name from a list of assigned arguments.
 let tryPickArgumentCodeText assignedArgs paramName =
     assignedArgs
     |> List.tryPick (fun { CalledArg=called; CallerArg=caller } -> 
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
index aa2b2a075c3..c51a3c31dff 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
@@ -15,14 +15,18 @@ try System.ArgumentException.ThrowIfNullOrWhiteSpace(Seq.init 50 (fun _ -> " ")
   (* comment *) 
   |> String.concat " ")
 with :? System.ArgumentException as ex -> 
-  assertEqual true (ex.Message.Contains("(Parameter 'Seq.init 50 (fun _ -> \" \")\n  (* comment *) \n  |> String.concat \" \""))
+  assertEqual true (ex.Message.Contains("(Parameter 'Seq.init 50 (fun _ -> \" \")
+  (* comment *) 
+  |> String.concat \" \""))
   
 
 try System.ArgumentException.ThrowIfNullOrWhiteSpace(argument = (Seq.init 11 (fun _ -> " ")
   (* comment *) 
   |> String.concat " "))
 with :? System.ArgumentException as ex -> 
-  assertEqual true (ex.Message.Contains("(Parameter '(Seq.init 11 (fun _ -> \" \")\n  (* comment *) \n  |> String.concat \" \")"))
+  assertEqual true (ex.Message.Contains("(Parameter '(Seq.init 11 (fun _ -> \" \")
+  (* comment *) 
+  |> String.concat \" \")"))
 """
         |> withLangVersionPreview
         |> asExe
@@ -153,6 +157,26 @@ assertEqual (A.B("abc")) "\"abc\""
         |> shouldSucceed
         |> ignore
         
+    [<FactForNETCOREAPP>]
+    let ``C# can consume methods using CallerArgumentExpression receiving special parameter names`` () =
+        let fs =
+          FSharp """module Lib
+let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
+open System.Runtime.CompilerServices
+
+type A() =
+  static member B (``ab c``, [<CallerArgumentExpression "ab c">]?n) =
+    defaultArg n "no value"
+        """ 
+          |> withLangVersionPreview
+
+        CSharp """Lib.assertEqual(A.B("abc"), "\"abc\"");"""
+        |> withReferences [fs]
+        |> asExe
+        |> compileAndRun
+        |> shouldSucceed
+        |> ignore
+        
     [<FactForNETCOREAPP>]
     let ``test Warns when cannot find the referenced parameter or self-referential`` () =
       FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
@@ -196,7 +220,7 @@ type A() =
         ]
         
     [<Fact>]
-    let ``Can self define CallerArgumentExpression`` () =
+    let ``User can define the CallerArgumentExpression`` () =
       FSharp """namespace System.Runtime.CompilerServices
 
 open System
@@ -288,7 +312,6 @@ match <@ a.Invoke(123 - 7) @> with
         |> shouldSucceed
         |> ignore
       
-   
     [<FactForNETCOREAPP>]
     let ``Can use with Interface and Object Expression`` =
       FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b

From fb8a3d0896b94f0ac8db68ea1aa90c67f531948f Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Thu, 20 Mar 2025 22:38:47 +0800
Subject: [PATCH 46/57] add test

---
 src/Compiler/Utilities/range.fs               | 31 ++++++++++++++++---
 .../CallerArgumentExpression.fs               |  3 +-
 .../FSharp.Compiler.Service.Tests.fsproj      |  1 +
 .../FileContentTests.fs                       | 30 ++++++++++++++++++
 4 files changed, 59 insertions(+), 6 deletions(-)
 create mode 100644 tests/FSharp.Compiler.Service.Tests/FileContentTests.fs

diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs
index e0d557e6642..8dbbb64bd4d 100755
--- a/src/Compiler/Utilities/range.fs
+++ b/src/Compiler/Utilities/range.fs
@@ -596,7 +596,7 @@ module internal FileContent =
 
     let private seperators = [| '\r'; '\n' |]
 
-    /// Find the index of the nearest line separator in the given string and offset.
+    /// Find the index of the nearest line separator (\r or \r\n or \n) in the given string and offset.
     let findLineEnd (input: string) lineStart =
         if lineStart >= input.Length then
             input.Length - 1
@@ -610,6 +610,8 @@ module internal FileContent =
             else
                 idx
 
+    /// Get the substring of the given range.
+    /// This can retain the line seperators in the source string, whilst `FSharp.Compiler.Text.StringText.GetSubTextFromRange` does not.
     let substring (input: string) (range: range) =
         let startLine, startCol = range.StartLine, range.StartColumn
         let endLine, endCol = range.EndLine, range.EndColumn
@@ -625,22 +627,40 @@ module internal FileContent =
         else
             // Here the loop was splited into two functions to avoid the non necessary allocation of the StringBuilder
 
+            /// Take text until reach the end line of the range.
             let rec loopEnd (result: System.Text.StringBuilder) lineCount (startIndex, endIndex) =
                 if lineCount < endLine then
                     result.Append(input.Substring(startIndex, endIndex - startIndex + 1)) |> ignore
-                    loopEnd result (lineCount + 1) (endIndex + 1, findLineEnd input (endIndex + 1))
+
+                    let nextLineEnd = findLineEnd input (endIndex + 1)
+
+                    if nextLineEnd = endIndex then
+                        result.ToString()
+                    else
+                        loopEnd result (lineCount + 1) (endIndex + 1, nextLineEnd)
                 elif lineCount = endLine then
                     let len = min endCol (endIndex - startIndex + 1)
                     result.Append(input.Substring(startIndex, len)).ToString()
                 else
                     result.ToString()
 
+            /// Go to the start line of the range.
             let rec loopStart lineCount (startIndex, endIndex) =
                 if lineCount < startLine then
-                    loopStart (lineCount + 1) (endIndex + 1, findLineEnd input (endIndex + 1))
+                    let nextLineEnd = findLineEnd input (endIndex + 1)
+
+                    if nextLineEnd = endIndex then
+                        System.String.Empty
+                    else
+                        loopStart (lineCount + 1) (endIndex + 1, nextLineEnd)
+
+                // reach the start line
                 elif lineCount = startLine && startLine = endLine then
-                    let endCol = min (endCol - 1) endIndex
-                    input.Substring(startIndex + startCol, endCol - startCol + 1)
+                    if startIndex + startCol <= endIndex then
+                        let endCol = min (endCol - 1) (endIndex - startIndex)
+                        input.Substring(startIndex + startCol, endCol - startCol + 1)
+                    else
+                        System.String.Empty
                 else
                     let result = System.Text.StringBuilder()
 
@@ -651,6 +671,7 @@ module internal FileContent =
 
                         loopEnd result (lineCount + 1) (endIndex + 1, findLineEnd input (endIndex + 1))
                     else
+                        // Should not go into here
                         loopEnd result lineCount (startIndex, endIndex)
 
             loopStart 1 (0, findLineEnd input 0)
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
index c51a3c31dff..788172600b6 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
@@ -170,7 +170,8 @@ type A() =
         """ 
           |> withLangVersionPreview
 
-        CSharp """Lib.assertEqual(A.B("abc"), "\"abc\"");"""
+        CSharp """Lib.assertEqual(Lib.A.B("abc"), "\"abc\"");"""
+        |> withName "CSLib"
         |> withReferences [fs]
         |> asExe
         |> compileAndRun
diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj
index 57ce88d8f02..54cca8a29dd 100644
--- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj
+++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj
@@ -48,6 +48,7 @@
     <Compile Include="XmlDocTests.fs" />
     <Compile Include="XmlDocTests - Units of Measure.fs" />
     <Compile Include="RangeTests.fs" />
+    <Compile Include="FileContentTests.fs" />
     <Compile Include="TooltipTests.fs" />
     <Compile Include="TokenizerTests.fs" />
     <Compile Include="CompilerTestHelpers.fs" />
diff --git a/tests/FSharp.Compiler.Service.Tests/FileContentTests.fs b/tests/FSharp.Compiler.Service.Tests/FileContentTests.fs
new file mode 100644
index 00000000000..eba6e1ac633
--- /dev/null
+++ b/tests/FSharp.Compiler.Service.Tests/FileContentTests.fs
@@ -0,0 +1,30 @@
+module FSharp.Compiler.Service.Tests.FileContentTests
+
+open FSharp.Compiler.Text
+open FSharp.Compiler.Text.Position
+open FSharp.Compiler.Text.Range
+open FSharp.Compiler.Text.FileContent
+open FSharp.Test.Assert
+open Xunit
+
+let substring (input: string) (startLine, startCol) (endLine, endCol) =
+    let range = mkFileIndexRange 0 (mkPos startLine startCol) (mkPos endLine endCol)
+    substring input range
+    
+[<Fact>]
+let ``substring tests`` () =
+    substring "Hello, world!\r\nThis is a test.\r\n" (1, 7) (2, 4) |> shouldEqual "world!\r\nThis"
+    substring "Hello, world!\r\nThis is a test.\r\n" (9, 7) (9, 4) |> shouldEqual ""
+    substring "Hello, world!\r\nThis is a test.\r\ntest\n" (1, 7) (9, 4) |> shouldEqual "world!\r\nThis is a test.\r\ntest\n"
+    substring "Hello, world!\r\nThis is a test.\r\n" (1, 7) (2, 100) |> shouldEqual "world!\r\nThis is a test.\r\n"
+    substring "Hello, world!\r\nThis is a test.\r\n" (1, 7) (2, 7) |> shouldEqual "world!\r\nThis is"
+    substring "Hello, world! This is a test.\r\na test" (2, 1) (2, 6) |> shouldEqual "test"
+    substring "Hello, world! This is a test.\r\na test" (2, 7) (2, 8) |> shouldEqual ""
+    
+    substring "Hello, world!\r\nThis is a test.\r\n" (1, 0) (1, 4) |> shouldEqual "Hell"
+    substring "Hello, world!\r\nThis is a test.\r\n" (1, 7) (1, 4) |> shouldEqual ""
+    substring "Hello, world!\r\nThis is a test.\r\n" (1, 7) (1, 100) |> shouldEqual "world!\r\n"
+    substring "Hello, world!\r\nThis is a test.\r\n" (1, 7) (1, 7) |> shouldEqual ""
+    substring "Hello, world!\r\nThis is a test.\r\n" (1, 7) (1, 8) |> shouldEqual "w"
+    substring "Hello, world!\r\nThis is a test.\r\n" (1, 0) (1, 8) |> shouldEqual "Hello, w"
+    substring "Hello, world!\r\nThis is a test.\r\n" (1, 0) (1, 100) |> shouldEqual "Hello, world!\r\n"

From 70f563065eeb41668b4a3beb12150f161eb207c7 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Fri, 21 Mar 2025 09:29:32 +0800
Subject: [PATCH 47/57] change the position to get code file content

---
 src/Compiler/Driver/ParseAndCheckInputs.fs    | 36 ++++++++-----------
 src/Compiler/Driver/ScriptClosure.fs          |  4 +--
 src/Compiler/Driver/fsc.fs                    |  2 --
 src/Compiler/Service/IncrementalBuild.fs      |  2 --
 src/Compiler/Service/TransparentCompiler.fs   |  2 --
 src/Compiler/Service/service.fs               |  3 --
 src/Compiler/Utilities/range.fs               |  7 +++-
 src/Compiler/Utilities/range.fsi              |  5 +++
 .../CallerArgumentExpression.fs               |  3 +-
 .../FileContentTests.fs                       |  2 +-
 10 files changed, 30 insertions(+), 36 deletions(-)

diff --git a/src/Compiler/Driver/ParseAndCheckInputs.fs b/src/Compiler/Driver/ParseAndCheckInputs.fs
index 975bfeef66f..83b2f53ea3a 100644
--- a/src/Compiler/Driver/ParseAndCheckInputs.fs
+++ b/src/Compiler/Driver/ParseAndCheckInputs.fs
@@ -702,52 +702,44 @@ let checkInputFile (tcConfig: TcConfig) fileName =
     else
         error (Error(FSComp.SR.buildInvalidSourceFileExtension (SanitizeFileName fileName tcConfig.implicitIncludeDir), rangeStartup))
 
-let parseInputStreamAux
+let parseInputSourceTextAux
     (
         tcConfig: TcConfig,
         lexResourceManager,
         fileName,
         isLastCompiland,
         diagnosticsLogger,
-        retryLocked,
-        stream: Stream
+        sourceText: ISourceText
     ) =
-    use reader = stream.GetReader(tcConfig.inputCodePage, retryLocked)
-
+    if FSharpImplFileSuffixes |> List.exists (FileSystemUtils.checkSuffix fileName) then
+        FSharp.Compiler.Text.FileContent.setFileContent fileName (sourceText.GetSubTextString(0, sourceText.Length))
+    
     // Set up the LexBuffer for the file
     let lexbuf =
-        UnicodeLexing.StreamReaderAsLexbuf(not tcConfig.compilingFSharpCore, tcConfig.langVersion, tcConfig.strictIndentation, reader)
+        UnicodeLexing.SourceTextAsLexbuf(not tcConfig.compilingFSharpCore, tcConfig.langVersion, tcConfig.strictIndentation, sourceText)
 
     // Parse the file drawing tokens from the lexbuf
     ParseOneInputLexbuf(tcConfig, lexResourceManager, lexbuf, fileName, isLastCompiland, diagnosticsLogger)
 
-let parseInputSourceTextAux
+let parseInputStreamAux
     (
         tcConfig: TcConfig,
         lexResourceManager,
         fileName,
         isLastCompiland,
         diagnosticsLogger,
-        sourceText: ISourceText
+        retryLocked,
+        stream: Stream
     ) =
-    // Set up the LexBuffer for the file
-    let lexbuf =
-        UnicodeLexing.SourceTextAsLexbuf(not tcConfig.compilingFSharpCore, tcConfig.langVersion, tcConfig.strictIndentation, sourceText)
-
-    // Parse the file drawing tokens from the lexbuf
-    ParseOneInputLexbuf(tcConfig, lexResourceManager, lexbuf, fileName, isLastCompiland, diagnosticsLogger)
+    use reader = stream.GetReader(tcConfig.inputCodePage, retryLocked)
+    let text = reader.ReadToEnd()
+    let sourceText = SourceText.ofString text
+    parseInputSourceTextAux (tcConfig, lexResourceManager, fileName, isLastCompiland, diagnosticsLogger, sourceText)
 
 let parseInputFileAux (tcConfig: TcConfig, lexResourceManager, fileName, isLastCompiland, diagnosticsLogger, retryLocked) =
     // Get a stream reader for the file
     use fileStream = FileSystem.OpenFileForReadShim(fileName)
-    use reader = fileStream.GetReader(tcConfig.inputCodePage, retryLocked)
-
-    // Set up the LexBuffer for the file
-    let lexbuf =
-        UnicodeLexing.StreamReaderAsLexbuf(not tcConfig.compilingFSharpCore, tcConfig.langVersion, tcConfig.strictIndentation, reader)
-
-    // Parse the file drawing tokens from the lexbuf
-    ParseOneInputLexbuf(tcConfig, lexResourceManager, lexbuf, fileName, isLastCompiland, diagnosticsLogger)
+    parseInputStreamAux (tcConfig, lexResourceManager, fileName, isLastCompiland, diagnosticsLogger, retryLocked, fileStream)
 
 /// Parse an input from stream
 let ParseOneInputStream
diff --git a/src/Compiler/Driver/ScriptClosure.fs b/src/Compiler/Driver/ScriptClosure.fs
index de1104ea944..c72975733cf 100644
--- a/src/Compiler/Driver/ScriptClosure.fs
+++ b/src/Compiler/Driver/ScriptClosure.fs
@@ -134,6 +134,8 @@ module ScriptPreprocessClosure =
         tcConfigB.conditionalDefines <- defines @ tcConfig.conditionalDefines
         let tcConfig = TcConfig.Create(tcConfigB, false)
 
+        FSharp.Compiler.Text.FileContent.setFileContent fileName (sourceText.GetSubTextString(0, sourceText.Length))
+
         let lexbuf =
             UnicodeLexing.SourceTextAsLexbuf(true, tcConfig.langVersion, tcConfig.strictIndentation, sourceText)
 
@@ -159,9 +161,7 @@ module ScriptPreprocessClosure =
             reduceMemoryUsage
         ) =
 
-        FileContent.readFileContents [ fileName ]
         let projectDir = !! Path.GetDirectoryName(fileName)
-
         let isInteractive = (codeContext = CodeContext.CompilationAndEvaluation)
         let isInvalidationSupported = (codeContext = CodeContext.Editing)
 
diff --git a/src/Compiler/Driver/fsc.fs b/src/Compiler/Driver/fsc.fs
index caccb6f6dbe..0e26f2db4ac 100644
--- a/src/Compiler/Driver/fsc.fs
+++ b/src/Compiler/Driver/fsc.fs
@@ -630,8 +630,6 @@ let main1
     // Register framework tcImports to be disposed in future
     disposables.Register frameworkTcImports
 
-    FileContent.readFileContents sourceFiles
-
     // Parse sourceFiles
     ReportTime tcConfig "Parse inputs"
     use unwindParsePhase = UseBuildPhase BuildPhase.Parse
diff --git a/src/Compiler/Service/IncrementalBuild.fs b/src/Compiler/Service/IncrementalBuild.fs
index bdae3a4c6a2..0cdc4b9235e 100644
--- a/src/Compiler/Service/IncrementalBuild.fs
+++ b/src/Compiler/Service/IncrementalBuild.fs
@@ -1490,8 +1490,6 @@ type IncrementalBuilder(initialState: IncrementalBuilderInitialState, state: Inc
 
                 tcConfigB, sourceFilesNew
 
-            FileContent.readFileContents sourceFiles
-
             // If this is a builder for a script, re-apply the settings inferred from the
             // script and its load closure to the configuration.
             //
diff --git a/src/Compiler/Service/TransparentCompiler.fs b/src/Compiler/Service/TransparentCompiler.fs
index 0a448e34479..3b411028328 100644
--- a/src/Compiler/Service/TransparentCompiler.fs
+++ b/src/Compiler/Service/TransparentCompiler.fs
@@ -917,8 +917,6 @@ type internal TransparentCompiler
             tcConfigB.parallelReferenceResolution <- parallelReferenceResolution
             tcConfigB.captureIdentifiersWhenParsing <- captureIdentifiersWhenParsing
 
-            FileContent.readFileContents sourceFilesNew
-
             return tcConfigB, sourceFilesNew, loadClosureOpt
         }
 
diff --git a/src/Compiler/Service/service.fs b/src/Compiler/Service/service.fs
index 68bdaceb9bc..4835b784bf8 100644
--- a/src/Compiler/Service/service.fs
+++ b/src/Compiler/Service/service.fs
@@ -634,9 +634,6 @@ type FSharpChecker
 
         // Apply command-line arguments and collect more source files if they are in the arguments
         let sourceFilesNew = ApplyCommandLineArgs(tcConfigB, sourceFiles, argv)
-
-        FileContent.readFileContents sourceFilesNew
-
         FSharpParsingOptions.FromTcConfigBuilder(tcConfigB, Array.ofList sourceFilesNew, isInteractive), errorScope.Diagnostics
 
     member ic.GetParsingOptionsFromCommandLineArgs(argv, ?isInteractive: bool, ?isEditing) =
diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs
index 8dbbb64bd4d..4ff1fe85b55 100755
--- a/src/Compiler/Utilities/range.fs
+++ b/src/Compiler/Utilities/range.fs
@@ -587,12 +587,17 @@ module internal FileContent =
 
     let readFileContents (fileNames: string list) =
         for fileName in fileNames do
+        // if FSharpImplFileSuffixes |> List.exists (FileSystemUtils.checkSuffix fileName) then
+        
             if FileSystem.FileExistsShim fileName then
                 try
                     use fileStream = FileSystem.OpenFileForReadShim(fileName)
                     fileContentDict[fileName] <- fileStream.ReadAllText()
                 with _ ->
                     ()
+                    
+    let setFileContent (fileName: string) (fileContent: string) =
+        fileContentDict[fileName] <- fileContent
 
     let private seperators = [| '\r'; '\n' |]
 
@@ -611,7 +616,7 @@ module internal FileContent =
                 idx
 
     /// Get the substring of the given range.
-    /// This can retain the line seperators in the source string, whilst `FSharp.Compiler.Text.StringText.GetSubTextFromRange` does not.
+    /// This can retain the line seperators in the source string.
     let substring (input: string) (range: range) =
         let startLine, startCol = range.StartLine, range.StartColumn
         let endLine, endCol = range.EndLine, range.EndColumn
diff --git a/src/Compiler/Utilities/range.fsi b/src/Compiler/Utilities/range.fsi
index 48620a9ceb4..7ccf4a5e9d9 100755
--- a/src/Compiler/Utilities/range.fsi
+++ b/src/Compiler/Utilities/range.fsi
@@ -277,6 +277,11 @@ module internal FileContent =
     /// Used by `getCodeText` to support `CallerArgumentExpression`
     val readFileContents: fileNames: string list -> unit
     
+    /// Save the file content.
+    val setFileContent: fileName: string -> fileContent: string -> unit
+    
+    /// Get the substring of the given range.
+    /// This can retain the line seperators in the source string.
     val substring: input: string -> range: range -> string    
         
     type DefaultGetRangeText =
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
index 788172600b6..cc7e6de85df 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
@@ -163,9 +163,10 @@ assertEqual (A.B("abc")) "\"abc\""
           FSharp """module Lib
 let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
 open System.Runtime.CompilerServices
+open System.Runtime.InteropServices
 
 type A() =
-  static member B (``ab c``, [<CallerArgumentExpression "ab c">]?n) =
+  static member B (``ab c``, [<CallerArgumentExpression "ab c"; Optional; DefaultParameterValue "no value">]n: string) =
     defaultArg n "no value"
         """ 
           |> withLangVersionPreview
diff --git a/tests/FSharp.Compiler.Service.Tests/FileContentTests.fs b/tests/FSharp.Compiler.Service.Tests/FileContentTests.fs
index eba6e1ac633..d257c153567 100644
--- a/tests/FSharp.Compiler.Service.Tests/FileContentTests.fs
+++ b/tests/FSharp.Compiler.Service.Tests/FileContentTests.fs
@@ -18,7 +18,7 @@ let ``substring tests`` () =
     substring "Hello, world!\r\nThis is a test.\r\ntest\n" (1, 7) (9, 4) |> shouldEqual "world!\r\nThis is a test.\r\ntest\n"
     substring "Hello, world!\r\nThis is a test.\r\n" (1, 7) (2, 100) |> shouldEqual "world!\r\nThis is a test.\r\n"
     substring "Hello, world!\r\nThis is a test.\r\n" (1, 7) (2, 7) |> shouldEqual "world!\r\nThis is"
-    substring "Hello, world! This is a test.\r\na test" (2, 1) (2, 6) |> shouldEqual "test"
+    substring "Hello, world! This is a test.\r\na test" (2, 1) (2, 6) |> shouldEqual " test"
     substring "Hello, world! This is a test.\r\na test" (2, 7) (2, 8) |> shouldEqual ""
     
     substring "Hello, world!\r\nThis is a test.\r\n" (1, 0) (1, 4) |> shouldEqual "Hell"

From 1cc439572896529aebfc44e6cf6c18f3bed37e10 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Fri, 21 Mar 2025 14:26:28 +0800
Subject: [PATCH 48/57] refractor

---
 src/Compiler/Driver/ParseAndCheckInputs.fs    | 36 +++++++++++--------
 src/Compiler/Driver/ScriptClosure.fs          |  2 --
 src/Compiler/Driver/fsc.fs                    | 10 ++++++
 src/Compiler/Interactive/fsi.fs               | 12 ++++++-
 src/Compiler/Utilities/range.fs               | 20 ++++-------
 src/Compiler/Utilities/range.fsi              | 15 +++-----
 .../CallerArgumentExpression.fs               |  2 +-
 7 files changed, 55 insertions(+), 42 deletions(-)

diff --git a/src/Compiler/Driver/ParseAndCheckInputs.fs b/src/Compiler/Driver/ParseAndCheckInputs.fs
index 83b2f53ea3a..975bfeef66f 100644
--- a/src/Compiler/Driver/ParseAndCheckInputs.fs
+++ b/src/Compiler/Driver/ParseAndCheckInputs.fs
@@ -702,44 +702,52 @@ let checkInputFile (tcConfig: TcConfig) fileName =
     else
         error (Error(FSComp.SR.buildInvalidSourceFileExtension (SanitizeFileName fileName tcConfig.implicitIncludeDir), rangeStartup))
 
-let parseInputSourceTextAux
+let parseInputStreamAux
     (
         tcConfig: TcConfig,
         lexResourceManager,
         fileName,
         isLastCompiland,
         diagnosticsLogger,
-        sourceText: ISourceText
+        retryLocked,
+        stream: Stream
     ) =
-    if FSharpImplFileSuffixes |> List.exists (FileSystemUtils.checkSuffix fileName) then
-        FSharp.Compiler.Text.FileContent.setFileContent fileName (sourceText.GetSubTextString(0, sourceText.Length))
-    
+    use reader = stream.GetReader(tcConfig.inputCodePage, retryLocked)
+
     // Set up the LexBuffer for the file
     let lexbuf =
-        UnicodeLexing.SourceTextAsLexbuf(not tcConfig.compilingFSharpCore, tcConfig.langVersion, tcConfig.strictIndentation, sourceText)
+        UnicodeLexing.StreamReaderAsLexbuf(not tcConfig.compilingFSharpCore, tcConfig.langVersion, tcConfig.strictIndentation, reader)
 
     // Parse the file drawing tokens from the lexbuf
     ParseOneInputLexbuf(tcConfig, lexResourceManager, lexbuf, fileName, isLastCompiland, diagnosticsLogger)
 
-let parseInputStreamAux
+let parseInputSourceTextAux
     (
         tcConfig: TcConfig,
         lexResourceManager,
         fileName,
         isLastCompiland,
         diagnosticsLogger,
-        retryLocked,
-        stream: Stream
+        sourceText: ISourceText
     ) =
-    use reader = stream.GetReader(tcConfig.inputCodePage, retryLocked)
-    let text = reader.ReadToEnd()
-    let sourceText = SourceText.ofString text
-    parseInputSourceTextAux (tcConfig, lexResourceManager, fileName, isLastCompiland, diagnosticsLogger, sourceText)
+    // Set up the LexBuffer for the file
+    let lexbuf =
+        UnicodeLexing.SourceTextAsLexbuf(not tcConfig.compilingFSharpCore, tcConfig.langVersion, tcConfig.strictIndentation, sourceText)
+
+    // Parse the file drawing tokens from the lexbuf
+    ParseOneInputLexbuf(tcConfig, lexResourceManager, lexbuf, fileName, isLastCompiland, diagnosticsLogger)
 
 let parseInputFileAux (tcConfig: TcConfig, lexResourceManager, fileName, isLastCompiland, diagnosticsLogger, retryLocked) =
     // Get a stream reader for the file
     use fileStream = FileSystem.OpenFileForReadShim(fileName)
-    parseInputStreamAux (tcConfig, lexResourceManager, fileName, isLastCompiland, diagnosticsLogger, retryLocked, fileStream)
+    use reader = fileStream.GetReader(tcConfig.inputCodePage, retryLocked)
+
+    // Set up the LexBuffer for the file
+    let lexbuf =
+        UnicodeLexing.StreamReaderAsLexbuf(not tcConfig.compilingFSharpCore, tcConfig.langVersion, tcConfig.strictIndentation, reader)
+
+    // Parse the file drawing tokens from the lexbuf
+    ParseOneInputLexbuf(tcConfig, lexResourceManager, lexbuf, fileName, isLastCompiland, diagnosticsLogger)
 
 /// Parse an input from stream
 let ParseOneInputStream
diff --git a/src/Compiler/Driver/ScriptClosure.fs b/src/Compiler/Driver/ScriptClosure.fs
index c72975733cf..0e22231abb8 100644
--- a/src/Compiler/Driver/ScriptClosure.fs
+++ b/src/Compiler/Driver/ScriptClosure.fs
@@ -134,8 +134,6 @@ module ScriptPreprocessClosure =
         tcConfigB.conditionalDefines <- defines @ tcConfig.conditionalDefines
         let tcConfig = TcConfig.Create(tcConfigB, false)
 
-        FSharp.Compiler.Text.FileContent.setFileContent fileName (sourceText.GetSubTextString(0, sourceText.Length))
-
         let lexbuf =
             UnicodeLexing.SourceTextAsLexbuf(true, tcConfig.langVersion, tcConfig.strictIndentation, sourceText)
 
diff --git a/src/Compiler/Driver/fsc.fs b/src/Compiler/Driver/fsc.fs
index 0e26f2db4ac..face9d4d397 100644
--- a/src/Compiler/Driver/fsc.fs
+++ b/src/Compiler/Driver/fsc.fs
@@ -683,6 +683,16 @@ let main1
     // Build the initial type checking environment
     ReportTime tcConfig "Typecheck"
 
+    // Read the source file content for the `CallerArgumentExpression` feature
+    for fileName in sourceFiles do
+        if FSharpImplFileSuffixes |> List.exists (FileSystemUtils.checkSuffix fileName) then
+            try
+                use fileStream = FileSystem.OpenFileForReadShim fileName
+                use reader = fileStream.GetReader(tcConfig.inputCodePage)
+                FileContent.update fileName (reader.ReadToEnd())
+            with _ ->
+                ()
+
     use unwindParsePhase = UseBuildPhase BuildPhase.TypeCheck
 
     let tcEnv0, openDecls0 =
diff --git a/src/Compiler/Interactive/fsi.fs b/src/Compiler/Interactive/fsi.fs
index 32c1e12eaaa..1983de07dec 100644
--- a/src/Compiler/Interactive/fsi.fs
+++ b/src/Compiler/Interactive/fsi.fs
@@ -2916,6 +2916,16 @@ type internal FsiDynamicCompiler
 
             let istate = fsiDynamicCompiler.ProcessDelayedReferences(ctok, istate)
 
+            // Read the source file content for the `CallerArgumentExpression` feature
+            for fileName in sourceFiles do
+                if FSharpImplFileSuffixes |> List.exists (FileSystemUtils.checkSuffix fileName) then
+                    try
+                        use fileStream = FileSystem.OpenFileForReadShim fileName
+                        use reader = fileStream.GetReader(tcConfig.inputCodePage)
+                        FileContent.update fileName (reader.ReadToEnd())
+                    with _ ->
+                        ()
+
             fsiDynamicCompiler.EvalParsedSourceFiles(ctok, diagnosticsLogger, istate, inputs, m)
 
     member _.GetBoundValues istate =
@@ -4676,7 +4686,7 @@ type FsiEvaluationSession
             fsiConsolePrompt.PrintAhead()
 
     do
-        FileContent.getRangeTextDynamic <-
+        FileContent.updateGetRangeTextDynamic
             { new FileContent.DefaultGetRangeText() with
                 override _.GetRangeText(range) : string =
                     if range.FileName = stdinMockFileName then
diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs
index 4ff1fe85b55..223baa13f84 100755
--- a/src/Compiler/Utilities/range.fs
+++ b/src/Compiler/Utilities/range.fs
@@ -585,18 +585,7 @@ module Range =
 module internal FileContent =
     let private fileContentDict = ConcurrentDictionary<string, string>()
 
-    let readFileContents (fileNames: string list) =
-        for fileName in fileNames do
-        // if FSharpImplFileSuffixes |> List.exists (FileSystemUtils.checkSuffix fileName) then
-        
-            if FileSystem.FileExistsShim fileName then
-                try
-                    use fileStream = FileSystem.OpenFileForReadShim(fileName)
-                    fileContentDict[fileName] <- fileStream.ReadAllText()
-                with _ ->
-                    ()
-                    
-    let setFileContent (fileName: string) (fileContent: string) =
+    let update (fileName: string) (fileContent: string) =
         fileContentDict[fileName] <- fileContent
 
     let private seperators = [| '\r'; '\n' |]
@@ -689,6 +678,11 @@ module internal FileContent =
             | true, text -> substring text range
             | _ -> String.Empty
 
-    let mutable getRangeTextDynamic = DefaultGetRangeText()
+    /// Get the code text of the specific `range` from already read files.
+    /// This is mutable because it may be replace by a reader that can access the `stdin` file in the `fsi.exe`.
+    let mutable private getRangeTextDynamic = DefaultGetRangeText()
+    
+    let updateGetRangeTextDynamic (getter: #DefaultGetRangeText) =
+        getRangeTextDynamic <- getter
 
     let getCodeText (m: range) = getRangeTextDynamic.GetRangeText(m)
diff --git a/src/Compiler/Utilities/range.fsi b/src/Compiler/Utilities/range.fsi
index 7ccf4a5e9d9..b7aa99f4032 100755
--- a/src/Compiler/Utilities/range.fsi
+++ b/src/Compiler/Utilities/range.fsi
@@ -272,13 +272,8 @@ module Line =
 /// Store code file content. Used to implement `CallerArgumentExpression`
 module internal FileContent =
 
-    /// Read all file contents.
-    ///
-    /// Used by `getCodeText` to support `CallerArgumentExpression`
-    val readFileContents: fileNames: string list -> unit
-    
-    /// Save the file content.
-    val setFileContent: fileName: string -> fileContent: string -> unit
+    /// Update the file content.
+    val update: fileName: string -> fileContent: string -> unit
     
     /// Get the substring of the given range.
     /// This can retain the line seperators in the source string.
@@ -289,10 +284,8 @@ module internal FileContent =
         abstract GetRangeText: range: range -> string
         override GetRangeText: range: range -> string
 
-    /// Get the code text of the specific `range` from already read files.
-    ///
-    /// Used by `getCodeText` to support `CallerArgumentExpression`
-    val mutable getRangeTextDynamic: DefaultGetRangeText
+    /// Update the function to get the code text of the specific `range`
+    val updateGetRangeTextDynamic: getter: #DefaultGetRangeText -> unit
 
     /// Get the code text of the specific `range`
     val getCodeText: range -> string
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
index cc7e6de85df..b7ab3df29de 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
@@ -167,7 +167,7 @@ open System.Runtime.InteropServices
 
 type A() =
   static member B (``ab c``, [<CallerArgumentExpression "ab c"; Optional; DefaultParameterValue "no value">]n: string) =
-    defaultArg n "no value"
+    n
         """ 
           |> withLangVersionPreview
 

From 3c1deb4e79973c25d79215081d7c501d01fa30bd Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Fri, 21 Mar 2025 15:17:09 +0800
Subject: [PATCH 49/57] new test

---
 src/Compiler/Utilities/range.fs               |  5 +-
 .../CallerArgumentExpression.fs               | 87 ++++++++++++++-----
 2 files changed, 66 insertions(+), 26 deletions(-)

diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs
index 223baa13f84..dbd0ec3d138 100755
--- a/src/Compiler/Utilities/range.fs
+++ b/src/Compiler/Utilities/range.fs
@@ -681,8 +681,7 @@ module internal FileContent =
     /// Get the code text of the specific `range` from already read files.
     /// This is mutable because it may be replace by a reader that can access the `stdin` file in the `fsi.exe`.
     let mutable private getRangeTextDynamic = DefaultGetRangeText()
-    
-    let updateGetRangeTextDynamic (getter: #DefaultGetRangeText) =
-        getRangeTextDynamic <- getter
+
+    let updateGetRangeTextDynamic (getter: #DefaultGetRangeText) = getRangeTextDynamic <- getter
 
     let getCodeText (m: range) = getRangeTextDynamic.GetRangeText(m)
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
index b7ab3df29de..ecc30dd7ab8 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
@@ -157,28 +157,6 @@ assertEqual (A.B("abc")) "\"abc\""
         |> shouldSucceed
         |> ignore
         
-    [<FactForNETCOREAPP>]
-    let ``C# can consume methods using CallerArgumentExpression receiving special parameter names`` () =
-        let fs =
-          FSharp """module Lib
-let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
-open System.Runtime.CompilerServices
-open System.Runtime.InteropServices
-
-type A() =
-  static member B (``ab c``, [<CallerArgumentExpression "ab c"; Optional; DefaultParameterValue "no value">]n: string) =
-    n
-        """ 
-          |> withLangVersionPreview
-
-        CSharp """Lib.assertEqual(Lib.A.B("abc"), "\"abc\"");"""
-        |> withName "CSLib"
-        |> withReferences [fs]
-        |> asExe
-        |> compileAndRun
-        |> shouldSucceed
-        |> ignore
-        
     [<FactForNETCOREAPP>]
     let ``test Warns when cannot find the referenced parameter or self-referential`` () =
       FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
@@ -335,4 +313,67 @@ type Interface1 =
         |> compileAndRun
         |> shouldSucceed
         |> ignore
-      
\ No newline at end of file
+      
+    (* ------------ C# Interop tests ------------- *)
+    [<FactForNETCOREAPP>]
+    let ``C# can consume methods using CallerArgumentExpression receiving special parameter names`` () =
+        let fs =
+          FSharp """module Lib
+let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
+open System.Runtime.CompilerServices
+open System.Runtime.InteropServices
+
+type A() =
+  static member B (``ab c``, [<CallerArgumentExpression "ab c"; Optional; DefaultParameterValue "no value">]n: string) =
+    n
+        """ 
+          |> withLangVersionPreview
+
+        CSharp """Lib.assertEqual(Lib.A.B("abc"), "\"abc\"");"""
+        |> withName "CSLib"
+        |> withReferences [fs]
+        |> asExe
+        |> compileAndRun
+        |> shouldSucceed
+        |> ignore
+        
+    [<FactForDESKTOP>]
+    let ``Can recognize CallerArgumentExpression defined in C#`` () =
+        let cs =
+          CSharp """using System.Runtime.CompilerServices;
+public class AInCs
+{
+    static string B(int param, [CallerArgumentExpression("param")] string expr = null) => expr;
+}
+
+namespace System.Runtime.CompilerServices
+{
+    [AttributeUsage(AttributeTargets.Parameter)]
+    sealed class CallerArgumentExpressionAttribute : Attribute
+    {
+        public CallerArgumentExpressionAttribute(string param)
+        {
+            Param = param;
+        }
+
+        public string Param { get; }
+    }
+}
+""" |> withName "CSLib"
+
+        FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
+open System.Runtime.CompilerServices
+
+type A() =
+  static member B (``ab c``, [<CallerArgumentExpression "ab c">]?n) =
+    defaultArg n "no value"
+
+A.B "abc" |> assertEqual "\"abc\""
+AInCs.B (123 - 7) |> assertEqual "123 - 7"
+      """ 
+        |> withLangVersionPreview
+        |> withReferences [cs]
+        |> asExe
+        |> compileAndRun
+        |> shouldSucceed
+        |> ignore
\ No newline at end of file

From a5a4b8bf098d10a8c07a400cbacc753f0f87ba55 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Tue, 25 Mar 2025 12:48:59 +0800
Subject: [PATCH 50/57] refactor

---
 src/Compiler/Driver/CompilerConfig.fs         | 11 +++++
 src/Compiler/Driver/CompilerConfig.fsi        |  3 ++
 src/Compiler/Driver/fsc.fs                    |  9 +---
 src/Compiler/Interactive/fsi.fs               | 34 +++++++--------
 src/Compiler/Utilities/range.fs               | 21 +++-------
 src/Compiler/Utilities/range.fsi              |  8 ----
 .../CallerArgumentExpression.fs               | 42 +++++++++++++++----
 7 files changed, 69 insertions(+), 59 deletions(-)

diff --git a/src/Compiler/Driver/CompilerConfig.fs b/src/Compiler/Driver/CompilerConfig.fs
index cf875be4959..0ade9568664 100644
--- a/src/Compiler/Driver/CompilerConfig.fs
+++ b/src/Compiler/Driver/CompilerConfig.fs
@@ -1539,3 +1539,14 @@ type TcConfigProvider =
         TcConfigProvider(fun _ctok -> TcConfig.Create(tcConfigB, validate = false))
 
 let GetFSharpCoreLibraryName () = getFSharpCoreLibraryName
+
+/// Read and store the source file content for the `CallerArgumentExpression` feature
+let readAndStoreFileContents (tcConfig: TcConfig) (sourceFiles: #seq<string>) =
+    for fileName in sourceFiles do
+        if FSharpImplFileSuffixes |> List.exists (FileSystemUtils.checkSuffix fileName) then
+            try
+                use fileStream = FileSystem.OpenFileForReadShim fileName
+                use reader = fileStream.GetReader(tcConfig.inputCodePage)
+                FileContent.update fileName (reader.ReadToEnd())
+            with _ ->
+                ()
diff --git a/src/Compiler/Driver/CompilerConfig.fsi b/src/Compiler/Driver/CompilerConfig.fsi
index 0e6c25727f8..f0efcbcefd4 100644
--- a/src/Compiler/Driver/CompilerConfig.fsi
+++ b/src/Compiler/Driver/CompilerConfig.fsi
@@ -961,3 +961,6 @@ val FSharpMLCompatFileSuffixes: string list
 
 /// Indicates whether experimental features should be enabled automatically
 val FSharpExperimentalFeaturesEnabledAutomatically: bool
+
+/// Read and store the source file content for the `CallerArgumentExpression` feature
+val readAndStoreFileContents: tcConfig: TcConfig -> sourceFiles: #seq<string> -> unit
diff --git a/src/Compiler/Driver/fsc.fs b/src/Compiler/Driver/fsc.fs
index face9d4d397..abf42822d98 100644
--- a/src/Compiler/Driver/fsc.fs
+++ b/src/Compiler/Driver/fsc.fs
@@ -684,14 +684,7 @@ let main1
     ReportTime tcConfig "Typecheck"
 
     // Read the source file content for the `CallerArgumentExpression` feature
-    for fileName in sourceFiles do
-        if FSharpImplFileSuffixes |> List.exists (FileSystemUtils.checkSuffix fileName) then
-            try
-                use fileStream = FileSystem.OpenFileForReadShim fileName
-                use reader = fileStream.GetReader(tcConfig.inputCodePage)
-                FileContent.update fileName (reader.ReadToEnd())
-            with _ ->
-                ()
+    readAndStoreFileContents tcConfig sourceFiles
 
     use unwindParsePhase = UseBuildPhase BuildPhase.TypeCheck
 
diff --git a/src/Compiler/Interactive/fsi.fs b/src/Compiler/Interactive/fsi.fs
index 1983de07dec..54dda3307c4 100644
--- a/src/Compiler/Interactive/fsi.fs
+++ b/src/Compiler/Interactive/fsi.fs
@@ -2917,14 +2917,7 @@ type internal FsiDynamicCompiler
             let istate = fsiDynamicCompiler.ProcessDelayedReferences(ctok, istate)
 
             // Read the source file content for the `CallerArgumentExpression` feature
-            for fileName in sourceFiles do
-                if FSharpImplFileSuffixes |> List.exists (FileSystemUtils.checkSuffix fileName) then
-                    try
-                        use fileStream = FileSystem.OpenFileForReadShim fileName
-                        use reader = fileStream.GetReader(tcConfig.inputCodePage)
-                        FileContent.update fileName (reader.ReadToEnd())
-                    with _ ->
-                        ()
+            readAndStoreFileContents tcConfig sourceFiles
 
             fsiDynamicCompiler.EvalParsedSourceFiles(ctok, diagnosticsLogger, istate, inputs, m)
 
@@ -3538,7 +3531,10 @@ type FsiStdinLexerProvider
                 |> Option.iter (fun t ->
                     match t with
                     | Null -> ()
-                    | NonNull t -> fsiStdinSyphon.Add(t + "\n"))
+                    | NonNull t -> 
+                        fsiStdinSyphon.Add(t + "\n")
+                        // Update the stdin file content for the `CallerArgumentExpression` feature
+                        FileContent.update stdinMockFileName fsiStdinSyphon.SyphonText)
 
                 match inputOption with
                 | Some Null
@@ -4235,6 +4231,9 @@ type FsiInteractionProcessor
 
                 ProcessStepStatus status None (fun _ istate -> run istate)
 
+            // Read the source file content for the `CallerArgumentExpression` feature
+            readAndStoreFileContents tcConfig [sourceFile]
+            
             run istate)
 
     /// Load the source files, one by one. Called on the main thread.
@@ -4312,6 +4311,10 @@ type FsiInteractionProcessor
         currState
         |> InteractiveCatch diagnosticsLogger (fun istate ->
             let expr = ParseInteraction tokenizer
+            
+            // Update the file content for the `CallerArgumentExpression` feature
+            FileContent.update scriptFileName sourceText
+            
             ExecuteParsedInteractionOnMainThread(ctok, diagnosticsLogger, expr, istate, cancellationToken))
         |> commitResult
 
@@ -4345,6 +4348,9 @@ type FsiInteractionProcessor
                     m,
                     SynExprSequentialTrivia.Zero
                 )
+            
+            // Update the file content for the `CallerArgumentExpression` feature
+            FileContent.update scriptFileName sourceText
 
             ExecuteParsedExpressionOnMainThread(ctok, diagnosticsLogger, exprWithSeq, istate))
         |> commitResult
@@ -4685,16 +4691,6 @@ type FsiEvaluationSession
         if List.isEmpty fsiOptions.SourceFiles then
             fsiConsolePrompt.PrintAhead()
 
-    do
-        FileContent.updateGetRangeTextDynamic
-            { new FileContent.DefaultGetRangeText() with
-                override _.GetRangeText(range) : string =
-                    if range.FileName = stdinMockFileName then
-                        FileContent.substring fsiStdinSyphon.SyphonText range
-                    else
-                        base.GetRangeText(range)
-            }
-
     let fsiConsoleInput = FsiConsoleInput(fsi, fsiOptions, inReader, outWriter)
 
     /// The single, global interactive checker that can be safely used in conjunction with other operations
diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs
index dbd0ec3d138..df5e952abdd 100755
--- a/src/Compiler/Utilities/range.fs
+++ b/src/Compiler/Utilities/range.fs
@@ -586,7 +586,7 @@ module internal FileContent =
     let private fileContentDict = ConcurrentDictionary<string, string>()
 
     let update (fileName: string) (fileContent: string) =
-        fileContentDict[fileName] <- fileContent
+        fileContentDict.AddOrUpdate(fileName, (fun _ -> fileContent), (fun _ _ -> fileContent)) |> ignore
 
     let private seperators = [| '\r'; '\n' |]
 
@@ -670,18 +670,7 @@ module internal FileContent =
 
             loopStart 1 (0, findLineEnd input 0)
 
-    type DefaultGetRangeText() =
-        abstract GetRangeText: range: range -> string
-
-        default _.GetRangeText(range: range) : string =
-            match fileContentDict.TryGetValue range.FileName with
-            | true, text -> substring text range
-            | _ -> String.Empty
-
-    /// Get the code text of the specific `range` from already read files.
-    /// This is mutable because it may be replace by a reader that can access the `stdin` file in the `fsi.exe`.
-    let mutable private getRangeTextDynamic = DefaultGetRangeText()
-
-    let updateGetRangeTextDynamic (getter: #DefaultGetRangeText) = getRangeTextDynamic <- getter
-
-    let getCodeText (m: range) = getRangeTextDynamic.GetRangeText(m)
+    let getCodeText (m: range) = 
+        match fileContentDict.TryGetValue m.FileName with
+        | true, text -> substring text m
+        | _ -> String.Empty
diff --git a/src/Compiler/Utilities/range.fsi b/src/Compiler/Utilities/range.fsi
index b7aa99f4032..ea2040459f2 100755
--- a/src/Compiler/Utilities/range.fsi
+++ b/src/Compiler/Utilities/range.fsi
@@ -278,14 +278,6 @@ module internal FileContent =
     /// Get the substring of the given range.
     /// This can retain the line seperators in the source string.
     val substring: input: string -> range: range -> string    
-        
-    type DefaultGetRangeText =
-        new: unit -> DefaultGetRangeText
-        abstract GetRangeText: range: range -> string
-        override GetRangeText: range: range -> string
-
-    /// Update the function to get the code text of the specific `range`
-    val updateGetRangeTextDynamic: getter: #DefaultGetRangeText -> unit
 
     /// Get the code text of the specific `range`
     val getCodeText: range -> string
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
index ecc30dd7ab8..56cbd5a7d30 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
@@ -339,8 +339,8 @@ type A() =
         
     [<FactForDESKTOP>]
     let ``Can recognize CallerArgumentExpression defined in C#`` () =
-        let cs =
-          CSharp """using System.Runtime.CompilerServices;
+      let cs =
+        CSharp """using System.Runtime.CompilerServices;
 public class AInCs
 {
     static string B(int param, [CallerArgumentExpression("param")] string expr = null) => expr;
@@ -359,9 +359,10 @@ namespace System.Runtime.CompilerServices
         public string Param { get; }
     }
 }
-""" |> withName "CSLib"
+"""
+        |> withName "CSLib"
 
-        FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
+      FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
 open System.Runtime.CompilerServices
 
 type A() =
@@ -371,9 +372,34 @@ type A() =
 A.B "abc" |> assertEqual "\"abc\""
 AInCs.B (123 - 7) |> assertEqual "123 - 7"
       """ 
+      |> withLangVersionPreview
+      |> withReferences [cs]
+      |> asExe
+      |> compileAndRun
+      |> shouldSucceed
+      |> ignore
+      
+    [<FactForNETCOREAPP>]
+    let ``Check in fsi`` () =
+        Fsx """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
+try System.ArgumentException.ThrowIfNullOrWhiteSpace(Seq.init 50 (fun _ -> " ")
+  (* comment *) 
+  |> String.concat " ")
+with :? System.ArgumentException as ex -> 
+  assertEqual true (ex.Message.Contains("(Parameter 'Seq.init 50 (fun _ -> \" \")
+  (* comment *) 
+  |> String.concat \" \""))
+  
+
+try System.ArgumentException.ThrowIfNullOrWhiteSpace(argument = (Seq.init 11 (fun _ -> " ")
+  (* comment *) 
+  |> String.concat " "))
+with :? System.ArgumentException as ex -> 
+  assertEqual true (ex.Message.Contains("(Parameter '(Seq.init 11 (fun _ -> \" \")
+  (* comment *) 
+  |> String.concat \" \")"))
+"""
         |> withLangVersionPreview
-        |> withReferences [cs]
-        |> asExe
-        |> compileAndRun
+        |> runFsi
         |> shouldSucceed
-        |> ignore
\ No newline at end of file
+        |> ignore

From 5cba8ca79601869ba5b4242fbc4c62ad357a72ec Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Tue, 25 Mar 2025 12:51:53 +0800
Subject: [PATCH 51/57] fmt

---
 src/Compiler/Interactive/fsi.fs | 12 ++++++------
 src/Compiler/Utilities/range.fs |  5 +++--
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/src/Compiler/Interactive/fsi.fs b/src/Compiler/Interactive/fsi.fs
index 54dda3307c4..3723a81634a 100644
--- a/src/Compiler/Interactive/fsi.fs
+++ b/src/Compiler/Interactive/fsi.fs
@@ -3531,7 +3531,7 @@ type FsiStdinLexerProvider
                 |> Option.iter (fun t ->
                     match t with
                     | Null -> ()
-                    | NonNull t -> 
+                    | NonNull t ->
                         fsiStdinSyphon.Add(t + "\n")
                         // Update the stdin file content for the `CallerArgumentExpression` feature
                         FileContent.update stdinMockFileName fsiStdinSyphon.SyphonText)
@@ -4232,8 +4232,8 @@ type FsiInteractionProcessor
                 ProcessStepStatus status None (fun _ istate -> run istate)
 
             // Read the source file content for the `CallerArgumentExpression` feature
-            readAndStoreFileContents tcConfig [sourceFile]
-            
+            readAndStoreFileContents tcConfig [ sourceFile ]
+
             run istate)
 
     /// Load the source files, one by one. Called on the main thread.
@@ -4311,10 +4311,10 @@ type FsiInteractionProcessor
         currState
         |> InteractiveCatch diagnosticsLogger (fun istate ->
             let expr = ParseInteraction tokenizer
-            
+
             // Update the file content for the `CallerArgumentExpression` feature
             FileContent.update scriptFileName sourceText
-            
+
             ExecuteParsedInteractionOnMainThread(ctok, diagnosticsLogger, expr, istate, cancellationToken))
         |> commitResult
 
@@ -4348,7 +4348,7 @@ type FsiInteractionProcessor
                     m,
                     SynExprSequentialTrivia.Zero
                 )
-            
+
             // Update the file content for the `CallerArgumentExpression` feature
             FileContent.update scriptFileName sourceText
 
diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs
index df5e952abdd..20b39f73fcb 100755
--- a/src/Compiler/Utilities/range.fs
+++ b/src/Compiler/Utilities/range.fs
@@ -586,7 +586,8 @@ module internal FileContent =
     let private fileContentDict = ConcurrentDictionary<string, string>()
 
     let update (fileName: string) (fileContent: string) =
-        fileContentDict.AddOrUpdate(fileName, (fun _ -> fileContent), (fun _ _ -> fileContent)) |> ignore
+        fileContentDict.AddOrUpdate(fileName, (fun _ -> fileContent), (fun _ _ -> fileContent))
+        |> ignore
 
     let private seperators = [| '\r'; '\n' |]
 
@@ -670,7 +671,7 @@ module internal FileContent =
 
             loopStart 1 (0, findLineEnd input 0)
 
-    let getCodeText (m: range) = 
+    let getCodeText (m: range) =
         match fileContentDict.TryGetValue m.FileName with
         | true, text -> substring text m
         | _ -> String.Empty

From 12588164b2572599e33f44141cbd6c7f24b0aa6c Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Tue, 25 Mar 2025 14:24:14 +0800
Subject: [PATCH 52/57] baseline; fix test

---
 .../CustomAttributes/CallerArgumentExpression.fs       |  1 -
 ...piler.Service.SurfaceArea.netstandard20.release.bsl |  5 -----
 .../ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl  |  7 ++++---
 ...fy_FSharp.Compiler.Service_Debug_netstandard2.0.bsl |  8 ++++----
 ...ilverify_FSharp.Compiler.Service_Release_net9.0.bsl |  7 ++++---
 ..._FSharp.Compiler.Service_Release_netstandard2.0.bsl |  8 ++++----
 vsintegration/src/FSharp.Editor/Common/Extensions.fs   | 10 ++--------
 7 files changed, 18 insertions(+), 28 deletions(-)

diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
index 56cbd5a7d30..bcb031f6cea 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
@@ -360,7 +360,6 @@ namespace System.Runtime.CompilerServices
     }
 }
 """
-        |> withName "CSLib"
 
       FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
 open System.Runtime.CompilerServices
diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl
index 435ce2e5bbb..f89f7a406be 100644
--- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl
+++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl
@@ -10893,9 +10893,7 @@ FSharp.Compiler.Text.PositionModule: System.String stringOfPos(FSharp.Compiler.T
 FSharp.Compiler.Text.PositionModule: System.Tuple`2[System.Int32,System.Int32] toZ(FSharp.Compiler.Text.Position)
 FSharp.Compiler.Text.PositionModule: Void outputPos(System.IO.TextWriter, FSharp.Compiler.Text.Position)
 FSharp.Compiler.Text.Range: Boolean Equals(System.Object)
-FSharp.Compiler.Text.Range: Boolean HasOriginalRange
 FSharp.Compiler.Text.Range: Boolean IsSynthetic
-FSharp.Compiler.Text.Range: Boolean get_HasOriginalRange()
 FSharp.Compiler.Text.Range: Boolean get_IsSynthetic()
 FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Position End
 FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Position Start
@@ -10903,7 +10901,6 @@ FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Position get_End()
 FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Position get_Start()
 FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Range EndRange
 FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Range StartRange
-FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Range WithOriginalRange(Microsoft.FSharp.Core.FSharpValueOption`1[FSharp.Compiler.Text.Range])
 FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Range Zero
 FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Range get_EndRange()
 FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Range get_StartRange()
@@ -10917,8 +10914,6 @@ FSharp.Compiler.Text.Range: Int32 get_EndColumn()
 FSharp.Compiler.Text.Range: Int32 get_EndLine()
 FSharp.Compiler.Text.Range: Int32 get_StartColumn()
 FSharp.Compiler.Text.Range: Int32 get_StartLine()
-FSharp.Compiler.Text.Range: Microsoft.FSharp.Core.FSharpValueOption`1[FSharp.Compiler.Text.Range] OriginalRange
-FSharp.Compiler.Text.Range: Microsoft.FSharp.Core.FSharpValueOption`1[FSharp.Compiler.Text.Range] get_OriginalRange()
 FSharp.Compiler.Text.Range: System.String FileName
 FSharp.Compiler.Text.Range: System.String ToString()
 FSharp.Compiler.Text.Range: System.String get_FileName()
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl
index a8802cc39da..0d83584b688 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl
@@ -5,7 +5,6 @@
 [IL]: Error [UnmanagedPointer]: : FSharp.Compiler.IO.RawByteMemory::.ctor(uint8*, int32, object)][offset 0x00000009] Unmanaged pointers are not a verifiable type.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::get_Item(int32)][offset 0x0000001E][found Native Int] Expected ByRef on the stack.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::set_Item(int32, uint8)][offset 0x00000025][found Native Int] Expected ByRef on the stack.
-[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.Range::ToString()][offset 0x00000021] Callvirt on a value type method.
 [IL]: Error [ReturnPtrToStack]: : Internal.Utilities.Text.Lexing.LexBuffer`1::get_LexemeView()][offset 0x00000019] Return type is ByRef, TypedReference, ArgHandle, or ArgIterator.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.Text.Lexing.UnicodeTables::scanUntilSentinel([FSharp.Compiler.Service]Internal.Utilities.Text.Lexing.LexBuffer`1<char>, int32)][offset 0x00000079][found Short] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Xml.XmlDoc::processLines([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>)][offset 0x00000031][found Char] Unexpected type on the stack.
@@ -22,7 +21,7 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x00000082][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3502-805::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001E5][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3508-805::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001FE][found Char] Unexpected type on the stack.
 [IL]: Error [UnmanagedPointer]: : FSharp.Compiler.Interactive.Shell+Utilities+pointerToNativeInt@110::Invoke(object)][offset 0x00000007] Unmanaged pointers are not a verifiable type.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharpCheckerResults+dataTipOfReferences@2225::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000084][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$ServiceLexing+clo@921-509::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<FSharp.Compiler.Parser+token,int32,int32>,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack.
@@ -60,7 +59,9 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x0000000B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x00000021][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000CD][found Char] Unexpected type on the stack.
-[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@587::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@558::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
+[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Range::.cctor()][offset 0x00000216][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Range::.cctor()][offset 0x0000021F][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000037][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000043][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack.
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl
index 93475f5e442..1beb3e3ac03 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl
@@ -5,7 +5,6 @@
 [IL]: Error [UnmanagedPointer]: : FSharp.Compiler.IO.RawByteMemory::.ctor(uint8*, int32, object)][offset 0x00000009] Unmanaged pointers are not a verifiable type.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::get_Item(int32)][offset 0x0000001E][found Native Int] Expected ByRef on the stack.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::set_Item(int32, uint8)][offset 0x00000025][found Native Int] Expected ByRef on the stack.
-[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.Range::ToString()][offset 0x00000021] Callvirt on a value type method.
 [IL]: Error [ReturnPtrToStack]: : Internal.Utilities.Text.Lexing.LexBuffer`1::get_LexemeView()][offset 0x00000019] Return type is ByRef, TypedReference, ArgHandle, or ArgIterator.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.Text.Lexing.UnicodeTables::scanUntilSentinel([FSharp.Compiler.Service]Internal.Utilities.Text.Lexing.LexBuffer`1<char>, int32)][offset 0x00000079][found Short] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Xml.XmlDoc::processLines([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>)][offset 0x00000031][found Char] Unexpected type on the stack.
@@ -28,9 +27,8 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x00000082][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiStdinSyphon::GetLine(string, int32)][offset 0x00000039][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiStdinSyphon::GetLineNoPrune(string, int32)][offset 0x0000002B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3502-805::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001E5][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3508-805::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001FE][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiInteractionProcessor::CompletionsForPartialLID([FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompilerState, string)][offset 0x0000001B][found Char] Unexpected type on the stack.
 [IL]: Error [UnmanagedPointer]: : FSharp.Compiler.Interactive.Shell+Utilities+pointerToNativeInt@110::Invoke(object)][offset 0x00000007] Unmanaged pointers are not a verifiable type.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharpCheckerResults+dataTipOfReferences@2225::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000084][found Char] Unexpected type on the stack.
@@ -86,7 +84,9 @@
 [IL]: Error [StackUnexpected]: : Internal.Utilities.FSharpEnvironment+probePathForDotnetHost@316::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000028][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.SimulatedMSBuildReferenceResolver+Pipe #6 input at line 68@68::FSharp.Compiler.CodeAnalysis.ILegacyReferenceResolver.Resolve([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyResolutionEnvironment, [S.P.CoreLib]System.Tuple`2<string,string>[], string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>, string, string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>, string, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.Unit>, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<bool,Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.Unit>>>)][offset 0x0000034D][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000CD][found Char] Unexpected type on the stack.
-[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@587::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@558::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
+[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Range::.cctor()][offset 0x00000216][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Range::.cctor()][offset 0x0000021F][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000037][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000043][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack.
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl
index 150e2b326c8..e0f2977d8d3 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl
@@ -5,7 +5,6 @@
 [IL]: Error [UnmanagedPointer]: : FSharp.Compiler.IO.RawByteMemory::.ctor(uint8*, int32, object)][offset 0x00000009] Unmanaged pointers are not a verifiable type.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::get_Item(int32)][offset 0x0000001A][found Native Int] Expected ByRef on the stack.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::set_Item(int32, uint8)][offset 0x0000001B][found Native Int] Expected ByRef on the stack.
-[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.Range::ToString()][offset 0x0000001F] Callvirt on a value type method.
 [IL]: Error [ReturnPtrToStack]: : Internal.Utilities.Text.Lexing.LexBuffer`1::get_LexemeView()][offset 0x00000017] Return type is ByRef, TypedReference, ArgHandle, or ArgIterator.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.Text.Lexing.UnicodeTables::scanUntilSentinel([FSharp.Compiler.Service]Internal.Utilities.Text.Lexing.LexBuffer`1<char>, int32)][offset 0x0000008D][found Short] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Xml.XmlDoc::processLines([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>)][offset 0x0000002C][found Char] Unexpected type on the stack.
@@ -22,7 +21,7 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x00000082][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3502-849::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001C7][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3508-849::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001E5][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharpCheckerResults+GetReferenceResolutionStructuredToolTipText@2225::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000076][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$ServiceLexing+clo@921-530::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<FSharp.Compiler.Parser+token,int32,int32>,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$ServiceLexing+clo@921-530::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<FSharp.Compiler.Parser+token,int32,int32>,Microsoft.FSharp.Core.Unit>)][offset 0x0000003B][found Char] Unexpected type on the stack.
@@ -86,7 +85,9 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x0000000B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x00000021][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000B6][found Char] Unexpected type on the stack.
-[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@587::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@558::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
+[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Range::.cctor()][offset 0x000000F0][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Range::.cctor()][offset 0x000000F9][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000035][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000041][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack.
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl
index e29a2a5d30b..268dfbb233c 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl
@@ -5,7 +5,6 @@
 [IL]: Error [UnmanagedPointer]: : FSharp.Compiler.IO.RawByteMemory::.ctor(uint8*, int32, object)][offset 0x00000009] Unmanaged pointers are not a verifiable type.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::get_Item(int32)][offset 0x0000001A][found Native Int] Expected ByRef on the stack.
 [IL]: Error [StackByRef]: : FSharp.Compiler.IO.RawByteMemory::set_Item(int32, uint8)][offset 0x0000001B][found Native Int] Expected ByRef on the stack.
-[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.Range::ToString()][offset 0x0000001F] Callvirt on a value type method.
 [IL]: Error [ReturnPtrToStack]: : Internal.Utilities.Text.Lexing.LexBuffer`1::get_LexemeView()][offset 0x00000017] Return type is ByRef, TypedReference, ArgHandle, or ArgIterator.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.Text.Lexing.UnicodeTables::scanUntilSentinel([FSharp.Compiler.Service]Internal.Utilities.Text.Lexing.LexBuffer`1<char>, int32)][offset 0x0000008D][found Short] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Xml.XmlDoc::processLines([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>)][offset 0x0000002C][found Char] Unexpected type on the stack.
@@ -28,9 +27,8 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x00000082][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiStdinSyphon::GetLine(string, int32)][offset 0x00000032][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiStdinSyphon::GetLineNoPrune(string, int32)][offset 0x0000002B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3502-849::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001C7][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3508-849::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001E5][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiInteractionProcessor::CompletionsForPartialLID([FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompilerState, string)][offset 0x00000024][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharpCheckerResults+GetReferenceResolutionStructuredToolTipText@2225::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000076][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.AssemblyContent+traverseMemberFunctionAndValues@176::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue)][offset 0x0000002B][found Char] Unexpected type on the stack.
@@ -113,7 +111,9 @@
 [IL]: Error [StackUnexpected]: : Internal.Utilities.FSharpEnvironment::probePathForDotnetHost@315([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x0000002A][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.SimulatedMSBuildReferenceResolver+SimulatedMSBuildResolver@68::FSharp.Compiler.CodeAnalysis.ILegacyReferenceResolver.Resolve([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyResolutionEnvironment, [S.P.CoreLib]System.Tuple`2<string,string>[], string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>, string, string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>, string, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.Unit>, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<bool,Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.Unit>>>)][offset 0x000002F5][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000B6][found Char] Unexpected type on the stack.
-[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@587::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
+[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@558::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
+[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Range::.cctor()][offset 0x000000F0][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Range::.cctor()][offset 0x000000F9][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000035][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000041][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack.
diff --git a/vsintegration/src/FSharp.Editor/Common/Extensions.fs b/vsintegration/src/FSharp.Editor/Common/Extensions.fs
index 8cc271d4928..3483c9c583e 100644
--- a/vsintegration/src/FSharp.Editor/Common/Extensions.fs
+++ b/vsintegration/src/FSharp.Editor/Common/Extensions.fs
@@ -81,14 +81,8 @@ type TextViewEventsHandler
             |> Option.iter (fun handler -> handler (view, newline, oldline))
 
         member this.OnChangeScrollInfo
-            (
-                _view: IVsTextView,
-                _iBar: int,
-                _iMinUnit: int,
-                _iMaxUnits: int,
-                _iVisibleUnits: int,
-                _iFirstVisibleUnit: int
-            ) =
+            (_view: IVsTextView, _iBar: int, _iMinUnit: int, _iMaxUnits: int, _iVisibleUnits: int, _iFirstVisibleUnit: int)
+            =
             ()
 
         member this.OnKillFocus(view: IVsTextView) =

From 95a4930f705c06e9481e7da63a0516feae2dca1d Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Tue, 25 Mar 2025 16:10:34 +0800
Subject: [PATCH 53/57] fix test

---
 .../CustomAttributes/CallerArgumentExpression.fs              | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
index bcb031f6cea..48a083f12f5 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
@@ -343,13 +343,13 @@ type A() =
         CSharp """using System.Runtime.CompilerServices;
 public class AInCs
 {
-    static string B(int param, [CallerArgumentExpression("param")] string expr = null) => expr;
+    public static string B(int param, [CallerArgumentExpression("param")] string expr = null) => expr;
 }
 
 namespace System.Runtime.CompilerServices
 {
     [AttributeUsage(AttributeTargets.Parameter)]
-    sealed class CallerArgumentExpressionAttribute : Attribute
+    public sealed class CallerArgumentExpressionAttribute : Attribute
     {
         public CallerArgumentExpressionAttribute(string param)
         {

From 5e1e27ccaee9d054eb680252c2aedab72c10225e Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Tue, 25 Mar 2025 18:09:20 +0800
Subject: [PATCH 54/57] try fix cannot determine in C# method with non BCL attr

---
 src/Compiler/Checking/infos.fs          | 12 ++----------
 src/Compiler/TypedTree/TypedTreeOps.fs  | 13 +++++++++++++
 src/Compiler/TypedTree/TypedTreeOps.fsi |  4 ++++
 src/Compiler/Utilities/range.fsi        |  2 +-
 4 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/src/Compiler/Checking/infos.fs b/src/Compiler/Checking/infos.fs
index 07735f72260..056dacd40c9 100644
--- a/src/Compiler/Checking/infos.fs
+++ b/src/Compiler/Checking/infos.fs
@@ -320,16 +320,7 @@ let CrackParamAttribsInfo g (ty: TType, argInfo: ArgReprInfo) =
     let isCallerMemberNameArg = HasFSharpAttribute g g.attrib_CallerMemberNameAttribute argInfo.Attribs
     let callerArgumentExpressionArg = 
         TryFindFSharpAttributeOpt g g.attrib_CallerArgumentExpressionAttribute argInfo.Attribs
-        // find user defined CallerArgumentExpressionAttribute
-        |> Option.orElseWith (fun () -> 
-            argInfo.Attribs
-            |> List.tryFind (fun (Attrib(tcref2, _, _, _, _, _, _)) -> 
-                match tcref2.TryDeref with
-                | ValueNone -> false
-                | ValueSome x ->
-                    x.CompilationPath.MangledPath = ["System"; "Runtime"; "CompilerServices"] && 
-                    x.CompiledName = "CallerArgumentExpressionAttribute")
-        )
+        |> Option.orElseWith (fun () -> TryFindFSharpAttributeByName "System.Runtime.CompilerServices.CallerArgumentExpressionAttribute" argInfo.Attribs)
 
     let callerInfo =
         match isCallerLineNumberArg, isCallerFilePathArg, isCallerMemberNameArg, callerArgumentExpressionArg with
@@ -1298,6 +1289,7 @@ type MethInfo =
                  let isCallerArgumentExpressionArg =
                      g.attrib_CallerArgumentExpressionAttribute
                      |> Option.bind (fun (AttribInfo(tref, _)) -> TryDecodeILAttribute tref attrs)
+                     |> Option.orElseWith (fun () -> TryDecodeILAttributeByName "System.Runtime.CompilerServices.CallerArgumentExpressionAttribute" attrs)
 
                  let callerInfo =
                     match isCallerLineNumberArg, isCallerFilePathArg, isCallerMemberNameArg, isCallerArgumentExpressionArg with
diff --git a/src/Compiler/TypedTree/TypedTreeOps.fs b/src/Compiler/TypedTree/TypedTreeOps.fs
index e5e330759dc..bf88932ea38 100644
--- a/src/Compiler/TypedTree/TypedTreeOps.fs
+++ b/src/Compiler/TypedTree/TypedTreeOps.fs
@@ -3519,12 +3519,25 @@ let HasILAttribute tref (attrs: ILAttributes) =
 let TryDecodeILAttribute tref (attrs: ILAttributes) = 
     attrs.AsArray() |> Array.tryPick (fun x -> if isILAttrib tref x then Some(decodeILAttribData x) else None)
 
+let TryDecodeILAttributeByName nm (attrs: ILAttributes) = 
+    attrs.AsArray() |> Array.tryPick (fun x -> if isILAttribByName ([], nm) x then Some(decodeILAttribData x) else None)
+
 // F# view of attributes (these get converted to AbsIL attributes in ilxgen) 
 let IsMatchingFSharpAttribute g (AttribInfo(_, tcref)) (Attrib(tcref2, _, _, _, _, _, _)) = tyconRefEq g tcref tcref2
 let HasFSharpAttribute g tref attrs = List.exists (IsMatchingFSharpAttribute g tref) attrs
 let TryFindFSharpAttribute g tref attrs = List.tryFind (IsMatchingFSharpAttribute g tref) attrs
 let TryFindFSharpAttributeOpt g tref attrs = match tref with None -> None | Some tref -> List.tryFind (IsMatchingFSharpAttribute g tref) attrs
 
+let TryFindFSharpAttributeByName nm attrs = 
+    let path, typeName = splitILTypeName nm
+    attrs
+    |> List.tryFind (fun (Attrib(tcref2, _, _, _, _, _, _)) -> 
+        match tcref2.TryDeref with
+        | ValueNone -> false
+        | ValueSome x ->
+            x.CompilationPath.MangledPath = path && 
+            x.CompiledName = typeName)
+
 let HasFSharpAttributeOpt g trefOpt attrs = match trefOpt with Some tref -> List.exists (IsMatchingFSharpAttribute g tref) attrs | _ -> false
 let IsMatchingFSharpAttributeOpt g attrOpt (Attrib(tcref2, _, _, _, _, _, _)) = match attrOpt with Some (AttribInfo(_, tcref)) -> tyconRefEq g tcref tcref2 | _ -> false
 
diff --git a/src/Compiler/TypedTree/TypedTreeOps.fsi b/src/Compiler/TypedTree/TypedTreeOps.fsi
index c67ccb30800..23c985f655b 100755
--- a/src/Compiler/TypedTree/TypedTreeOps.fsi
+++ b/src/Compiler/TypedTree/TypedTreeOps.fsi
@@ -2315,6 +2315,8 @@ val mkLdelem: TcGlobals -> range -> TType -> Expr -> Expr -> Expr
 
 val TryDecodeILAttribute: ILTypeRef -> ILAttributes -> (ILAttribElem list * ILAttributeNamedArg list) option
 
+val TryDecodeILAttributeByName: nm: string -> ILAttributes -> (ILAttribElem list * ILAttributeNamedArg list) option
+
 val IsILAttrib: BuiltinAttribInfo -> ILAttribute -> bool
 
 val TryFindILAttribute: BuiltinAttribInfo -> ILAttributes -> bool
@@ -2329,6 +2331,8 @@ val HasFSharpAttribute: TcGlobals -> BuiltinAttribInfo -> Attribs -> bool
 
 val HasFSharpAttributeOpt: TcGlobals -> BuiltinAttribInfo option -> Attribs -> bool
 
+val TryFindFSharpAttributeByName: nm: string -> Attribs -> Attrib option
+
 val TryFindFSharpAttribute: TcGlobals -> BuiltinAttribInfo -> Attribs -> Attrib option
 
 val TryFindFSharpAttributeOpt: TcGlobals -> BuiltinAttribInfo option -> Attribs -> Attrib option
diff --git a/src/Compiler/Utilities/range.fsi b/src/Compiler/Utilities/range.fsi
index ea2040459f2..fbbd392077e 100755
--- a/src/Compiler/Utilities/range.fsi
+++ b/src/Compiler/Utilities/range.fsi
@@ -272,7 +272,7 @@ module Line =
 /// Store code file content. Used to implement `CallerArgumentExpression`
 module internal FileContent =
 
-    /// Update the file content.
+    /// Update the file content. Should be called before the code file/expression is typechecked.
     val update: fileName: string -> fileContent: string -> unit
     
     /// Get the substring of the given range.

From 199d4b5b76d625b052cf8e545284de30c45ea26f Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Wed, 26 Mar 2025 13:37:20 +0800
Subject: [PATCH 55/57] refactor

---
 src/Compiler/Driver/CompilerConfig.fs         |  18 +--
 src/Compiler/Interactive/fsi.fs               |   9 +-
 src/Compiler/Utilities/range.fs               | 130 ++++++++----------
 src/Compiler/Utilities/range.fsi              |  16 ++-
 .../CallerArgumentExpression.fs               |  70 ++++------
 .../CallerArgumentExpression/test script.fsx  |  17 +++
 .../FSharp.Compiler.ComponentTests.fsproj     |   2 +-
 .../FSharp.Compiler.Service.Tests.fsproj      |   1 -
 .../FileContentTests.fs                       |  30 ----
 9 files changed, 126 insertions(+), 167 deletions(-)
 rename tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/{ => CallerArgumentExpression}/CallerArgumentExpression.fs (88%)
 create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression/test script.fsx
 delete mode 100644 tests/FSharp.Compiler.Service.Tests/FileContentTests.fs

diff --git a/src/Compiler/Driver/CompilerConfig.fs b/src/Compiler/Driver/CompilerConfig.fs
index 67f39b6e3da..35cd81ce100 100644
--- a/src/Compiler/Driver/CompilerConfig.fs
+++ b/src/Compiler/Driver/CompilerConfig.fs
@@ -1540,13 +1540,13 @@ type TcConfigProvider =
 
 let GetFSharpCoreLibraryName () = getFSharpCoreLibraryName
 
-/// Read and store the source file content for the `CallerArgumentExpression` feature
+/// Read and store the source file content for the `CallerArgumentExpression` feature.
+/// This should only be called in `fsc` or `fsi` processing.
 let readAndStoreFileContents (tcConfig: TcConfig) (sourceFiles: #seq<string>) =
-    for fileName in sourceFiles do
-        if FSharpImplFileSuffixes |> List.exists (FileSystemUtils.checkSuffix fileName) then
-            try
-                use fileStream = FileSystem.OpenFileForReadShim fileName
-                use reader = fileStream.GetReader(tcConfig.inputCodePage)
-                FileContent.update fileName (reader.ReadToEnd())
-            with _ ->
-                ()
+    if
+        tcConfig.langVersion.SupportsFeature LanguageFeature.SupportCallerArgumentExpression
+        && (tcConfig.compilationMode.IsOneOff || tcConfig.isInteractive)
+    then
+        for fileName in sourceFiles do
+            if FSharpImplFileSuffixes |> List.exists (FileSystemUtils.checkSuffix fileName) then
+                FileContent.update fileName (FileContent.FileCacheType.NotYetRead tcConfig.inputCodePage)
diff --git a/src/Compiler/Interactive/fsi.fs b/src/Compiler/Interactive/fsi.fs
index df543abdc0c..e266647aee7 100644
--- a/src/Compiler/Interactive/fsi.fs
+++ b/src/Compiler/Interactive/fsi.fs
@@ -3520,7 +3520,8 @@ type FsiStdinLexerProvider
                     | NonNull t ->
                         fsiStdinSyphon.Add(t + "\n")
                         // Update the stdin file content for the `CallerArgumentExpression` feature
-                        FileContent.update stdinMockFileName fsiStdinSyphon.SyphonText)
+                        FileContent.clear ()
+                        FileContent.update stdinMockFileName (FileContent.FileCacheType.FromString fsiStdinSyphon.SyphonText))
 
                 match inputOption with
                 | Some Null
@@ -4299,7 +4300,8 @@ type FsiInteractionProcessor
             let expr = ParseInteraction tokenizer
 
             // Update the file content for the `CallerArgumentExpression` feature
-            FileContent.update scriptFileName sourceText
+            FileContent.clear ()
+            FileContent.update scriptFileName (FileContent.FileCacheType.FromString sourceText)
 
             ExecuteParsedInteractionOnMainThread(ctok, diagnosticsLogger, expr, istate, cancellationToken))
         |> commitResult
@@ -4336,7 +4338,8 @@ type FsiInteractionProcessor
                 )
 
             // Update the file content for the `CallerArgumentExpression` feature
-            FileContent.update scriptFileName sourceText
+            FileContent.clear ()
+            FileContent.update scriptFileName (FileContent.FileCacheType.FromString sourceText)
 
             ExecuteParsedExpressionOnMainThread(ctok, diagnosticsLogger, exprWithSeq, istate))
         |> commitResult
diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs
index 20b39f73fcb..10734d0a77a 100755
--- a/src/Compiler/Utilities/range.fs
+++ b/src/Compiler/Utilities/range.fs
@@ -583,95 +583,81 @@ module Range =
             mkRange file (mkPos 1 0) (mkPos 1 80)
 
 module internal FileContent =
-    let private fileContentDict = ConcurrentDictionary<string, string>()
+    [<RequireQualifiedAccess>]
+    type FileCacheType =
+        | AlreadyRead of lines: string array
+        | NotYetRead of codePage: int option
 
-    let update (fileName: string) (fileContent: string) =
-        fileContentDict.AddOrUpdate(fileName, (fun _ -> fileContent), (fun _ _ -> fileContent))
-        |> ignore
+        static member FromString(s: string) = AlreadyRead(s.Split '\n')
 
-    let private seperators = [| '\r'; '\n' |]
+    let private fileContentDict = ConcurrentDictionary<string, FileCacheType>()
 
-    /// Find the index of the nearest line separator (\r or \r\n or \n) in the given string and offset.
-    let findLineEnd (input: string) lineStart =
-        if lineStart >= input.Length then
-            input.Length - 1
-        else
-            let idx = input.IndexOfAny(seperators, lineStart)
+    let update (fileName: string) (fileContent: FileCacheType) =
+        fileContentDict.AddOrUpdate(fileName, (fun _ -> fileContent), (fun _ _ -> fileContent))
+        |> ignore
 
-            if idx = -1 then
-                input.Length - 1
-            elif input.[idx] = '\r' && idx + 1 < input.Length && input.[idx + 1] = '\n' then
-                idx + 1
-            else
-                idx
+    let clear () = fileContentDict.Clear()
 
     /// Get the substring of the given range.
-    /// This can retain the line seperators in the source string.
-    let substring (input: string) (range: range) =
+    let private substring (input: string array) (range: range) =
         let startLine, startCol = range.StartLine, range.StartColumn
         let endLine, endCol = range.EndLine, range.EndColumn
 
         if
-            startLine < 1
-            || (startLine = endLine && startCol > endCol)
+            (startCol < 0 || endCol < 0)
+            || startLine < 1
             || startLine > endLine
-            || startCol < 0
-            || endCol < 0
+            || startLine > input.Length
+            || (startLine = endLine
+                && (startCol > endCol || startCol >= input.[startLine - 1].Length))
         then
             System.String.Empty
+        elif startLine = endLine then
+            let line = input.[startLine - 1]
+            let endCol = min (endCol - 1) (line.Length - 1)
+            let result = line.Substring(startCol, endCol - startCol + 1)
+
+            if endCol = line.Length - 1 && line[endCol] = '\r' then
+                result + "\n"
+            else
+                result
         else
-            // Here the loop was splited into two functions to avoid the non necessary allocation of the StringBuilder
-
-            /// Take text until reach the end line of the range.
-            let rec loopEnd (result: System.Text.StringBuilder) lineCount (startIndex, endIndex) =
-                if lineCount < endLine then
-                    result.Append(input.Substring(startIndex, endIndex - startIndex + 1)) |> ignore
-
-                    let nextLineEnd = findLineEnd input (endIndex + 1)
-
-                    if nextLineEnd = endIndex then
-                        result.ToString()
-                    else
-                        loopEnd result (lineCount + 1) (endIndex + 1, nextLineEnd)
-                elif lineCount = endLine then
-                    let len = min endCol (endIndex - startIndex + 1)
-                    result.Append(input.Substring(startIndex, len)).ToString()
-                else
-                    result.ToString()
-
-            /// Go to the start line of the range.
-            let rec loopStart lineCount (startIndex, endIndex) =
-                if lineCount < startLine then
-                    let nextLineEnd = findLineEnd input (endIndex + 1)
-
-                    if nextLineEnd = endIndex then
-                        System.String.Empty
-                    else
-                        loopStart (lineCount + 1) (endIndex + 1, nextLineEnd)
-
-                // reach the start line
-                elif lineCount = startLine && startLine = endLine then
-                    if startIndex + startCol <= endIndex then
-                        let endCol = min (endCol - 1) (endIndex - startIndex)
-                        input.Substring(startIndex + startCol, endCol - startCol + 1)
-                    else
-                        System.String.Empty
-                else
-                    let result = System.Text.StringBuilder()
+            let appendNewLineMark sb =
+                (sb: System.Text.StringBuilder).Append '\n' |> ignore
+
+            let startCol = min startCol (input.[startLine - 1].Length - 1)
+            let result = System.Text.StringBuilder()
+            result.Append(input.[startLine - 1].Substring(startCol)) |> ignore
+            appendNewLineMark result
 
-                    if lineCount = startLine then
-                        if startCol < endIndex - startIndex + 1 then
-                            result.Append(input.Substring(startIndex + startCol, endIndex - startIndex + 1 - startCol))
-                            |> ignore
+            let upperBound = min (endLine - 2) (input.Length - 1)
 
-                        loopEnd result (lineCount + 1) (endIndex + 1, findLineEnd input (endIndex + 1))
-                    else
-                        // Should not go into here
-                        loopEnd result lineCount (startIndex, endIndex)
+            for i in startLine..upperBound do
+                result.Append(input.[i]) |> ignore
+                appendNewLineMark result
 
-            loopStart 1 (0, findLineEnd input 0)
+            if endLine < input.Length then
+                let line = input.[endLine - 1]
+                let endCol = min endCol line.Length
+                result.Append(line.Substring(0, endCol)) |> ignore
+
+                if endCol = line.Length - 1 && line[endCol] = '\r' then
+                    appendNewLineMark result
+
+            result.ToString()
 
     let getCodeText (m: range) =
-        match fileContentDict.TryGetValue m.FileName with
-        | true, text -> substring text m
+        let fileName = m.FileName
+
+        match fileContentDict.TryGetValue fileName with
+        | true, FileCacheType.AlreadyRead lines -> substring lines m
+        | true, FileCacheType.NotYetRead codePage ->
+            try
+                use fileStream = FileSystem.OpenFileForReadShim fileName
+                use reader = fileStream.GetReader(codePage)
+                let lines = reader.ReadToEnd().Split('\n')
+                update fileName (FileCacheType.AlreadyRead lines)
+                substring lines m
+            with _ ->
+                String.Empty
         | _ -> String.Empty
diff --git a/src/Compiler/Utilities/range.fsi b/src/Compiler/Utilities/range.fsi
index fbbd392077e..363b8bee927 100755
--- a/src/Compiler/Utilities/range.fsi
+++ b/src/Compiler/Utilities/range.fsi
@@ -271,13 +271,19 @@ module Line =
 
 /// Store code file content. Used to implement `CallerArgumentExpression`
 module internal FileContent =
+    [<RequireQualifiedAccess>]
+    type FileCacheType =
+        | AlreadyRead of lines: string array
+        | NotYetRead of codePage: int option
+        
+        static member FromString: s: string -> FileCacheType
 
     /// Update the file content. Should be called before the code file/expression is typechecked.
-    val update: fileName: string -> fileContent: string -> unit
+    val update: fileName: string -> fileContent: FileCacheType -> unit
+    
+    /// Clean up all the file contents. 
+    /// May be called in `fsi` processing, to avoid holding the source files which were compiled.
+    val clear: unit -> unit
     
-    /// Get the substring of the given range.
-    /// This can retain the line seperators in the source string.
-    val substring: input: string -> range: range -> string    
-
     /// Get the code text of the specific `range`
     val getCodeText: range -> string
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression/CallerArgumentExpression.fs
similarity index 88%
rename from tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
rename to tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression/CallerArgumentExpression.fs
index 48a083f12f5..08d7437ff62 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression/CallerArgumentExpression.fs
@@ -7,32 +7,16 @@ open FSharp.Test.Compiler
 open FSharp.Test
 
 module CustomAttributes_CallerArgumentExpression =
-
+    let scriptPath = __SOURCE_DIRECTORY__ ++ "test script.fsx"
+  
     [<FactForNETCOREAPP>]
     let ``Can consume CallerArgumentExpression in BCL methods`` () =
-        FSharp """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
-try System.ArgumentException.ThrowIfNullOrWhiteSpace(Seq.init 50 (fun _ -> " ")
-  (* comment *) 
-  |> String.concat " ")
-with :? System.ArgumentException as ex -> 
-  assertEqual true (ex.Message.Contains("(Parameter 'Seq.init 50 (fun _ -> \" \")
-  (* comment *) 
-  |> String.concat \" \""))
-  
-
-try System.ArgumentException.ThrowIfNullOrWhiteSpace(argument = (Seq.init 11 (fun _ -> " ")
-  (* comment *) 
-  |> String.concat " "))
-with :? System.ArgumentException as ex -> 
-  assertEqual true (ex.Message.Contains("(Parameter '(Seq.init 11 (fun _ -> \" \")
-  (* comment *) 
-  |> String.concat \" \")"))
-"""
-        |> withLangVersionPreview
-        |> asExe
-        |> compileAndRun
-        |> shouldSucceed
-        |> ignore
+      FsFromPath scriptPath
+      |> withLangVersionPreview
+      |> asExe
+      |> compileAndRun
+      |> shouldSucceed
+      |> ignore
 
     [<FactForNETCOREAPP>]
     let ``Can define methods using CallerArgumentExpression with C#-style optional arguments`` () =
@@ -377,28 +361,22 @@ AInCs.B (123 - 7) |> assertEqual "123 - 7"
       |> compileAndRun
       |> shouldSucceed
       |> ignore
-      
+        
+    (* ------------ FSI tests ------------- *)
+    
     [<FactForNETCOREAPP>]
     let ``Check in fsi`` () =
-        Fsx """let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
-try System.ArgumentException.ThrowIfNullOrWhiteSpace(Seq.init 50 (fun _ -> " ")
-  (* comment *) 
-  |> String.concat " ")
-with :? System.ArgumentException as ex -> 
-  assertEqual true (ex.Message.Contains("(Parameter 'Seq.init 50 (fun _ -> \" \")
-  (* comment *) 
-  |> String.concat \" \""))
-  
+      FsxFromPath scriptPath
+      |> withLangVersionPreview
+      |> runFsi
+      |> shouldSucceed
+      |> ignore
 
-try System.ArgumentException.ThrowIfNullOrWhiteSpace(argument = (Seq.init 11 (fun _ -> " ")
-  (* comment *) 
-  |> String.concat " "))
-with :? System.ArgumentException as ex -> 
-  assertEqual true (ex.Message.Contains("(Parameter '(Seq.init 11 (fun _ -> \" \")
-  (* comment *) 
-  |> String.concat \" \")"))
-"""
-        |> withLangVersionPreview
-        |> runFsi
-        |> shouldSucceed
-        |> ignore
+
+    [<FactForNETCOREAPP>]
+    let ``Check fsi #load`` () =
+      Fsx $"""#load @"{scriptPath}" """
+      |> withLangVersionPreview
+      |> runFsi
+      |> shouldSucceed
+      |> ignore
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression/test script.fsx b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression/test script.fsx
new file mode 100644
index 00000000000..c2152fa6b3b
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression/test script.fsx	
@@ -0,0 +1,17 @@
+let assertEqual a b = if a <> b then failwithf "not equal: %A and %A" a b
+try System.ArgumentException.ThrowIfNullOrWhiteSpace(Seq.init 50 (fun _ -> " ")
+  (* comment *) 
+  |> String.concat " ")
+with :? System.ArgumentException as ex -> 
+  assertEqual true (ex.Message.Contains("(Parameter 'Seq.init 50 (fun _ -> \" \")
+  (* comment *) 
+  |> String.concat \" \""))
+  
+
+try System.ArgumentException.ThrowIfNullOrWhiteSpace(argument = (Seq.init 11 (fun _ -> " ")
+  (* comment *) 
+  |> String.concat " "))
+with :? System.ArgumentException as ex -> 
+  assertEqual true (ex.Message.Contains("(Parameter '(Seq.init 11 (fun _ -> \" \")
+  (* comment *) 
+  |> String.concat \" \")"))
\ No newline at end of file
diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
index 80a601d77dd..a9af0d57eee 100644
--- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
+++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
@@ -40,7 +40,7 @@
     <Compile Include="Conformance\BasicGrammarElements\AccessibilityAnnotations\PermittedLocations\PermittedLocations.fs" />
     <Compile Include="Conformance\BasicGrammarElements\CustomAttributes\AttributeInheritance\AttributeInheritance.fs" />
     <Compile Include="Conformance\BasicGrammarElements\CustomAttributes\AttributeUsage\AttributeUsage.fs" />
-    <Compile Include="Conformance\BasicGrammarElements\CustomAttributes\CallerArgumentExpression.fs" />
+    <Compile Include="Conformance\BasicGrammarElements\CustomAttributes\CallerArgumentExpression\CallerArgumentExpression.fs" />
     <Compile Include="Conformance\BasicGrammarElements\CustomAttributes\Basic\Basic.fs" />
     <Compile Include="Conformance\BasicGrammarElements\CustomAttributes\ImportedAttributes\ImportedAttributes.fs" />
     <Compile Include="Conformance\BasicGrammarElements\CustomAttributes\ArgumentsOfAllTypes\ArgumentsOfAllTypes.fs" />
diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj
index 54cca8a29dd..57ce88d8f02 100644
--- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj
+++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj
@@ -48,7 +48,6 @@
     <Compile Include="XmlDocTests.fs" />
     <Compile Include="XmlDocTests - Units of Measure.fs" />
     <Compile Include="RangeTests.fs" />
-    <Compile Include="FileContentTests.fs" />
     <Compile Include="TooltipTests.fs" />
     <Compile Include="TokenizerTests.fs" />
     <Compile Include="CompilerTestHelpers.fs" />
diff --git a/tests/FSharp.Compiler.Service.Tests/FileContentTests.fs b/tests/FSharp.Compiler.Service.Tests/FileContentTests.fs
deleted file mode 100644
index d257c153567..00000000000
--- a/tests/FSharp.Compiler.Service.Tests/FileContentTests.fs
+++ /dev/null
@@ -1,30 +0,0 @@
-module FSharp.Compiler.Service.Tests.FileContentTests
-
-open FSharp.Compiler.Text
-open FSharp.Compiler.Text.Position
-open FSharp.Compiler.Text.Range
-open FSharp.Compiler.Text.FileContent
-open FSharp.Test.Assert
-open Xunit
-
-let substring (input: string) (startLine, startCol) (endLine, endCol) =
-    let range = mkFileIndexRange 0 (mkPos startLine startCol) (mkPos endLine endCol)
-    substring input range
-    
-[<Fact>]
-let ``substring tests`` () =
-    substring "Hello, world!\r\nThis is a test.\r\n" (1, 7) (2, 4) |> shouldEqual "world!\r\nThis"
-    substring "Hello, world!\r\nThis is a test.\r\n" (9, 7) (9, 4) |> shouldEqual ""
-    substring "Hello, world!\r\nThis is a test.\r\ntest\n" (1, 7) (9, 4) |> shouldEqual "world!\r\nThis is a test.\r\ntest\n"
-    substring "Hello, world!\r\nThis is a test.\r\n" (1, 7) (2, 100) |> shouldEqual "world!\r\nThis is a test.\r\n"
-    substring "Hello, world!\r\nThis is a test.\r\n" (1, 7) (2, 7) |> shouldEqual "world!\r\nThis is"
-    substring "Hello, world! This is a test.\r\na test" (2, 1) (2, 6) |> shouldEqual " test"
-    substring "Hello, world! This is a test.\r\na test" (2, 7) (2, 8) |> shouldEqual ""
-    
-    substring "Hello, world!\r\nThis is a test.\r\n" (1, 0) (1, 4) |> shouldEqual "Hell"
-    substring "Hello, world!\r\nThis is a test.\r\n" (1, 7) (1, 4) |> shouldEqual ""
-    substring "Hello, world!\r\nThis is a test.\r\n" (1, 7) (1, 100) |> shouldEqual "world!\r\n"
-    substring "Hello, world!\r\nThis is a test.\r\n" (1, 7) (1, 7) |> shouldEqual ""
-    substring "Hello, world!\r\nThis is a test.\r\n" (1, 7) (1, 8) |> shouldEqual "w"
-    substring "Hello, world!\r\nThis is a test.\r\n" (1, 0) (1, 8) |> shouldEqual "Hello, w"
-    substring "Hello, world!\r\nThis is a test.\r\n" (1, 0) (1, 100) |> shouldEqual "Hello, world!\r\n"

From 5e3e596c69d71934c13265d5ea91cd9ce19bdfcf Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Wed, 26 Mar 2025 14:47:33 +0800
Subject: [PATCH 56/57] fix test

---
 .../CallerArgumentExpression.fs                      | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression/CallerArgumentExpression.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression/CallerArgumentExpression.fs
index 08d7437ff62..81dec3701fa 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression/CallerArgumentExpression.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/CallerArgumentExpression/CallerArgumentExpression.fs
@@ -7,11 +7,11 @@ open FSharp.Test.Compiler
 open FSharp.Test
 
 module CustomAttributes_CallerArgumentExpression =
-    let scriptPath = __SOURCE_DIRECTORY__ ++ "test script.fsx"
-  
+
     [<FactForNETCOREAPP>]
     let ``Can consume CallerArgumentExpression in BCL methods`` () =
-      FsFromPath scriptPath
+      let path = __SOURCE_DIRECTORY__ ++ "test script.fsx"
+      FsFromPath path
       |> withLangVersionPreview
       |> asExe
       |> compileAndRun
@@ -366,7 +366,8 @@ AInCs.B (123 - 7) |> assertEqual "123 - 7"
     
     [<FactForNETCOREAPP>]
     let ``Check in fsi`` () =
-      FsxFromPath scriptPath
+      let path = __SOURCE_DIRECTORY__ ++ "test script.fsx"
+      FsxFromPath path
       |> withLangVersionPreview
       |> runFsi
       |> shouldSucceed
@@ -375,7 +376,8 @@ AInCs.B (123 - 7) |> assertEqual "123 - 7"
 
     [<FactForNETCOREAPP>]
     let ``Check fsi #load`` () =
-      Fsx $"""#load @"{scriptPath}" """
+      let path = __SOURCE_DIRECTORY__ ++ "test script.fsx"
+      Fsx $"""#load @"{path}" """
       |> withLangVersionPreview
       |> runFsi
       |> shouldSucceed

From 607f2d1530164162a5c77105619996419b1c8986 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Wed, 26 Mar 2025 15:15:43 +0800
Subject: [PATCH 57/57] ilverify

---
 src/Compiler/Driver/CompilerConfig.fsi                   | 3 ++-
 .../ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl    | 4 +---
 ...rify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl | 6 +++---
 .../ilverify_FSharp.Compiler.Service_Release_net9.0.bsl  | 4 +---
 ...fy_FSharp.Compiler.Service_Release_netstandard2.0.bsl | 9 ++++++---
 5 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/src/Compiler/Driver/CompilerConfig.fsi b/src/Compiler/Driver/CompilerConfig.fsi
index f0efcbcefd4..13d234840dc 100644
--- a/src/Compiler/Driver/CompilerConfig.fsi
+++ b/src/Compiler/Driver/CompilerConfig.fsi
@@ -962,5 +962,6 @@ val FSharpMLCompatFileSuffixes: string list
 /// Indicates whether experimental features should be enabled automatically
 val FSharpExperimentalFeaturesEnabledAutomatically: bool
 
-/// Read and store the source file content for the `CallerArgumentExpression` feature
+/// Read and store the source file content for the `CallerArgumentExpression` feature.
+/// This should only be called in `fsc` or `fsi` processing.
 val readAndStoreFileContents: tcConfig: TcConfig -> sourceFiles: #seq<string> -> unit
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl
index 0d83584b688..da3d394d76a 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl
@@ -21,7 +21,7 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x00000082][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3508-805::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001FE][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3508-805::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x00000209][found Char] Unexpected type on the stack.
 [IL]: Error [UnmanagedPointer]: : FSharp.Compiler.Interactive.Shell+Utilities+pointerToNativeInt@110::Invoke(object)][offset 0x00000007] Unmanaged pointers are not a verifiable type.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharpCheckerResults+dataTipOfReferences@2225::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000084][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$ServiceLexing+clo@921-509::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<FSharp.Compiler.Parser+token,int32,int32>,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack.
@@ -60,8 +60,6 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x00000021][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000CD][found Char] Unexpected type on the stack.
 [IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@558::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
-[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Range::.cctor()][offset 0x00000216][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Range::.cctor()][offset 0x0000021F][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000037][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000043][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack.
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl
index 1beb3e3ac03..188df6b5a7a 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl
@@ -28,7 +28,7 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiStdinSyphon::GetLine(string, int32)][offset 0x00000039][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3508-805::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001FE][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3508-805::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x00000209][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiInteractionProcessor::CompletionsForPartialLID([FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompilerState, string)][offset 0x0000001B][found Char] Unexpected type on the stack.
 [IL]: Error [UnmanagedPointer]: : FSharp.Compiler.Interactive.Shell+Utilities+pointerToNativeInt@110::Invoke(object)][offset 0x00000007] Unmanaged pointers are not a verifiable type.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharpCheckerResults+dataTipOfReferences@2225::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000084][found Char] Unexpected type on the stack.
@@ -84,9 +84,9 @@
 [IL]: Error [StackUnexpected]: : Internal.Utilities.FSharpEnvironment+probePathForDotnetHost@316::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000028][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.SimulatedMSBuildReferenceResolver+Pipe #6 input at line 68@68::FSharp.Compiler.CodeAnalysis.ILegacyReferenceResolver.Resolve([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyResolutionEnvironment, [S.P.CoreLib]System.Tuple`2<string,string>[], string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>, string, string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>, string, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.Unit>, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<bool,Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.Unit>>>)][offset 0x0000034D][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000CD][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Text.FileContent::getCodeText([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000098][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Text.FileContent+FileCacheType::FromString(string)][offset 0x0000000B][found Char] Unexpected type on the stack.
 [IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@558::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
-[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Range::.cctor()][offset 0x00000216][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Range::.cctor()][offset 0x0000021F][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000037][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000043][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack.
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl
index e0f2977d8d3..de04825a10c 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl
@@ -21,7 +21,7 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x00000082][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3508-849::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001E5][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3508-849::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001FC][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharpCheckerResults+GetReferenceResolutionStructuredToolTipText@2225::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000076][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$ServiceLexing+clo@921-530::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<FSharp.Compiler.Parser+token,int32,int32>,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$ServiceLexing+clo@921-530::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<FSharp.Compiler.Parser+token,int32,int32>,Microsoft.FSharp.Core.Unit>)][offset 0x0000003B][found Char] Unexpected type on the stack.
@@ -86,8 +86,6 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x00000021][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000B6][found Char] Unexpected type on the stack.
 [IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@558::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
-[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Range::.cctor()][offset 0x000000F0][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Range::.cctor()][offset 0x000000F9][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000035][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000041][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack.
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl
index 268dfbb233c..dfdd1660d6c 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl
@@ -28,8 +28,11 @@
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiStdinSyphon::GetLine(string, int32)][offset 0x00000032][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3508-849::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001E5][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3508-849::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x00000107][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3508-849::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x00000208][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiInteractionProcessor::CompletionsForPartialLID([FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompilerState, string)][offset 0x00000024][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+EvalInteraction@4299::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompilerState)][offset 0x0000002E][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+EvalExpression@4326::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompilerState)][offset 0x00000059][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharpCheckerResults+GetReferenceResolutionStructuredToolTipText@2225::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000076][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.AssemblyContent+traverseMemberFunctionAndValues@176::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue)][offset 0x0000002B][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.AssemblyContent+traverseEntity@218::GenerateNext([S.P.CoreLib]System.Collections.Generic.IEnumerable`1<FSharp.Compiler.EditorServices.AssemblySymbol>&)][offset 0x000000BB][found Char] Unexpected type on the stack.
@@ -111,9 +114,9 @@
 [IL]: Error [StackUnexpected]: : Internal.Utilities.FSharpEnvironment::probePathForDotnetHost@315([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x0000002A][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.SimulatedMSBuildReferenceResolver+SimulatedMSBuildResolver@68::FSharp.Compiler.CodeAnalysis.ILegacyReferenceResolver.Resolve([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyResolutionEnvironment, [S.P.CoreLib]System.Tuple`2<string,string>[], string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>, string, string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>, string, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.Unit>, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<bool,Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.FSharpFunc`2<string,Microsoft.FSharp.Core.Unit>>>)][offset 0x000002F5][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000B6][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Text.FileContent::getCodeText([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000089][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Text.FileContent+FileCacheType::FromString(string)][offset 0x0000000B][found Char] Unexpected type on the stack.
 [IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@558::System.Collections.Generic.IEqualityComparer<FSharp.Compiler.Text.Range>.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method.
-[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Range::.cctor()][offset 0x000000F0][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Range::.cctor()][offset 0x000000F9][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000035][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000041][found Char] Unexpected type on the stack.
 [IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack.