Skip to content

Fix semantic classification regressions (#19905)#19960

Open
T-Gro wants to merge 8 commits into
dotnet:mainfrom
T-Gro:fix/issue-19905
Open

Fix semantic classification regressions (#19905)#19960
T-Gro wants to merge 8 commits into
dotnet:mainfrom
T-Gro:fix/issue-19905

Conversation

@T-Gro

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

Copy link
Copy Markdown
Member

Fixes #19905

  • Delegate declarations no longer paint the synthetic Invoke/BeginInvoke/EndInvoke slot as Method across the entire delegate of … -> … clause.
  • CE builder identifier inside [ for … do builder { } ] classified as ComputationExpression, not Value.
  • Type.Method<int>() / new T<args>(…) / T<args>.M(…) no longer classify <…> as Method/Type; classification narrows to the identifier.
  • xs[0..] trailing ] no longer classified as Method (synthesized GetSlice lookup uses a synthetic range).

Copilot and others added 7 commits June 16, 2026 11:07
… classification

The semantic classifier was registering an Item.Value resolution for the
synthesized Invoke/BeginInvoke/EndInvoke members of an F# delegate type
declaration with a range covering the entire `delegate of ...` RHS, then
classifying it as Method. This caused the `delegate` keyword and parameter
syntax to be highlighted as a method in the IDE.

Guard the Item.Value branch in SemanticClassification when the value is an
Invoke/BeginInvoke/EndInvoke member of an F# delegate tycon. Real call sites
resolve via Item.MethodGroup, not Item.Value, so suppressing here does not
affect call-site classification.

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

Adds an anti-regression test using the issue's exact snippet. The fix
itself was delivered by the preceding commit (Item.Value guard in
SemanticClassification.fs); this commit only locks in coverage for
the tupled-parameter form.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…pending dotnet#19905 items 3+4 fix)

Test reproduces the bug on HEAD; skipped so the build is green.

Sprint 04 will unskip this test as part of the items 3+4 fix.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…unction/Type in method/ctor calls

TcMethodItemThen and TcCtorItemThen previously passed mExprAndTypeArgs
(covering ident + `<...>`) to CallNameResolutionSink for Item.MethodGroup /
Item.Types. SemanticClassification.fs then painted the entire span as
Method, swallowing the type-argument punctuation. Narrow the sink range to
the identifier (mItem / mItemIdent), matching the TP-static-args
fast path's existing convention.

For the generic-ctor shape `new Foo<int>(args)` (dotnet#19905 item 4 proper), the
ctor flows through TcNewExpr -> TcCtorCall -> ForNewConstructors with
mObjTy = synObjTy.Range, which covers `Foo<int>`. SemanticClassification
then paints the whole span as ConstructorForReferenceType / DisposableType.
Add a headTypeIdentRange helper that returns the type-name range for the
simple `Ident<...>` shape and use it at the three SynType call sites
(SynExpr.New, TcExprObjectExpr, Phase2AInherit). The helper is conservative:
nested forms like `Foo<int>.Bar` keep their existing wider range, so the
Project11 ProjectAnalysis baseline is unaffected. The change does narrow the
ctor symbol-use range for the simple generic ctor shape, which the existing
`No duplicate ctor symbol for generic object expression` test had pinned at
the wide range; that test is updated to the new narrow expectation. Its
anti-regression intent (no spurious shifted-line ctor entry) is preserved.

Item 6 (`MailboxProcessor<int>.Start(...)`) flows through a different code
path (TcTypeItemThen -> ResolveExprDotLongIdentAndComputeRange) and is not
covered by this change. Its regression test stays skipped with an explanatory
comment for a follow-up sprint.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… classified as ComputationExpression

Inside a [ for ... do builder { ... } ] list/array comprehension, TcComputationExpression emits the Item.CustomBuilder CNR for the builder identifier, but the same range can also carry an Item.Value CNR plus a duplicate Item.CustomBuilder CNR (because the comprehension causes TcComputationExpression to fire on the same builder twice). The classifier in SemanticClassification.fs only deduped buckets of size 1 or 2, and only when an explicit range was supplied, so the three-element bucket fell through to the default branch and the no-range path skipped the dedup pipeline entirely. The Value CNR therefore won the per-range dedup HashSet and the builder was classified as Value rather than ComputationExpression. Generalize takeCustomBuilder to collapse N greater-equal 2 buckets containing only Value, CustomBuilder, or CustomOperation entries down to the CE entries, and always run the groupBy and dedup pipeline regardless of whether the caller supplied a range filter.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… no longer classified as Function

Narrow the synthesized GetSlice/Item member resolution range so its classification span does not include the closing `]`. For `leftExpr[idx]` syntax the `[0..]` `mDot` argument is narrowed to its start position; `DelayedDotLookup` uses that narrow range while the synthesized ident keeps the wide range for accurate error messages, and the subsequent `PropagateThenTcDelayed` is widened to `mWholeExpr` so method-app error ranges remain accurate.

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

For `open type T` where T is a discriminated union, UnusedOpens'
revealedSymbols built the set of symbols brought into scope by iterating
NESTED entities only - so union cases of the opened entity itself were
never included. Static-member uses already worked via
`entity.MembersFunctionsAndValues`; this commit completes the picture
by also adding `entity.UnionCases` (when `T` is not
RequireQualifiedAccess) so that bare union-case access after
`open type T` is correctly credited to the open statement.

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

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

✅ No release notes required

@github-actions github-actions Bot added the AI-Tooling-Check-Scanned-Clean Tooling check: diff analyzed, no interesting infrastructure files label Jun 16, 2026
@T-Gro T-Gro changed the title Fix semantic classification regressions Fix semantic classification regressions (#19905) Jun 17, 2026
T-Gro pushed a commit that referenced this pull request Jun 17, 2026
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI-Tooling-Check-Scanned-Clean Tooling check: diff analyzed, no interesting infrastructure files

Projects

Status: New

Development

Successfully merging this pull request may close these issues.

VS Report: F# syntax highlighting errors

1 participant