-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
[API Proposal]: Add mechanism for indicating a method/constructor/property violates constraints #99788
Comments
Do we really want |
Is this attribute meant for everybody out there to use, or is it meant to be only used on the few methods on Span? |
My initial perspective was no and I planed to just mark it
|
Is runtime going to pay attention to the attribute? Aren't constraints checked anyway? |
I understand how the attribute applies to the Span case. I think the general use case needs more clarification. For example:
Does this compile? If it does compile, what is the runtime behavior of |
I assume the proposal is to suppress compile time generic constraints checks in the signature and in the body of the method/property. If that is the case, consider stating that explicitly. Do we want checks for other specific restrictions to be suppressed as well? For example, disallowing boxing for an "allows ref struct" type parameter isn't really a generic constraint check. Do we want the boxing be allowed as well? Some other "unsafe" operations? Do we want impact of the attribute be limited only to violations around "allows ref struct"? A very broad interpretation of the attribute might lead to some surprising consequences. For example. overload resolution might start reporting an ambiguity error for some calls, because candidates that would violate generic constraints (like a |
At the moment C# doesn't support "ref" modifier (and any other modifiers) for type arguments. And there is no plan to change that in the current release. |
I have edited my example to use Span instead. |
Or, perhaps, the assumption is wrong and the attribute is supposed to affect the signature only. The method body is supposed to obey all the constraints and restrictions. This option is much simpler, I think. |
If the compiler allows constraints violations in the signature, it has to allow them in the method body too. Otherwise, the Span case won't work. For example, We would need a constraint bridging feature to make it possible for the method body to obey all constraints and restrictions. |
@jkotas The JIT of |
@AlekseyTs Yes, that is the expectation. The runtime will do the check where appropriate - type load or method JIT time. |
Would it be deterministic failure? I think the behavior would be non-deterministic. For example, when the JIT sees This attribute gives Roslyn a permission to produce invalid IL. The problem is that the runtime behavior on invalid IL is undefined. We do not guarantee that the runtime is going to throw an exception or where it is going to throw the exception. Do we like that the behavior of methods marked with this attribute is undefined when called on invalid instantiation? If we do not like the undefined behavior, I see two options: |
Okay. So then it seems like going with option (1), which was the original plan, is the most appropriate. That plan will allow us to unblock the priority usage for @AlekseyTs I will update the spec and put out a PR for this soon. Let me know if you have any concerns. |
The |
Background and motivation
Implementing support for ByRefLike types as generic parameters exposes some existing APIs to unsafe behavior. The safety of these types is enforced at run-time, but violate compilation rules. This attribute let's existing APIs indicate the check will be handled at run-time and the compiler can ignore the potential violation. Additional details can be found in the design document - byreflike-generics.md.
Troublesome APIs:
Span<T>
public Span(T[]? array);
public Span(T[]? array, int start, int length);
public T[] ToArray();
public static implicit operator Span<T>(ArraySegment<T> segment);
public static implicit operator Span<T>(T[]? array);
ReadOnlySpan<T>
public ReadOnlySpan(T[]? array);
public ReadOnlySpan(T[]? array, int start, int length);
public T[] ToArray();
public static implicit operator ReadOnlySpan<T>(ArraySegment<T> segment);
public static implicit operator ReadOnlySpan<T>(T[]? array);
API Proposal
API Usage
Note the addition of the new ByRefLike constraint.
Alternative Designs
No response
Risks
No response
The text was updated successfully, but these errors were encountered: