Skip to content

Fix #19657: MeasureAnnotatedAbbreviation over ref type + | null#19775

Open
T-Gro wants to merge 4 commits into
mainfrom
fix/nullness-umx
Open

Fix #19657: MeasureAnnotatedAbbreviation over ref type + | null#19775
T-Gro wants to merge 4 commits into
mainfrom
fix/nullness-umx

Conversation

@T-Gro
Copy link
Copy Markdown
Member

@T-Gro T-Gro commented May 20, 2026

Fixes #19657

SolveTypeIsReferenceType did not strip measure equations before calling isRefTy, unlike its siblings (SolveTypeIsNonNullableValueType, SolveTypeRequiresDefaultConstructor). This caused [<MeasureAnnotatedAbbreviation>] types over reference types (e.g. FSharp.UMX string<'m>) to be rejected by | null and 'T : not struct constraints.

T-Gro and others added 4 commits May 15, 2026 14:43
…eference type with | null

Add four tests in NullableReferenceTypesTests.fs covering:
- MeasureAnnotatedAbbreviation over string accepts | null in let bindings,
  parameters, returns, type abbreviations, and inline instantiations (fails today).
- MeasureAnnotatedAbbreviation over user-defined reference class accepts | null
  (fails today).
- MeasureAnnotatedAbbreviation over value types still rejects | null
  (non-regression, passes today).
- Nullness flow and not-null constraints work through the abbreviation
  (fails today; compilation does not reach the flow assertions).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
MeasureAnnotatedAbbreviation tycons over a reference type (e.g. UMX-style
`type string<[<Measure>] 'm> = string`) previously failed the reference-type
constraint check used by the `| null` syntax, producing FS0043. The surface
type is a TType_app over a MeasureableReprTycon, which isRefTy does not
recognise. Strip measure equations before testing reference semantics so the
underlying erased representation is consulted, consistent with TypeNullNever
and IsReferenceTyparTy. Value-type erasure still correctly fails FS0043.

Also corrects a Sprint 1 test expectation that listed a phantom diagnostic
which the compiler does not emit (the matched-on null case is fully covered).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Rename strippedTy -> underlyingTy for consistency with SolveTypeIsNonNullableValueType
- Condense comment to single line
- Add test: not-struct constraint satisfied by MeasureAnnotatedAbbreviation
- Add test: MAA over obj, interface, and chained abbreviation

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@T-Gro T-Gro requested a review from a team as a code owner May 20, 2026 12:47
@T-Gro T-Gro added AI-Auto-Resolve-CI Opt-in: LabelOps triages CI failures on this PR every 3h AI-Auto-Resolve-Conflicts Opt-in: LabelOps merges main into this PR and resolves conflicts every 3h labels May 20, 2026
@T-Gro T-Gro requested a review from abonie May 20, 2026 12:47
@github-actions
Copy link
Copy Markdown
Contributor

❗ Release notes required


✅ Found changes and release notes in following paths:

Warning

No PR link found in some release notes, please consider adding it.

Change path Release notes path Description
src/Compiler docs/release-notes/.FSharp.Compiler.Service/11.0.100.md No current pull request URL (#19775) found, please consider adding it

@github-actions github-actions Bot added the AI-Tooling-Check-Bypassed Tooling check: non-fork PR, not diff-analyzed label May 20, 2026
@github-actions github-actions Bot mentioned this pull request May 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI-Auto-Resolve-CI Opt-in: LabelOps triages CI failures on this PR every 3h AI-Auto-Resolve-Conflicts Opt-in: LabelOps merges main into this PR and resolves conflicts every 3h 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.

Nullness issue - units of measure don't work with nullables

1 participant