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

Anonymous-Params-delegate is generated incorrectly with AllowRefStructFlag #74823

Closed
bernd5 opened this issue Aug 20, 2024 · 3 comments · Fixed by #74914
Closed

Anonymous-Params-delegate is generated incorrectly with AllowRefStructFlag #74823

bernd5 opened this issue Aug 20, 2024 · 3 comments · Fixed by #74914

Comments

@bernd5
Copy link
Contributor

bernd5 commented Aug 20, 2024

Version Used:

Steps to Reproduce:

Compile the following code:

var counter = Counter;
counter.Invoke();

void Counter(params int[] arr)
{
}

Expected Behavior:
The compiler should generate an unspeakable delegate type like:

[CompilerGenerated]
internal delegate void <>f__AnonymousDelegate0<T1>(params T1[] arg);

Actual Behavior:

It generates code like:

[CompilerGenerated]
internal delegate void <>f__AnonymousDelegate0<T1>(params T1[] arg) where T1: allows ref struct;

If you look in dotPeek for example and have a look at the TypeParameter flags you can see 0x0020 is set.

grafik

The value is defined here: it means allows ref struct

@jjonescz
Copy link
Member

Why would that be incorrect? Is anything broken by the compiler generating the delegate with allows ref struct?

Btw, the behavior follows the feature proposal:

If target runtime supports allows ref struct constraints, generic anonymous delegate types will include allows ref struct constraint for their type parameters. This will enable substitution of those type parameters with ref struct types and other type parameters with allows ref struct constraint.

@bernd5
Copy link
Contributor Author

bernd5 commented Aug 21, 2024

It is correct without usage as array element type.

E.g.:

internal delegate void <>f__AnonymousDelegate0<T1>(T1 arg) where T1: allows ref struct;

would be very well.

But

internal delegate void <>f__AnonymousDelegate0<T1>(params T1[] arg) where T1 : allows ref struct;

violates the following part of the proposal:

A type parameter bound by allows ref struct has all of the behaviors of a ref struct type:

Instances of it cannot be boxed
Instances participate in lifetime rules like a normal ref struct
The type parameter cannot be used in static fields, elements of an array, etc ...
Instances can be marked with scoped

Any usage of the delegate with an ref-like type as typeargument would be invalid. Currently the runtime simply does not care (and roslyn enforces that such delegate types can't be declared by a user).

E.g.

internal delegate void SomeDelegate0<T1>(params T1[] arg) where T1 : allows ref struct;

emits the following diagnostic: CS0611: Array elements cannot be of type T1

@jaredpar jaredpar added Bug New Feature - RefStructInterfaces and removed untriaged Issues and PRs which have not yet been triaged by a lead labels Aug 21, 2024
@jaredpar jaredpar added this to the 17.12 milestone Aug 21, 2024
@jaredpar
Copy link
Member

Think that part of the spec needs to be limited to using allows ref struct where it would be legal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment