[mono] Check for additional implemented variant interfaces (#57086)
authorAleksey Kliger (λgeek) <alklig@microsoft.com>
Tue, 17 Aug 2021 14:23:31 +0000 (10:23 -0400)
committerGitHub <noreply@github.com>
Tue, 17 Aug 2021 14:23:31 +0000 (10:23 -0400)
commiteeee548ba69083cce4c2a8cfb9f7222355b2d1a0
treee363d9e93c2523913c761cb1ea96cc7c4135ed74
parentb4932783ca1ff1868054cc5061c66d8a2d90e2f3
[mono] Check for additional implemented variant interfaces (#57086)

* [class-setup-vtable] Use flags bitmask in check_interface_method_override

No funcitonal change yet.

* [class-setup-vtable] Check additional slots when explicitly implementing variant interfaces

If a class implements a variant interface, consider whether it is explicitly
implementing (as opposed to obtaining by being a subclass of some base class)
some variant interfaces.

Two examples:
public interface IFactory<out T> { T Get(); }
public class Foo {}
public class Bar : Foo {}
public class FooFactory : IFactory<Foo> { public Foo Get() => new Foo(); }
public class BarFactory : FooFactory, IFactory<Bar> { public new Bar Get() => new Bar(); }

In this case, BarFactory explicitly implements IFactory<Bar> and also
IFactory<Foo>.

Conversely for contravariant gparams:
interface ITaker<in T> { string Consume (T x); }
class Foo {}
class Bar : Foo {}
class BarTaker : ITaker<Bar> { public string Consume (Bar x) => "consumed Bar"; }
class FooTaker : BarTaker, ITaker<Foo> { public string Consume (Foo x) =>
"consumed Foo"; }

In this case FooTaker implements ITaker<Foo> but also ITaker<Bar>.

When this happens, the signature of the implementing method 'Bar
BarFactory:Get()' doesn't match the signature of the implemented interface
method 'Foo IFactory<Foo>:Get()'.

We should check the signature parameters of the candidate method and the
implemented method, but I think the interface setup code already checks this
for us.

Fixes https://github.com/dotnet/runtime/issues/48512

* oops, disable vtable tracing

* Use explicit variant interface to implement base type interfaces
src/mono/mono/metadata/class-setup-vtable.c