IL2CPU icon indicating copy to clipboard operation
IL2CPU copied to clipboard

Implement Static abstract members in interfaces

Open MishaProductions opened this issue 1 year ago • 2 comments

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.

MishaProductions avatar Aug 17 '24 20:08 MishaProductions

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.

Guillermo-Santos avatar Aug 18 '24 01:08 Guillermo-Santos

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 image

Guillermo-Santos avatar Dec 05 '24 14:12 Guillermo-Santos