dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.38k stars 4.75k forks source link

[UnsafeAccessor] throws MissingFieldException on .NET 9 when used on unspeakable fields #109943

Open Sergio0694 opened 2 hours ago

Sergio0694 commented 2 hours ago

Description

Spotted while porting my ComputeSharp samples to .NET 9 (see here). It seems that [UnsafeAccessor] is broken in .NET 9 when used to access unspeakable fields (captured primary constructor parameters being a common example).

Reproduction Steps

using System.Runtime.CompilerServices;

Blah blah = new("Bob");

string name = Blah.GetName(in blah);

Console.WriteLine(name);

public readonly struct Blah(string name)
{
    public string EnsureCaptured => name;

    [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "<name>P")]
    public static extern ref readonly string GetName(ref readonly Blah value);
}

Expected behavior

Should work as expected.

Actual behavior

https://github.com/Sergio0694/ComputeSharp/pull/871

Regression?

Yes. Works fine on .NET 8.

Known Workarounds

None that I can think of.

Configuration

dotnet-policy-service[bot] commented 2 hours ago

Tagging subscribers to this area: @dotnet/area-system-runtime-compilerservices See info in area-owners.md if you want to be subscribed.

Sergio0694 commented 2 hours ago

@AaronRobinsonMSFT it seems the problem is the ref readonly return. If I change it to just ref, then it works on .NET 9 as well. I suppose I can use that as a workaround for now, but shouldn't that work too though? It was working fine on .NET 8, and it feels like it should? 🤔

AaronRobinsonMSFT commented 1 hour ago

It is possible this was fixed in https://github.com/dotnet/runtime/pull/109694. Can you check the nightly build?