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

UnsafeAccessor does not work for generic constructors, .NET 9 #110054

Open
mgravell opened this issue Nov 21, 2024 · 3 comments
Open

UnsafeAccessor does not work for generic constructors, .NET 9 #110054

mgravell opened this issue Nov 21, 2024 · 3 comments
Labels
area-System.Runtime.CompilerServices untriaged New issue has not been triaged by the area owner

Comments

@mgravell
Copy link
Member

mgravell commented Nov 21, 2024

Description

This ticket suggests that this should work from 9.0 Preview 4, however this fails in 9.0 GA:

using System.Runtime.CompilerServices;

// this works fine
Console.WriteLine(Hack.CreateFoo());

// this doesn't work
Console.WriteLine(Hack.CreateBar<int>());

// this doesn't work
Bar<int> evil = (Bar<int>)RuntimeHelpers.GetUninitializedObject(typeof(Bar<int>));
Hack.HacketyHackHack(evil);
Console.WriteLine(evil);

static class Hack
{
    [UnsafeAccessor(UnsafeAccessorKind.Constructor)]
    internal static extern Foo CreateFoo();

    [UnsafeAccessor(UnsafeAccessorKind.Method, Name = ".ctor")]
    internal extern static void HacketyHackHack<T>(Bar<T> obj);

    [UnsafeAccessor(UnsafeAccessorKind.Constructor)]
    internal static extern Bar<T> CreateBar<T>();
}
class Foo
{
    private readonly string s = ".ctor has run";
    public override string ToString() => s;
    private Foo() { }
}
class Bar<T>
{
    private readonly string s = ".ctor has run; " + typeof(T).Name;
    public override string ToString() => s;
    private Bar() { }
}

Reproduction Steps

as above

Expected behavior

it works

Actual behavior

Unhandled exception. System.InvalidProgramException: Generic type constraints do not match.
   at Hack.CreateBar[T]()
   at Program.<Main>$(String[] args) in C:\Users\marcg\source\repos\ConsoleApp4\ConsoleApp4\Program.cs:line 7

Regression?

No response

Known Workarounds

No response

Configuration

No response

Other information

No response

@dotnet-issue-labeler dotnet-issue-labeler bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Nov 21, 2024
@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label Nov 21, 2024
@vcsjones vcsjones added area-System.Runtime.CompilerServices and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels Nov 21, 2024
@vcsjones
Copy link
Member

Where T is declared seems to matter. This works:

using System;
using System;
using System.Runtime.CompilerServices;

Hack<int>.CreateBar();

Bar<int> evil = (Bar<int>)RuntimeHelpers.GetUninitializedObject(typeof(Bar<int>));
Console.WriteLine(Hack<short>.CreateBar());
Hack<int>.HacketyHackHack(evil);
Console.WriteLine(evil);

static class Hack<T>
{

    [UnsafeAccessor(UnsafeAccessorKind.Method, Name = ".ctor")]
    internal extern static void HacketyHackHack(Bar<T> obj);

    [UnsafeAccessor(UnsafeAccessorKind.Constructor)]
    internal static extern Bar<T> CreateBar();
}

class Bar<T>
{
    private readonly string s = ".ctor has run; " + typeof(T).Name;
    public override string ToString() => s;
    private Bar() { }
}

@mgravell
Copy link
Member Author

Useful workaround @vcsjones ! (I haven't verified, but will do tomorrow)

@jkotas
Copy link
Member

jkotas commented Nov 22, 2024

cc @AaronRobinsonMSFT

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-System.Runtime.CompilerServices untriaged New issue has not been triaged by the area owner
Projects
None yet
Development

No branches or pull requests

3 participants