Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
55769f8
Narrow overload-error and symbol-use ranges to terminal identifier (#…
T-Gro Apr 22, 2026
1388527
Address review feedback: remove unused mItemIdent from TcItemThen
T-Gro May 14, 2026
f0ce164
Merge branch 'main' into copilot/fix-9141961-29048891-ac83c611-04a8-4…
T-Gro May 14, 2026
97eaeec
Address review: thread mItemIdent instead of manual range arithmetic
T-Gro May 19, 2026
a43c3be
Merge remote-tracking branch 'origin/main' into copilot/fix-9141961-2…
T-Gro May 19, 2026
f7a06f3
Simplify ComputeItemRange doc comment
T-Gro May 19, 2026
b545435
Thread mItemIdent through constructor path and fix baselines
T-Gro May 19, 2026
7166e4a
Scope down to Method-only: revert sink narrowing and workaround
T-Gro May 21, 2026
be2676e
Clean up slop: remove redundant comments, fix multiline test assertion
T-Gro May 21, 2026
cb49dad
R2: trim doc comments, add constructor overload test
T-Gro May 21, 2026
abdf73c
R3: drop dead destructure, add terse TcItemThen comment, fix ctor test
T-Gro May 21, 2026
112ed39
Address review: pass narrow ident range as mItem, drop mItemIdent par…
T-Gro May 21, 2026
0a689f5
Fix missed TypeDirectedConversion baseline for narrowed Warning 64 range
T-Gro May 22, 2026
23026ab
Revert narrow-mItem approach: keep 3 ranges, rewrap only FS0041
T-Gro May 22, 2026
b287287
Unify 3 range params to 2: pass narrow mItemIdent as mItem
T-Gro May 25, 2026
34a16a7
Fix neg20/neg106 baselines: remove spurious duplicate diagnostics
T-Gro May 25, 2026
79e1367
Narrow static property overload ranges via TcPropertyItemThen
T-Gro May 25, 2026
495ece2
Fix neg106.vsbsl baseline: remove spurious FS1204 duplicates
T-Gro May 25, 2026
5b8fadb
Fix CI test baselines for narrowed diagnostic ranges
T-Gro May 26, 2026
12431a6
Fix neg30.bsl baseline for CompilerMessage property range narrowing
T-Gro May 26, 2026
6579e12
Fix neg30.bsl: FS0120 CompilerMessage warning emits from two paths
T-Gro May 26, 2026
ac86494
Remove wide mItem range, pass only narrow terminal-identifier range
T-Gro May 26, 2026
1bfba02
Update test baselines for narrow-range-only changes
T-Gro May 26, 2026
45a6bcf
Reuse itemIdentRange for property sink registration
T-Gro May 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/aw/actions-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
"version": "v8",
"sha": "ed597411d8f924073f98dfc5c65a23a2325f34cd"
},
"actions/github-script@v9.0.0": {
"actions/github-script@v9": {
"repo": "actions/github-script",
"version": "v9.0.0",
"version": "v9",
"sha": "3a2844b7e9c422d3c10d287c895573f7108da1b3"
},
"github/gh-aw-actions/setup@v0.72.1": {
"github/gh-aw-actions/setup@v0.68.3": {
"repo": "github/gh-aw-actions/setup",
"version": "v0.72.1",
"sha": "bc56a0cad2f450c562810785ef38649c04db812a"
"version": "v0.68.3",
"sha": "ba90f2186d7ad780ec640f364005fa24e797b360"
},
"github/gh-aw/actions/setup@v0.67.2": {
"repo": "github/gh-aw/actions/setup",
Expand Down
1 change: 1 addition & 0 deletions docs/release-notes/.FSharp.Compiler.Service/11.0.100.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* Fix attributes on return type of unparenthesized tuple methods being silently dropped from IL. ([Issue #462](https://github.com/dotnet/fsharp/issues/462), [PR #19714](https://github.com/dotnet/fsharp/pull/19714))
* Fix internal error FS0073 "Undefined or unsolved type variable" in IlxGen when nested inline SRTP functions with multiple overloads leave unsolved typars in the non-witness codegen path. ([Issue #19709](https://github.com/dotnet/fsharp/issues/19709), [PR #19710](https://github.com/dotnet/fsharp/pull/19710))
* Fix NRE when calling virtual Object methods on value types through inline SRTP functions. ([Issue #8098](https://github.com/dotnet/fsharp/issues/8098), [PR #19511](https://github.com/dotnet/fsharp/pull/19511))
* Narrow overload-resolution error ranges to the method name only instead of covering the entire expression. ([Issue #14284](https://github.com/dotnet/fsharp/issues/14284), [PR #19505](https://github.com/dotnet/fsharp/pull/19505))
* Fix attributes not resolved from opened namespaces in `namespace rec` / `module rec` scopes. ([Issue #7931](https://github.com/dotnet/fsharp/issues/7931), [PR #19502](https://github.com/dotnet/fsharp/pull/19502))
* Fix DU case names matching IWSAM member names no longer cause duplicate property entries. (Issue [#14321](https://github.com/dotnet/fsharp/issues/14321), [PR #19341](https://github.com/dotnet/fsharp/pull/19341))
* Fix DefaultAugmentation(false) duplicate entry in method table. (Issue [#16565](https://github.com/dotnet/fsharp/issues/16565), [PR #19341](https://github.com/dotnet/fsharp/pull/19341))
Expand Down
26 changes: 16 additions & 10 deletions src/Compiler/Checking/Expressions/CheckExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6634,7 +6634,6 @@ and TcTyparExprThen (cenv: cenv) overallTy env tpenv synTypar m delayed =
| DelayedDotLookup (ident :: rest, m2) :: delayed2 ->
let ad = env.eAccessRights
let tp, tpenv = TcTypar cenv env NoNewTypars tpenv synTypar
let mExprAndLongId = unionRanges synTypar.Range ident.idRange
let ty = mkTyparTy tp
let lookupKind = LookupKind.Expr LookupIsInstance.Ambivalent
let item, _rest = ResolveLongIdentInType cenv.tcSink cenv.nameResolver env.NameEnv lookupKind ident.idRange ad ident IgnoreOverrides TypeNameResolutionInfo.Default ty
Expand All @@ -6643,7 +6642,7 @@ and TcTyparExprThen (cenv: cenv) overallTy env tpenv synTypar m delayed =
| [] -> delayed2
| _ -> DelayedDotLookup (rest, m2) :: delayed2
CallNameResolutionSink cenv.tcSink (ident.idRange, env.NameEnv, item, emptyTyparInst, ItemOccurrence.Use, env.AccessRights)
TcItemThen cenv overallTy env tpenv ([], item, mExprAndLongId, [], AfterResolution.DoNothing) (Some ty) delayed3
TcItemThen cenv overallTy env tpenv ([], item, ident.idRange, [], AfterResolution.DoNothing) (Some ty) delayed3
//TcLookupItemThen cenv overallTy env tpenv mObjExpr objExpr objExprTy delayed item mItem rest afterResolution
| _ ->
let (SynTypar(_, q, _)) = synTypar
Expand Down Expand Up @@ -8632,7 +8631,7 @@ and TcNameOfExpr (cenv: cenv) env tpenv (synArg: SynExpr) =
let nameResolutionResult = ResolveLongIdentAsExprAndComputeRange cenv.tcSink cenv.nameResolver (rangeOfLid longId) ad env.eNameResEnv typeNameResInfo longId None
let resolvesAsExpr =
match nameResolutionResult with
| Result (_, item, _, _, _ as res)
| Result (tinstEnclosing, item, mItem, rest, afterRes)
when
(match item with
| Item.DelegateCtor _
Expand All @@ -8643,7 +8642,7 @@ and TcNameOfExpr (cenv: cenv) env tpenv (synArg: SynExpr) =
| _ -> true
| _ -> true) ->
let overallTy = match overallTyOpt with None -> MustEqual (NewInferenceType g) | Some t -> t
let _, _ = TcItemThen cenv overallTy env tpenv res None delayed
let _, _ = TcItemThen cenv overallTy env tpenv (tinstEnclosing, item, mItem, rest, afterRes) None delayed
true
| _ ->
false
Expand Down Expand Up @@ -8870,17 +8869,17 @@ and TcLongIdentThen (cenv: cenv) (overallTy: OverallTy) env tpenv (SynLongIdent(

let ad = env.eAccessRights
let typeNameResInfo = GetLongIdentTypeNameInfo delayed
let nameResolutionResult =
let (tinstEnclosing, item, mItem, rest, afterResolution) =
let maybeAppliedArgExpr = DelayedItem.maybeAppliedArgForPreferExtensionOverProperty delayed
ResolveLongIdentAsExprAndComputeRange cenv.tcSink cenv.nameResolver (rangeOfLid longId) ad env.eNameResEnv typeNameResInfo longId maybeAppliedArgExpr
|> ForceRaise
TcItemThen cenv overallTy env tpenv nameResolutionResult None delayed
TcItemThen cenv overallTy env tpenv (tinstEnclosing, item, mItem, rest, afterResolution) None delayed

//-------------------------------------------------------------------------
// Typecheck "item+projections"
//------------------------------------------------------------------------- *)

// mItem is the textual range covered by the long identifiers that make up the item
// mItem = range of the terminal identifier (for diagnostic and expression ranges)
and TcItemThen (cenv: cenv) (overallTy: OverallTy) env tpenv (tinstEnclosing, item, mItem, rest, afterResolution) staticTyOpt delayed =
let delayed = delayRest rest mItem delayed
match item with
Expand Down Expand Up @@ -9224,7 +9223,7 @@ and TcCtorItemThen (cenv: cenv) overallTy env item nm minfos tinstEnclosing tpen
item, minfos

minfosAfterTyArgs |> List.iter (fun minfo -> UnifyTypes cenv env mExprAndTypeArgs minfo.ApparentEnclosingType objTyAfterTyArgs)
TcCtorCall true cenv env tpenv overallTy objTyAfterTyArgs (Some mExprAndTypeArgs) itemAfterTyArgs false [arg] mExprAndArg otherDelayed (Some afterResolution)
TcCtorCall true cenv env tpenv overallTy objTyAfterTyArgs (Some mItem) itemAfterTyArgs false [arg] mExprAndArg otherDelayed (Some afterResolution)

| DelayedTypeApp(tyargs, _mTypeArgs, mExprAndTypeArgs) :: otherDelayed ->

Expand All @@ -9235,7 +9234,7 @@ and TcCtorItemThen (cenv: cenv) overallTy env item nm minfos tinstEnclosing tpen
CallNameResolutionSink cenv.tcSink (mExprAndTypeArgs, env.NameEnv, resolvedItem, emptyTyparInst, ItemOccurrence.Use, env.eAccessRights)

minfos |> List.iter (fun minfo -> UnifyTypes cenv env mExprAndTypeArgs minfo.ApparentEnclosingType objTy)
TcCtorCall true cenv env tpenv overallTy objTy (Some mExprAndTypeArgs) item false [] mExprAndTypeArgs otherDelayed (Some afterResolution)
TcCtorCall true cenv env tpenv overallTy objTy (Some mItem) item false [] mExprAndTypeArgs otherDelayed (Some afterResolution)

| _ ->

Expand Down Expand Up @@ -9960,7 +9959,7 @@ and TcMethodApplicationThen
callerTyArgs // The return type of the overall expression including "delayed"
objArgs // The 'obj' arguments in obj.M(...) and obj.M, if any
m // The range of the object argument or whole application. We immediately union this with the range of the arguments
mItem // The range of the item that resolved to the method name
mItem // The range of the terminal identifier that resolved to the method name
methodName // string, name of the method
ad // accessibility rights of the caller
mut // what do we know/assume about whether this method will mutate or not?
Expand Down Expand Up @@ -10463,6 +10462,13 @@ and TcMethodApplication

let result, errors = ResolveOverloadingForCall denv cenv.css mMethExpr methodName callerArgs ad postArgumentTypeCheckingCalledMethGroup true returnTy

// #14284 - mItem already carries the narrow terminal-identifier range, so rewrap to it
let errors =
match errors with
| ErrorResult(warns, UnresolvedOverloading(denvErr, callerArgsErr, failure, _mWide)) ->
ErrorResult(warns, UnresolvedOverloading(denvErr, callerArgsErr, failure, mItem))
| other -> other

match afterResolution, result with
| AfterResolution.DoNothing, _ -> ()

Expand Down
38 changes: 21 additions & 17 deletions src/Compiler/Checking/NameResolution.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4195,13 +4195,19 @@ let private ResolveExprDotLongIdent (ncenv: NameResolver) m ad nenv ty (id: Iden
ForceRaise adhocDotSearchAccessible

let ComputeItemRange wholem (lid: Ident list) rest =
match rest with
| [] -> wholem
| _ ->
let ids = List.truncate (max 0 (lid.Length - rest.Length)) lid
match ids with
let itemRange =
match rest with
| [] -> wholem
| _ -> rangeOfLid ids
| _ ->
let ids = List.truncate (max 0 (lid.Length - rest.Length)) lid
match ids with
| [] -> wholem
| _ -> rangeOfLid ids
let itemIdentRange =
match rest, lid with
| [], _ :: _ -> (List.last lid).idRange
| _ -> itemRange
itemRange, itemIdentRange

/// Filters method groups that will be sent to Visual Studio IntelliSense
/// to include only static/instance members
Expand Down Expand Up @@ -4249,7 +4255,7 @@ let ResolveLongIdentAsExprAndComputeRange (sink: TcResultsSink) (ncenv: NameReso
match ResolveExprLongIdent sink ncenv wholem ad nenv typeNameResInfo lid maybeAppliedArgExpr with
| Exception e -> Exception e
| Result (tinstEnclosing, item1, rest) ->
let itemRange = ComputeItemRange wholem lid rest
let itemRange, itemIdentRange = ComputeItemRange wholem lid rest

let item = FilterMethodGroups ncenv itemRange item1 true

Expand Down Expand Up @@ -4280,8 +4286,7 @@ let ResolveLongIdentAsExprAndComputeRange (sink: TcResultsSink) (ncenv: NameReso
// #16621
match refinedItem with
| Item.Property(_, pinfos, _) ->
let propIdentRange = if rest.IsEmpty then (List.last lid).idRange else itemRange
RegisterUnionCaseTesterForProperty sink propIdentRange pinfos
RegisterUnionCaseTesterForProperty sink itemIdentRange pinfos
| _ -> ()

let callSinkWithSpecificOverload (minfo: MethInfo, pinfoOpt: PropInfo option, tpinst) =
Expand All @@ -4308,7 +4313,7 @@ let ResolveLongIdentAsExprAndComputeRange (sink: TcResultsSink) (ncenv: NameReso
callSink (item, emptyTyparInst)
AfterResolution.DoNothing

success (tinstEnclosing, item, itemRange, rest, afterResolution)
success (tinstEnclosing, item, itemIdentRange, rest, afterResolution)

[<return: Struct>]
let (|NonOverridable|_|) namedItem =
Expand All @@ -4326,11 +4331,11 @@ let ResolveExprDotLongIdentAndComputeRange (sink: TcResultsSink) (ncenv: NameRes
| id :: rest ->
ResolveExprDotLongIdent ncenv wholem ad nenv ty id rest typeNameResInfo findFlag maybeAppliedArgExpr
| _ -> error(InternalError("ResolveExprDotLongIdentAndComputeRange", wholem))
let itemRange = ComputeItemRange wholem lid rest
resInfo, item, rest, itemRange
let itemRange, itemIdentRange = ComputeItemRange wholem lid rest
resInfo, item, rest, itemRange, itemIdentRange

// "true" resolution
let resInfo, item, rest, itemRange = resolveExpr findFlag
let resInfo, item, rest, itemRange, itemIdentRange = resolveExpr findFlag
ResolutionInfo.SendEntityPathToSink(sink, ncenv, nenv, ItemOccurrence.Use, ad, resInfo, ResultTyparChecker(fun () -> CheckAllTyparsInferrable ncenv.amap itemRange item))

// Record the precise resolution of the field for intellisense/goto definition
Expand All @@ -4345,7 +4350,7 @@ let ResolveExprDotLongIdentAndComputeRange (sink: TcResultsSink) (ncenv: NameRes
| _, NonOverridable() -> item, itemRange, false
| FindMemberFlag.IgnoreOverrides, _
| FindMemberFlag.DiscardOnFirstNonOverride, _ ->
let _, item, _, itemRange = resolveExpr FindMemberFlag.PreferOverrides
let _, item, _, itemRange, _itemIdentRange = resolveExpr FindMemberFlag.PreferOverrides
item, itemRange, true

let callSink (refinedItem, tpinst) =
Expand All @@ -4356,8 +4361,7 @@ let ResolveExprDotLongIdentAndComputeRange (sink: TcResultsSink) (ncenv: NameRes
// #16621
match refinedItem with
| Item.Property(_, pinfos, _) ->
let propIdentRange = if rest.IsEmpty then (List.last lid).idRange else itemRange
RegisterUnionCaseTesterForProperty sink propIdentRange pinfos
RegisterUnionCaseTesterForProperty sink itemIdentRange pinfos
| _ -> ()

let callSinkWithSpecificOverload (minfo: MethInfo, pinfoOpt: PropInfo option, tpinst) =
Expand All @@ -4378,7 +4382,7 @@ let ResolveExprDotLongIdentAndComputeRange (sink: TcResultsSink) (ncenv: NameRes
callSink (unrefinedItem, emptyTyparInst)
AfterResolution.DoNothing

item, itemRange, rest, afterResolution
item, itemIdentRange, rest, afterResolution


//-------------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions src/Compiler/Checking/NameResolution.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,7 @@ val internal ResolvePartialLongIdentToClassOrRecdFields:
val internal ResolveRecordOrClassFieldsOfType: NameResolver -> range -> AccessorDomain -> TType -> bool -> Item list

/// Resolve a long identifier occurring in an expression position.
/// Also returns the terminal identifier range for error diagnostics (#14284).
val internal ResolveLongIdentAsExprAndComputeRange:
sink: TcResultsSink ->
ncenv: NameResolver ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ module AccessibilityAnnotations_Basic =
|> verifyCompile
|> shouldFail
|> withDiagnostics [
(Error 629, Line 11, Col 24, Line 11, Col 41, "Method 'MemberwiseClone' is not accessible from this code location")
(Error 629, Line 11, Col 26, Line 11, Col 41, "Method 'MemberwiseClone' is not accessible from this code location")
]

//SOURCE=E_MoreAccessibleBaseClass01.fs # E_MoreAccessibleBaseClass01.fs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,9 +268,9 @@ module CustomAttributes_AttributeUsage =
|> verifyCompile
|> shouldFail
|> withDiagnostics [
(Error 685, Line 14, Col 1, Line 14, Col 6, "The generic function 'Foo' must be given explicit type argument(s)")
(Error 685, Line 26, Col 1, Line 26, Col 6, "The generic function 'Foo' must be given explicit type argument(s)")
(Error 685, Line 28, Col 1, Line 28, Col 6, "The generic function 'Foo' must be given explicit type argument(s)")
(Error 685, Line 14, Col 3, Line 14, Col 6, "The generic function 'Foo' must be given explicit type argument(s)")
(Error 685, Line 26, Col 3, Line 26, Col 6, "The generic function 'Foo' must be given explicit type argument(s)")
(Error 685, Line 28, Col 3, Line 28, Col 6, "The generic function 'Foo' must be given explicit type argument(s)")
]

// SOURCE=E_RequiresExplicitTypeArguments02.fs SCFLAGS="--test:ErrorRanges" # E_RequiresExplicitTypeArguments02.fs
Expand All @@ -280,7 +280,7 @@ module CustomAttributes_AttributeUsage =
|> verifyCompile
|> shouldFail
|> withDiagnostics [
(Error 685, Line 20, Col 5, Line 20, Col 10, "The generic function 'Foo' must be given explicit type argument(s)")
(Error 685, Line 20, Col 7, Line 20, Col 10, "The generic function 'Foo' must be given explicit type argument(s)")
]

// SOURCE=E_WithBitwiseOr01.fsx SCFLAGS="--test:ErrorRanges -a" # E_WithBitwiseOr01.fsx
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
neg_invalid_constructor.fs (3,29)-(3,56) typecheck error A unique overload for method 'ImmutableStack`1' could not be determined based on type information prior to this program point. A type annotation may be needed.
neg_invalid_constructor.fs (3,29)-(3,43) typecheck error A unique overload for method 'ImmutableStack`1' could not be determined based on type information prior to this program point. A type annotation may be needed.

Known type of argument: 'a list

Candidates:
- new: col: 'b -> ImmutableStack<'a>
- private new: items: 'a list -> ImmutableStack<'a>
neg_invalid_constructor.fs (4,93)-(4,111) typecheck error A unique overload for method 'ImmutableStack`1' could not be determined based on type information prior to this program point. A type annotation may be needed.
neg_invalid_constructor.fs (4,93)-(4,107) typecheck error A unique overload for method 'ImmutableStack`1' could not be determined based on type information prior to this program point. A type annotation may be needed.

Known type of argument: 'a list

Candidates:
- new: col: 'b -> ImmutableStack<'a>
- private new: items: 'a list -> ImmutableStack<'a>
neg_invalid_constructor.fs (7,30)-(7,60) typecheck error A unique overload for method 'ImmutableStack`1' could not be determined based on type information prior to this program point. A type annotation may be needed.
neg_invalid_constructor.fs (7,30)-(7,44) typecheck error A unique overload for method 'ImmutableStack`1' could not be determined based on type information prior to this program point. A type annotation may be needed.

Known type of argument: 'a list

Expand Down
Loading
Loading