Uh oh!
There was an error while loading. Please reload this page.
Preserve information necessary to validate otherwise unused interface constraints in MakeGeneric - #132592
Open
MichalStrehovsky with Copilot wants to merge 5 commits into
Open
Preserve information necessary to validate otherwise unused interface constraints in MakeGeneric#132592MichalStrehovsky with Copilot wants to merge 5 commits into
MichalStrehovsky with Copilot wants to merge 5 commits into
Conversation
|
Azure Pipelines: 16 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
Contributor
Tagging subscribers to this area: @agocke, @dotnet/ilc-contrib |
Co-authored-by: MichalStrehovsky <13110571+MichalStrehovsky@users.noreply.github.com>
MichalStrehovsky
commented
Aug 21, 2026
Member
/azp run runtime-nativeaot-outerloop |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
This was referenced Aug 21, 2026
MichalStrehovsky
marked this pull request as ready for review
August 21, 2026 23:21
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
Contributor
There was a problem hiding this comment.
Pull request overview
Updates the NativeAOT ILCompiler dependency analysis so generic-constraint information (metadata + interface-use tracking) is preserved when reflection-driven MakeGenericType / MakeGenericMethod flows require constraint validation.
Changes:
- Preserve metadata dependencies for generic parameter constraints when generating type metadata.
- Ensure reflection-visible generic interface definitions also contribute
InterfaceUseso interface usage flows correctly across the scan/compile boundary. - Add constraint-driven dependency rooting for
MakeGenericType/MakeGenericMethoddataflow handling; update the regression test project to no longer depend onTestLibrary.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/TypeMetadataNode.cs | Adds metadata dependencies for generic parameter constraint types. |
| src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericDefinitionEETypeNode.cs | Ensures reflection-visible generic interface definitions also record InterfaceUse. |
| src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/HandleCallAction.cs | Roots dependencies based on interface constraints when MakeGeneric* intrinsics are recognized. |
| src/tests/Loader/classloader/StaticVirtualMethods/Regression/GitHub_130545.csproj | Removes now-unneeded TestLibrary project reference. |
| src/tests/Loader/classloader/StaticVirtualMethods/Regression/GitHub_130545.cs | Removes TestLibrary usage and the ActiveIssue skip. |
Suppressed comments (1)
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/HandleCallAction.cs:160
- Similarly for MakeGenericMethod: AddDependenciesFromConstraintUse runs before the arity check (
inst.Length == methodInstantiated.Instantiation.Length). For malformed instantiation arrays that will fail at runtime, this still roots constraint interfaces. Consider moving it into the arity-match block to avoid unnecessary dependency growth.
else if (!methodInstantiated.OwningType.IsGenericDefinition
&& TryGetMakeGenericInstantiation(_callingMethod, argumentValues[0], out Instantiation inst, out bool isExact))
{
AddDependenciesFromConstraintUse(_reflectionMarker, methodInstantiated.Instantiation);
if (inst.Length == methodInstantiated.Instantiation.Length)
{
methodInstantiated = methodInstantiated.MakeInstantiatedMethod(inst);
Comment on lines
77
to
83
| else if (TryGetMakeGenericInstantiation(_callingMethod, argumentValues[0], out Instantiation inst, out bool isExact)) | ||
| { | ||
| AddDependenciesFromConstraintUse(_reflectionMarker, typeInstantiated.Instantiation); | ||
| if (inst.Length == typeInstantiated.Instantiation.Length) | ||
| { | ||
| typeInstantiated = ((MetadataType)typeInstantiated).MakeInstantiatedType(inst); |
jkotas
approved these changes
Aug 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The problem was that we didn't preserve information necessary to do the constraint check in MakeGeneric:
InterfaceUsebut that only works in modes without scanner since InterfaceUse is not propagated across scanning/compilation boundary. Reflected types are. rt-sz measurement says this doesn't matter. GenericTypeDefinitionNode needed to report interface use to complete the "reflected type" -> "interface use" implication. Other EEType node already did that. rt-sz says this doesn't matter either.