Implement Static abstract members in interfaces
Currently, when compiling the following code using master branch:
using System;
using System.Collections.Generic;
using System.Text;
using Sys = Cosmos.System;
using System.Runtime.Versioning;
namespace net8test
{
public class Kernel: Sys.Kernel
{
[RequiresPreviewFeatures]
protected override void BeforeRun()
{
var test = new Test();
Test.InvokeBreakIl2cpu();
}
protected override void Run()
{
Console.Write("Input: ");
var input = Console.ReadLine();
Console.Write("Text typed: ");
Console.WriteLine(input);
}
}
public interface ITest<T>
{
[RequiresPreviewFeatures]
public static abstract bool DoThings<TOther>(TOther value);
}
public class Test : ITest<object>
{
[RequiresPreviewFeatures]
static bool ITest<object>.DoThings<TOther>(TOther t)
{
return true;
}
[RequiresPreviewFeatures]
public static void BreakIl2cpu<TImplementation, TOther>() where TImplementation : ITest<object>
{
TImplementation.DoThings<Test>(new Test());
}
[RequiresPreviewFeatures]
public static void InvokeBreakIl2cpu()
{
BreakIl2cpu<Test, object>();
}
}
}
Will result in the DoThings method not being emitted:
bin/cosmos/Debug/net6.0/net8test.asm:119142: error: undefined symbol `A0SystemBooleanA9A9net8testITest1A0SystemObjectDoThingsA9net8testTestA9net8testTest' (first use)
bin/cosmos/Debug/net6.0/net8test.asm:119142: error: (Each undefined symbol is reported only once.)
Add the following to your csproj to reproduce the issue:
<EnablePreviewFeatures>true</EnablePreviewFeatures>
<LangVersion>11</LangVersion>
This issue blocks .NET 8 support as types such as UInt32 rely on this feature.
bin/cosmos/Debug/net6.0/net8test.asm:119142: error: undefined symbol `A0SystemBooleanA9A9net8testITest1A0SystemObjectDoThingsA9net8testTestA9net8testTest' (first use) bin/cosmos/Debug/net6.0/net8test.asm:119142: error: (Each undefined symbol is reported only once.)
If I am reading this correctly, it seems like IL2CPU is looking at the interface implementations, not the class implementation, since on the symbol label it is using net8testITest not net8testTest.
This kind of call can only be done from the type that implements the interface?
TImplementation.DoThings<Test>(new Test());
if so then the solution would be to replace the call to the interface method to call the implemented method.
Another solution may be to treat this kind of interface method the same as virtual/abstract methods and treat this call as a callvirt