ashmind / SharpLab

.NET language playground
https://sharplab.io
BSD 2-Clause "Simplified" License
2.68k stars 195 forks source link

Call generic methods in IL is broken #1331

Open wherewhere opened 4 months ago

wherewhere commented 4 months ago

When I call generic method in IL, it just becomes something like call /* 2B000001 */.

What I wrote:

.class public C
{
    .method public static void M<+ .ctor class ([System.Runtime]System.Int32) T>()
    {
        ret
    }

    .method public static void M()
    {
        .entrypoint
        call void C::M<int64>()
        ret
    }
}

What it output:

.class public auto ansi C
    extends [mscorlib]System.Object
{
    // Methods
    .method public static 
        void M<class .ctor ([System.Runtime]System.Int32) +T> () cil managed 
    {
        // Method begins at RVA 0x2050
        // Code size 1 (0x1)
        .maxstack 8

        IL_0000: ret
    } // end of method C::M

    .method public static 
        void M () cil managed 
    {
        // Method begins at RVA 0x2054
        // Code size 6 (0x6)
        .maxstack 8
        .entrypoint

        IL_0000: call  /* 2B000001 */
        IL_0005: ret
    } // end of method C::M

} // end of class C
public class C
{
    public static void M<out T>() where T : class, int, new()
    {
    }

    public static void M()
    {
        //Discarded unreachable code: IL_0005
        /*Error: Read out of bounds.*/;
    }
}

The method is just gone. But it can be compiled when I switch the branch to x64, .NET Framework (x64) and Default at the first time (switch to other branch and switch back). Screenshot_20240406-192947_Chrome Canary.png

The code link: https://sharplab.io/#v2:EYLgtghglgdgNAGxFBAfAAgNgAQEECwAUAN5EC+RRAdAMYIQDOD2ADgK7AJQ3YDCRpQtmHYqYAKYAXABYB7ACasOXHg0kRJ3bADdZURQFkAPAGpRNSbIBO2Oo2YAKANoBlAJ5rxYKgCU2MTQkAXXdPbwBJAIBmACYASmwAFQA+BziiEWxBTMyrKQyRCiERAuExKTlFdk4tNQ0tXX1sAzTSrLbM9AAWDpEaCAQEHT1FXhAQY1hJTC7U9OKc7DzJNqKyIA

leppie commented 2 months ago

You could at least provide a simple repro with valid IL (I have no idea what you trying).

Here is one that produces the same call /* 2B000001 */ output.

.method static void M<T>()
{
    ret
}

.method static void Main()
{
    .entrypoint
    call void M<int64>()
    ret
}

https://sharplab.io/#v2:EYLgtghglgdgNAGxFBcAuyEB8CwAoAOjAFM0ALAewBMACAZzQjSgGMaA3CqWgWQB4AKgD4AFAEp8Ab3w1ZNAE6l8AX3z4ipSrQZNWHLr2gxxUmXIACAFjOyWEBAn3ca/WGgBsl0RLxyFSvFU8IA=

wherewhere commented 2 months ago

Screenshot_20240604-122507_Chrome Canary.png