Fix FS1182 not reported for unused let functions in class types#19805
Fix FS1182 not reported for unused let functions in class types#19805T-Gro wants to merge 3 commits into
Conversation
Removed the 'not v.IsCompiledAsTopLevel' guard in the local 'reportIfUnused' helper inside CheckIncrementalClasses.IncrClassReprInfo.ChooseRepresentation. Class-let function bindings are promoted to compiler-generated members, which sets IsCompiledAsTopLevel=true and previously silently suppressed FS1182. The helper is local to class-binding representation choice, so this change cannot introduce module-level false positives. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
❗ Release notes required
Warning No PR link found in some release notes, please consider adding it.
|
T-Gro
left a comment
There was a problem hiding this comment.
Review Summary
Looks good — Clean, well-scoped fix with thorough test coverage.
Analysis
The root cause is correctly identified: class let-functions are promoted to compiler-generated members via AdjustValToHaveValReprInfo (line 370), which sets ValReprInfo, making IsCompiledAsTopLevel = true. The old not v.IsCompiledAsTopLevel guard in reportIfUnused() then silently suppressed FS1182 for all class let-functions.
Why the fix is safe:
-
No module-level false positives —
reportIfUnused()is local toIncrClassReprInfo.ChooseRepresentation, which only processes class-level bindings. Module-level bindings go throughPostInferenceChecks.BindValwhich has its own independentIsCompiledAsTopLevelguard (line 315 in PostInferenceChecks.fs). -
No duplicate warnings — After
AdjustValToHaveValReprInforuns, the class let-function hasIsCompiledAsTopLevel = true, soPostInferenceChecks.BindValwon't also emit FS1182 (its conditionnot v.IsCompiledAsTopLevel || topLevelBindingHiddenBySignatureFile()evaluates tofalsefor class let-functions that aren't module bindings). -
HasBeenReferenced is reliable — This flag is set during type-checking when the value is referenced, and applies uniformly to let-values and let-functions.
Tests
Excellent coverage:
- RED tests pin the bug fix (unused let-function variants, mixed used/unused, static let-function)
- GUARD tests prevent regressions (used functions, recursive self-reference, module-level, underscore-prefixed)
Minor
The release notes entry should include the PR link (as noted by the bot): [PR #19805](https://github.com/dotnet/fsharp/pull/19805).
Summary
Fix #13849: FS1182 ("unused binding") warning was not reported for unused
letfunction bindings inside class types.Problem
Class-let function bindings are promoted to compiler-generated members, which sets
IsCompiledAsTopLevel=true. ThereportIfUnusedhelper inCheckIncrementalClasses.IncrClassReprInfo.ChooseRepresentationhad anot v.IsCompiledAsTopLevelguard that silently suppressed FS1182 for these bindings.Fix
Removed the
not v.IsCompiledAsTopLevelguard from the localreportIfUnusedhelper. This helper is scoped to class-binding representation choice, so the change cannot introduce module-level false positives.Test
Added test cases in
tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/warnon/warnon.fsverifying that FS1182 is correctly emitted for unusedletfunctions in class types.Fixes #13849