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 dcaad6579a9..26346c6b264 100644
--- a/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md
+++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md
@@ -35,6 +35,7 @@
* Added nullability annotations to `.Using` builder method for `async`, `task` and compiler-internal builders ([PR #18292](https://github.com/dotnet/fsharp/pull/18292))
* Warn when `unit` is passed to an `obj`-typed argument ([PR #18330](https://github.com/dotnet/fsharp/pull/18330))
* Warning for "useless null handling" works with piped syntax constructs now ([PR #18331](https://github.com/dotnet/fsharp/pull/18331))
+* Adjust caller info attribute error message range ([PR #18388](https://github.com/dotnet/fsharp/pull/18388))
### Breaking Changes
* Struct unions with overlapping fields now generate mappings needed for reading via reflection ([Issue #18121](https://github.com/dotnet/fsharp/issues/17797), [PR #18274](https://github.com/dotnet/fsharp/pull/17877))
diff --git a/src/Compiler/Checking/PostInferenceChecks.fs b/src/Compiler/Checking/PostInferenceChecks.fs
index 3a4fe0e65ed..4df0185a2e5 100644
--- a/src/Compiler/Checking/PostInferenceChecks.fs
+++ b/src/Compiler/Checking/PostInferenceChecks.fs
@@ -2398,9 +2398,23 @@ let CheckEntityDefn cenv env (tycon: Entity) =
errorR(Error(FSComp.SR.chkCurriedMethodsCantHaveOutParams(), m))
if numCurriedArgSets = 1 then
+ 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))
+
minfo.GetParamDatas(cenv.amap, m, minfo.FormalMethodInst)
- |> List.iterSquared (fun (ParamData(_, isInArg, _, optArgInfo, callerInfo, _, _, ty)) ->
+ |> 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))
@@ -2410,18 +2424,9 @@ 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 _, (CallerFilePath | CallerMemberName) -> errorIfNotStringTy m ty callerInfo
+ | CalleeSide, (CallerFilePath | CallerMemberName) -> errorIfNotStringOptionTy m ty callerInfo
+ )
for pinfo in immediateProps do
let nm = pinfo.PropertyName
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 @@
-//'CallerFilePath' must be applied to an argument of type 'string', but has been applied to an argument of type 'int'
-//'CallerFilePath' can only be applied to optional arguments
-//'CallerFilePath' can only be applied to optional arguments
+//'CallerFilePath' must be applied to an argument of type 'string', but has been applied to an argument of type 'int'
+//'CallerFilePath' can only be applied to optional arguments
+//'CallerFilePath' can only be applied to optional arguments
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 @@
-//'CallerLineNumber' must be applied to an argument of type 'int', but has been applied to an argument of type 'string'
-//'CallerLineNumber' can only be applied to optional arguments
-//'CallerLineNumber' can only be applied to optional arguments
+//'CallerLineNumber' must be applied to an argument of type 'int', but has been applied to an argument of type 'string'
+//'CallerLineNumber' can only be applied to optional arguments
+//'CallerLineNumber' can only be applied to optional arguments
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 @@
-//'CallerMemberName' must be applied to an argument of type 'string', but has been applied to an argument of type 'int'
-//'CallerMemberName' can only be applied to optional arguments
-//'CallerMemberName' can only be applied to optional arguments
+//'CallerMemberName' must be applied to an argument of type 'string', but has been applied to an argument of type 'int'
+//'CallerMemberName' can only be applied to optional arguments
+//'CallerMemberName' can only be applied to optional arguments
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 @@
-//'CallerFilePath' must be applied to an argument of type 'string', but has been applied to an argument of type 'int'
-//'CallerFilePath' must be applied to an argument of type 'string', but has been applied to an argument of type 'int'
-//'CallerLineNumber' must be applied to an argument of type 'int', but has been applied to an argument of type 'string'
-//'CallerLineNumber' must be applied to an argument of type 'int', but has been applied to an argument of type 'string'
+//'CallerFilePath' must be applied to an argument of type 'string', but has been applied to an argument of type 'int'
+//'CallerFilePath' must be applied to an argument of type 'string', but has been applied to an argument of type 'int'
+//'CallerLineNumber' must be applied to an argument of type 'int', but has been applied to an argument of type 'string'
+//'CallerLineNumber' must be applied to an argument of type 'int', but has been applied to an argument of type 'string'
namespace Test