Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Static abstract members in interfaces #224

Open
MishaProductions opened this issue Aug 17, 2024 · 2 comments
Open

Implement Static abstract members in interfaces #224

MishaProductions opened this issue Aug 17, 2024 · 2 comments

Comments

@MishaProductions
Copy link
Member

MishaProductions commented Aug 17, 2024

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.

@Guillermo-Santos
Copy link

Guillermo-Santos commented Aug 18, 2024

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
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants