Skip to content

Handle nullable-unwrapped generic parameter values#127305

Open
MichalStrehovsky wants to merge 3 commits intodotnet:mainfrom
MichalStrehovsky:nullableunwrap
Open

Handle nullable-unwrapped generic parameter values#127305
MichalStrehovsky wants to merge 3 commits intodotnet:mainfrom
MichalStrehovsky:nullableunwrap

Conversation

@MichalStrehovsky
Copy link
Copy Markdown
Member

Introduce NullableUnwrappedGenericParameterValue to represent a typeof(T) that was unwrapped via Nullable.GetUnderlyingType.

This fixes an issue where typeof(Gen<>).MakeGenericType(Nullable.GetUnderlyingType(typeof(T))) would make ILC precompile Gen<T>, not produce a warning, and then fail at runtime because we actually need Gen<Nullable<T>>.

Cc @dotnet/illink

Introduce NullableUnwrappedGenericParameterValue to represent a typeof(T) that was unwrapped via Nullable.GetUnderlyingType.
Copilot AI review requested due to automatic review settings April 22, 2026 23:33
@dotnet-policy-service dotnet-policy-service Bot added the linkable-framework Issues associated with delivering a linker friendly framework label Apr 22, 2026
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @agocke, @dotnet/ilc-contrib
See info in area-owners.md if you want to be subscribed.

@MichalStrehovsky
Copy link
Copy Markdown
Member Author

After many iterations on this with several models, the only "bug" this has is that:

static Type X<T>() where T : class
    => typeof(Gen<>).MakeGenericType(Nullable.GetUnderlyingType(typeof(T)))

static Type Y<T>() where T : Enum
    => typeof(Gen<>).MakeGenericType(Nullable.GetUnderlyingType(typeof(T)))

Previously didn't generate a warning, now it does generate warning, even though the codepath is actually trim safe (we know GetUnderlyingType will return null). I've decided not to fix this "regression".

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves trim/AOT dataflow modeling for the Nullable.GetUnderlyingType(typeof(T)) pattern by introducing a dedicated value kind to represent “nullable-unwrapped generic parameter” results, preventing incorrect generic instantiation assumptions and enabling the appropriate NativeAOT warning behavior.

Changes:

  • Add NullableUnwrappedGenericParameterValue to represent typeof(T) after Nullable.GetUnderlyingType unwrapping in the trim analysis value lattice.
  • Update trim-analysis logic to recognize constraint-based satisfactions (e.g., new() / Enum) through the new wrapper and to unwrap it for diagnostic formatting.
  • Add/linker tests covering the MakeGenericType(Nullable.GetUnderlyingType(typeof(T))) NativeAOT warning corner case and constraint propagation scenarios.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/NullableAnnotations.cs Adds new constraint-focused test cases for Nullable.GetUnderlyingType(typeof(T)) flows.
src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MakeGenericDataflowIntrinsics.cs Adds a regression test expecting NativeAOT-specific IL3050 for the nullable unwrapping + MakeGenericType corner case.
src/tools/illink/src/ILLink.Shared/TrimAnalysis/RequireDynamicallyAccessedMembersAction.cs Teaches DAM-requirement validation to treat the new wrapper like its underlying GenericParameterValue for constraint-based allowances.
src/tools/illink/src/ILLink.Shared/TrimAnalysis/NullableUnwrappedGenericParameterValue.cs Introduces the new value type representing a generic parameter after nullable unwrapping.
src/tools/illink/src/ILLink.Shared/TrimAnalysis/HandleCallAction.cs Produces NullableUnwrappedGenericParameterValue for Nullable.GetUnderlyingType when the input is a GenericParameterValue.
src/tools/illink/src/ILLink.Shared/Annotations.cs Unwraps the new wrapper when generating annotation-mismatch diagnostics (argument formatting).
src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/DiagnosticContext.cs Unwraps the new wrapper when mapping diagnostics back to Roslyn symbols/locations.

Copy link
Copy Markdown
Member

@sbomer sbomer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add the "regression" cases as tests too? Thank you!

Copilot AI review requested due to automatic review settings April 23, 2026 23:22
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-NativeAOT-coreclr linkable-framework Issues associated with delivering a linker friendly framework

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants