Skip to content

Fix semantic classification errors for generics, slices, CEs, and open type#19939

Open
T-Gro wants to merge 7 commits into
mainfrom
fix/issue-19905
Open

Fix semantic classification errors for generics, slices, CEs, and open type#19939
T-Gro wants to merge 7 commits into
mainfrom
fix/issue-19905

Conversation

@T-Gro

@T-Gro T-Gro commented Jun 12, 2026

Copy link
Copy Markdown
Member

Fixes #19905

  • Type.Method<int>() / new T<args>(...) / T<args>.M(...) no longer classify <…> as Function/Type; span narrows to the identifier.
  • list[0..] trailing ] no longer classified as Function.
  • CE builder name inside [ for .. do builder { } ] classified as ComputationExpression, not Value.
  • open type T no longer always reported as unused.

Copilot and others added 6 commits June 12, 2026 15:10
Pin current behaviour of all 7 items reported in #19905. Items that
already pass on HEAD (item 1 via #19813, item 7 with the minimal repro)
become real regression tests. Items that still reproduce are marked
[<Fact(Skip = "Tracked in #19905 ...")>] and will be un-skipped (and
inverted) by their fix sprints.

No production code changes in this commit.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ot classified as Function (#19905)

In TcMethodItemThen, TcTypeItemThen, and SynExpr.New, CallNameResolutionSink was emitting Item.MethodGroup / Item.Types / Item.CtorGroup resolutions with the wide mExprAndTypeArgs / synObjTy.Range range covering 'Method<int>' / 'MailboxProcessor<int*int>' / 'MailboxProcessor<int>.Start'. The downstream classifier in SemanticClassification.fs then painted the entire span as Function/DisposableType.

Narrow the CNR ranges to the identifier-only ranges (mItem/mItemIdent for methods, the type's leading SynLongIdent for ctors via the new synTypeLeadingIdentRange helper, and rangeOfLid longId as the wholem for the recursive dot-lookup) so the classifier paints only the identifier and leaves the type-arg punctuation and inner type names to their own resolutions.

Updates Project11/17/18 symbol-use baselines and one neg/error-range baseline to reflect the narrower (more correct) ranges that flow from the narrower CNRs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…`]` as Function (#19905)

TcIndexingThen synthesized the GetSlice/SetSlice identifier with mWholeExpr as its range, causing the op_GetSlice CNR to span the entire `list[...]` expression including the closing `]`. The semantic classifier then painted that whole span as Method/Function.

Mark the synthesized identifier's range as synthetic for slice expressions (not regular indexing) so NotifyNameResolution drops the CNR. Regular `x.[n]` indexing keeps the visible range to preserve find-all-references on the implicit Item indexer (Project17 baselines unchanged).

Also swap the symmetric `range1` to `range2` in ExpandIndexArgs for the missing upper-bound branch (no behavioural change for classification - mkSynNoneExpr already makes the range synthetic - but matches the `Some` branch using range2 for the upper bound).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…19905)

`UnusedOpens.getUnusedOpens` only recorded symbol uses whose declaring entity was a namespace or module. Members imported by `open type T` have T as their declaring entity, so when the match between an open declaration's target and a symbol use's declaring entity is needed, the type was missing from the lookup dictionary.

Now records symbol uses against any declaring entity (namespace, module, or type) for both partitions returned by `splitSymbolUses`. The change is purely additive: `symbolUses2` still flows through the existing `RevealedSymbolsContains` path, while the dictionary lookup now also matches type entities for `open type`. Entity equality goes through `IsEffectivelySameAs` so type entities match themselves correctly.

Adds two new regression tests in `SemanticClassificationRegressions.fs`: one confirming `open type T` with no usage is still flagged unused, and one confirming plain `open System` is still flagged when unused.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…s ComputationExpression (#19905)

takeCustomBuilder in SemanticClassification.fs only handled the 2-element CNR-group case (Value + CustomBuilder). Inside a list/array comprehension, name resolution can record 3+ CNRs at the same range for the builder identifier; the existing code fell through, the first Item.Value hit won the dedup race, and the builder name was painted as a local value.

Generalize takeCustomBuilder to prefer any Item.CustomBuilder or Item.CustomOperation over Item.Value regardless of group size. Also apply the same grouping in the whole-file (range = None) code path so the basic `async { .. }` case is unaffected.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add one bullet per fixed item from the #19905 cluster under
docs/release-notes/.FSharp.Compiler.Service/11.0.100.md, ### Fixed.

Issue-comment draft is in .tools/ralph/issue-comment.md (not tracked);
the user will post it manually after pushing the fix commits.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

✅ No release notes required

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions github-actions Bot added the AI-Tooling-Check-Bypassed Tooling check: non-fork PR, not diff-analyzed label Jun 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI-Tooling-Check-Bypassed Tooling check: non-fork PR, not diff-analyzed

Projects

Status: New

Development

Successfully merging this pull request may close these issues.

VS Report: F# syntax highlighting errors

1 participant