Skip to content

Change TypedReference to standard ref struct semantics + support __makeref(ref struct) #65255

@steveharter

Description

@steveharter

To support ref struct with reflection (invoking and passing), the current 8.0 runtime plan for "safe" code is to leverage the existing TypedReference type to create and obtain ref struct references through the existing __makeref and __refvalue keywords.

In addition, TypedReference, being a stack-only construct, was added in 1.0 well before ref struct support (or byref-like types) and currently has more restricted compiler semantics than ref struct causing various limitations such as the inability to use ref struct as a field. This has been discussed as fixing or sunsetting "restricted types" in
https://github.com/dotnet/csharplang/blob/main/proposals/csharp-11.0/low-level-struct-improvements.md but this has not yet been addressed. See also #64811. cc @jaredpar

An alternative to supporting __makeref\__refvalue\__reftype with ref struct but much more expensive, is to support generic method parameters for ref struct. This could be added in the future and new static methods added to TypedReference to support that. However, based on prior discussions, adding support for __makeref et al. would be much easier for now.

Misc prototyping in the roslyn repro to remove the various compiler restrictions shows the 8.0 .NET runtime seems to handle the changes fine. Whether the runtime needs a new "feature switch" should be discussed -- I assume most runtimes, if they support ref struct and TypedReference and __makeref et al., should work as-is without additional work. cc @AaronRobinsonMSFT @jkotas

Version Used:
MSBuild17.4.0+18d5aef85 (C# 11)

Steps to Reproduce:
Sample code that repro some of the restricted usages of TypedReference but are valid with ref structs such as Span<object>.:

Console.WriteLine("Hello, World!");

Span<object> obj = default;
TypedReference tr = __makeref(obj); // CS1601: Cannot make reference to variable of type 'Span<object>'

public class MyClass
{
    public TypedReference _field; // CS0610: Field or property cannot be of type 'TypedReference'
    public TypedReference CallMe() => default;  // CS1599: The return type of a method, delegate, or function pointer cannot be 'TypedReference'
    public void CallMe(ref TypedReference tr) {} //  CS1601: Cannot make reference to variable of type 'TypedReference' error CS1601
}

Related Links:

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions