Skip to content

NativeAOT fails when calling through generic method with reference type using reflection #70951

Description

@davidfowl

Description

This might be by design by I don't know why so consider this both a bug and a question. I thought the only problems with using MakeGenericType and NativeAOT was the fact that value types needed unique code and that had to be generated ahead of time (since we don't have the fallback to universal shared generics). So for example, if I called MakeGenericMethod(reference type) it would be fine because that would use a shared implementation and wouldn't need to generate new code.

I found that to be mostly true until I tried to call a static abstract interface method via reflection.

Reproduction Steps

// Reflection for calling Parser.Parse<StringWrapper>("Hello");
var method = typeof(Parser).GetMethod(nameof(Parser.Parse), BindingFlags.Public | BindingFlags.Static)!.MakeGenericMethod(typeof(StringWrapper));
var r = (StringWrapper)method.Invoke(null, new[] { "Hello" })!;
Console.WriteLine(r);

class Parser
{
    // A generic callsite that lets use the static abstract interface method
    public static T Parse<T>(string s) where T : IParsable<T>
    {
        return T.Parse(s, CultureInfo.InvariantCulture);
    }
}

class StringWrapper : IParsable<StringWrapper>
{
    private string _data;
    public StringWrapper(string data)
    {
        _data = data;
    }

    public static StringWrapper Parse(string s, IFormatProvider? provider)
    {
        return new StringWrapper(s);
    }

    public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider, out StringWrapper result)
    {
        result = new(s);
        return true;
    }

    public override string ToString() => _data;
}

Expected behavior

This should print Hello to the console.

Actual behavior

I get this exception.

Unhandled Exception: EETypeRva:0x018EB208(System.Reflection.MissingRuntimeArtifactException): MakeGenericMethod() cannot create this generic method instantiation because no code was generated for it: 'Parser.Parse<StringWrapper>(System.String)'.
   at System.Reflection.Runtime.MethodInfos.RuntimeNamedMethodInfo`1.GetUncachedMethodInvoker(RuntimeTypeInfo[], MemberInfo) + 0x113
   at System.Reflection.Runtime.MethodInfos.RuntimeMethodInfo.get_MethodInvoker() + 0xa1
   at System.Reflection.Runtime.MethodInfos.RuntimeNamedMethodInfo`1.MakeGenericMethod(Type[]) + 0x183
   at Program.<Main>$(String[]) + 0x7b
   at WebApplication35!<BaseAddress>+0xc23123

Regression?

No response

Known Workarounds

No response

Configuration

.NET 7.0.100-preview.6.22314.18

Other information

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions