Skip to content

Instantiation argument missing when calling devirtualized valuetype methods #51983

@MichalStrehovsky

Description

@MichalStrehovsky
using System;
using System.Runtime.CompilerServices;

class Program
{
    static int Main()
    {
        MyStruct<Atom> s = default;

        // RyuJIT can devirtualize this, but NoInlining prevents the inline
        // This checks that we properly pass the instantiation context to the shared generic method.
        return ((IFoo)s).GetTheType() == typeof(Atom) ? 100 : -1;
    }
}

interface IFoo
{
    Type GetTheType();
}

struct MyStruct<T> : IFoo
{
    [MethodImpl(MethodImplOptions.NoInlining)]
    Type IFoo.GetTheType() => typeof(T);
}

class Atom { }

Compile above with crossgen2 (optimizations on, default settings otherwise).

Expected: returns 100
Observed:

Fatal error. Internal CLR error. (0x80131506)
   at MyStruct`1[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].IFoo.GetTheType()
   at <Program>$.<Main>$(System.String[])

This is caused by the JIT not generating the instantiation argument for the devirtualized call (I assume because of what crossgen2 told JIT to do).

Attempted to fix this in #51918 but this has other problems.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions