Uh oh!
There was an error while loading. Please reload this page.
Fix variant interface GVM resolution in managed type system - #130218
Conversation
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
There was a problem hiding this comment.
Pull request overview
This PR adjusts the CoreCLR managed TypeSystem’s interface virtual method resolution so that interface slot selection for instantiated interface GVMs is performed on the generic method definition (and then the method instantiation is reapplied), avoiding incorrect target selection when multiple variant-compatible interface instantiations exist.
Changes:
- Update
MetadataVirtualMethodAlgorithmto resolve interface GVMs using the method definition and then re-instantiate the resolved target. - Add a new variance-focused regression test (plus optimized variant) under
src/tests/JIT/Generics/Variance.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/coreclr/tools/Common/TypeSystem/Common/MetadataVirtualMethodAlgorithm.cs | Resolves instantiated interface GVMs via the definition for slot selection, then reapplies method instantiation. |
| src/tests/JIT/Generics/Variance/variance_generic_virtual.cs | Adds a regression test covering multiple variant-compatible interface instantiations with generic interface methods. |
| src/tests/JIT/Generics/Variance/variance_generic_virtual.csproj | Adds the new JIT test project. |
| src/tests/JIT/Generics/Variance/variance_generic_virtual_o.csproj | Adds an optimized build variant of the same test. |
Uh oh!
There was an error while loading. Please reload this page.
hez2010
commented
Jul 5, 2026
Test failure is #129871. @MichalStrehovsky Please take a look. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
MichalStrehovsky
commented
Jul 6, 2026
/azp run runtime-nativeaot-outerloop, runtime-coreclr crossgen2 outerloop, runtime-coreclr outerloop |
|
Azure Pipelines successfully started running 3 pipeline(s). |
MichalStrehovsky
commented
Jul 7, 2026
/ba-g filed #130286 on the crash in GC. it's unlikely to be related. |
Uh oh!
There was an error while loading. Please reload this page.
MichalStrehovsky
commented
Jul 7, 2026
I didn't merge copilot's spelling nit because then I can no longer approve or merge and that's not a good tradeoff. |
hez2010
commented
Jul 7, 2026
I didn't merge it either as that would require yet another long outerloop run and that's not a good tradeoff as well. |
Any eta on when this will be pushed into the a release? Currently dealing with this issue. What i found was when a class implements the same generic interface with different type arguments (e.g., Workaround that worked: The issue can be avoided by extracting the cast and method call into a separate generic helper method, which forces the JIT to resolve the correct interface method at runtime: privateIHaveLevelSettingsResolveParent<TParent>()whereTParent:class,ICanBeIdentified,ICanBeEnumerated_Base<TParent>,IHaveLevelSettings{if(thisisI_IsParent<TParent,LE_LevelSettings>typed){returntyped.ParentGaurantee();}thrownewServerException($"No I_IsParent<{typeof(TParent).Name}, LE_LevelSettings> implemented");}Code that triggered the bug: Direct casting and calling in a switch statement: // This incorrectly called the wrong interface methodAP_Instanceapplication=((I_IsParent<AP_Instance,LE_LevelSettings>)this).ParentGaurantee();thankyou |
The issue you described doesn't seem to be the same issue here. Here it's an AOT-specific issue after enabling GVM devirt in .NET 11 preview7 (not released yet). In .NET 10 we don't devirtualize any GVM at all. Can you share a standalone repro in a new issue so that we can take a look? |
When resolving an instantiated interface GVM, we passed down the method generic instantiation. However, interface slot selection needs to be done on the GVM definition, otherwise it could resolve to whatever the first compatible interface slot we saw. This can produce the incorrect devirtualized target when a type implements an interface GVM with multiple variant-compatible instantiations. Fixed it by stripping the method instantiation before resolving the interface slot. The CoreCLR native type system already handles such cases well so we don't have any issue there. Found this issue while I was working on GVM devirt for NAOT in #130202. See added tests for repro: previously it failed for the `CallOnBase` cases. Tests are added to both the managed type system and the normal JIT tests to prevent future regressions in either side. cc: @MichalStrehovsky
When resolving an instantiated interface GVM, we passed down the method generic instantiation. However, interface slot selection needs to be done on the GVM definition, otherwise it could resolve to whatever the first compatible interface slot we saw. This can produce the incorrect devirtualized target when a type implements an interface GVM with multiple variant-compatible instantiations.
Fixed it by stripping the method instantiation before resolving the interface slot.
The CoreCLR native type system already handles such cases well so we don't have any issue there.
Found this issue while I was working on GVM devirt for NAOT in #130202. See added tests for repro: previously it failed for the
CallOnBasecases. Tests are added to both the managed type system and the normal JIT tests to prevent future regressions in either side.cc: @MichalStrehovsky