Skip to content

Bugfix :: Nullness :: Bug selection - #19262

Merged
T-Gro merged 22 commits into
mainfrom
nullness-bugs
Feb 18, 2026
Merged

Bugfix :: Nullness :: Bug selection#19262
T-Gro merged 22 commits into
mainfrom
nullness-bugs

Conversation

@T-Gro

@T-GroT-Gro commented Feb 8, 2026

Copy link
Copy Markdown
Member

Description

Five nullness-related bug fixes and two regression tests for the F# compiler's nullable reference type checking.

Bug Fixes

  1. UoM ToString returns string for value types (fixesNullness issue - ToString on an integer with UoM takes nullness information from ValueType #17539)

    • int<kg>.ToString() now returns string instead of string | null
    • Added isMeasureableValueType helper in TypedTreeOps.fs
    • Extended the ToString return-type override in MethodCalls.fs to cover measureable value types
  2. Pipe operator nullness warning location (fixesNullness issue - Error shows on incorrect symbol when using |> #18013)

    • Nullness warnings from piped expressions (e.g. bar |> foo "mr") now point at the nullable argument (bar) instead of the pipe operator
    • Added NullnessCheckOfCapturedArg context to ConstraintSolver, propagated through CheckExpressions.fs
  3. AllowNullLiteral false positive on non-null instances (fixesNullness issue - No way to silence warning in e.g. ServiceCollection.AddSingleton if type allows null #18021)

    • MyClass() where MyClass has [<AllowNullLiteral>] no longer triggers a false nullness warning
    • Rewrote TypeNullIsExtraValueNew to check explicit nullness annotation first, only falling back to AllowNullLiteral when nullness is ambivalent
  4. not null constraint on type extensions (fixesNullness issue – Invalid type constraint resolution on ILookup #18334)

    • type ILookup<'Key, 'Value when 'Key : not null> with ... no longer errors
    • Added typarsAEquivWithAddedNotNullConstraintsAllowed for extension checks
    • Fixed letrec binding fixup to strip/restore extra not-null constraints during CheckTypars
  5. Tuple null elimination over-inference (fixesNullness issue - type check in multi-match expressions doesn't eliminate null #19042)

    • match x, y with | null, _ -> ... | s, 5 -> test s no longer over-infers non-null when non-wild patterns restrict non-nullable elements
    • Simplified the tuple null elimination condition

Regression Tests (no code changes, tests only)

Changed Files (13 total)

Source (10 files):

  • src/Compiler/Checking/CheckDeclarations.fs
  • src/Compiler/Checking/ConstraintSolver.fs + .fsi
  • src/Compiler/Checking/Expressions/CheckExpressions.fs
  • src/Compiler/Checking/MethodCalls.fs
  • src/Compiler/Driver/CompilerDiagnostics.fs
  • src/Compiler/Symbols/FSharpDiagnostic.fs
  • src/Compiler/TypedTree/TypedTreeOps.fs + .fsi

Tests (3 files):

  • tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableReferenceTypesTests.fs (704 lines added)
  • 3 BSL files updated for changed error locations/baselines

Release notes:

  • docs/release-notes/.FSharp.Compiler.Service/10.0.300.md

@github-actions

github-actionsBot commented Feb 8, 2026

Copy link
Copy Markdown
Contributor

✅ No release notes required

@T-Gro
T-Groforce-pushed the nullness-bugs branch 8 times, most recently from ce5d2f0 to 052d236CompareFebruary 8, 2026 22:23
Fix#17539: UoM ToString on value types returns string instead of string|null
Fix#18013: Pipe operator nullness warning location points to nullable argument
Fix#18021: No false positive nullness warning for non-null AllowNullLiteral instances
Fix#18334: Allow 'not null' constraint on type extensions
Fix#19042: Multi-match tuple null elimination with restricting patterns
Also adds regression tests for #17727 (Option.toObj inference) and
#18034 (FSharpPlus monad CE with nullness).
@T-GroT-Gro changed the title Fix nullness bugs: #17539, #18013, #18021, #18334, #19042Bugfix :: Nullness :: Bug selectionFeb 9, 2026
T-Gro added 14 commits February 9, 2026 17:12
…date tests
- Delete explicitNullnessOfTy helper (unsound)
- Revert TypeNullIsExtraValueNew to main branch logic using stripTyparEqns,
tryTcrefOfAppTy, TypeHasAllowNull, nullnessOfTy, GetTyparTyIfSupportsNull
- Update 6 AllowNullLiteral tests (B1-B6) for new diagnostics
- Remove GitHub issue URL comments from test code
…yOverallType
Filter env.eContextInfo to only forward NullnessCheckOfCapturedArg context
to the constraint solver, passing NoContext for all other cases. This
prevents unintended side effects on non-nullness error formatting (e.g.
duplicated parse errors and expanded type mismatch messages in neg83.vsbsl).
…I (IsFromConstructor, KnownWithoutNullFromCtor)
… issues
- Remove Nullness.KnownFromConstructor (dead code: never constructed in production)
- Remove all handling branches in ConstraintSolver.fs, TypedTree.fs, TypedTreeBasics.fs
- Replace KnownFromConstructor-specific tests with equivalent Known WithoutNull tests
- Remove redundant comments in TypedTreeOps.fs
- Clean up blank line artifacts in .fsi files
…temThen
The proto/bootstrap build (netstandard2.0 with NO_TYPEPROVIDERS defined) fails
because 'let g = cenv.g' was moved outside the #if block but is only used
inside #if !NO_TYPEPROVIDERS code paths within TcCtorItemThen, causing
error FS1182 (unused value treated as error via --warnaserror).
@T-Gro
T-Gro requested a review from abonieFebruary 13, 2026 09:57
Comment threadsrc/Compiler/Checking/Expressions/CheckExpressions.fs Outdated
Co-authored-by: Adam Boniecki <20281641+abonie@users.noreply.github.com>
@T-Gro
T-Gro requested a review from abonieFebruary 18, 2026 14:54
@T-Gro
T-Gro enabled auto-merge (squash) February 18, 2026 14:54
@github-project-automationgithub-project-automationBot moved this from New to In Progress in F# Compiler and ToolingFeb 18, 2026
@T-Gro
T-Gro merged commit 176e33d into mainFeb 18, 2026
48 checks passed
@github-project-automationgithub-project-automationBot moved this from In Progress to Done in F# Compiler and ToolingFeb 18, 2026
@T-Gro
T-Gro deleted the nullness-bugs branch February 26, 2026 11:04
T-Gro added a commit that referenced this pull request Mar 2, 2026
- Restore docs/release-notes/.Language/11.0.md (DIM hierarchy notes from PR #19241)
- Restore docs/release-notes/.FSharp.Compiler.Service/10.0.300.md entries
(Nullness fixes PR #19262, graph-based checking PR #19280, semantic
classification PR #19311, type checker recovery PR #19314, overload
resolution cache)
- Add trailing newline to Operators.fs
- Remove untracked docs/RFC_Review.md review artifact
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment