Skip to content

Static virtual reabstraction doesn't seem to work #71414

Closed
@MichalStrehovsky

Description

@MichalStrehovsky

I'm working on implementing this with NativeAOT and was looking at how it works in the VM.

Reproed with 7.0.100-preview.5.22307.18 SDK7.0.100-preview.7.22328.2:

Compile following program:

Call<BarClass>();

static void Call<T>() where T : IFoo => T.Frob();

interface IFoo
{
    static virtual void Frob() => throw null;
}

interface IBar : IFoo
{
    static void IFoo.Frob() => throw null;
}

interface IBaz : IFoo
{
    static abstract void IFoo.Frob();
}

class BarClass : IBar
{
}

This will throw at runtime:

Unhandled exception. System.TypeLoadException: Method implementation on an interface 'IBar' from assembly 'publishaot2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' must be a final method.
   at Program.<Main>$(String[] args)

Sure, looks like a Roslyn bug, but it's not what I'm after. (@AlekseyTs is this known?)

Fix the problem by ildasm-ing the assembly, adding the missing final and ILAsm-ing it back. Now the program works as expected.

Now, go back to the IL and change BarClass to implement IBaz instead of the IBar (Roslyn wouldn't allow compiling that because the method was reabstracted). Rebuild the IL.

Unhandled exception. System.MissingMethodException: Method not found: 'Void IFoo.Frob()'.
   at Program.<Main>$(String[] args)

This doesn't look like the experience we would want for reabstraction. For reference, the exception with instance default interface methods is (you have to go back to the IL this generates and replace IBar with IBaz in BarClass interface list, same as for the static virtual case because Roslyn doesn't allow compiling with the reabstraction):

IFoo foo = new BarClass();
foo.Frob();

interface IFoo
{
    virtual void Frob() => throw null;
}

interface IBar : IFoo
{
    void IFoo.Frob() => throw null;
}

interface IBaz : IFoo
{
    abstract void IFoo.Frob();
}

class BarClass : IBar
{
}

This will print a more descriptive message:

Unhandled exception. System.EntryPointNotFoundException: Could not call method 'IFoo.Frob()' on type 'IFoo' with an instance of 'BarClass' from assembly 'publishaot2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because there is no implementation for the method.
   at IFoo.Frob()
   at Program.<Main>$(String[] args)

Cc @trylek @davidwrighton

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions