From 554ee169e99a98db61c4159d5ab0154b4d9d209e Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Sat, 15 Mar 2025 23:08:43 +0800
Subject: [PATCH 1/2] improve caller info attribute error message range
---
src/Compiler/Checking/PostInferenceChecks.fs | 31 +++++++++++--------
.../Imported/CallerInfo/E_CallerFilePath.fs | 6 ++--
.../Imported/CallerInfo/E_CallerLineNumber.fs | 6 ++--
.../Imported/CallerInfo/E_CallerMemberName.fs | 6 ++--
.../Imported/CallerInfo/E_MultipleAttrs.fs | 8 ++---
5 files changed, 31 insertions(+), 26 deletions(-)
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
From 073d64e3e6219aa07d195af182ce374e503643c1 Mon Sep 17 00:00:00 2001
From: ijklam <43789618+Tangent-90@users.noreply.github.com>
Date: Sat, 15 Mar 2025 23:12:25 +0800
Subject: [PATCH 2/2] release note
---
docs/release-notes/.FSharp.Compiler.Service/9.0.300.md | 1 +
1 file changed, 1 insertion(+)
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 12f4074a4a0..8dde2434701 100644
--- a/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md
+++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md
@@ -33,6 +33,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))