-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Permit loading Explicit layouts with generics constrained to unmanaged #97526
Comments
+1 from me, this would be very useful. |
Sidenote: the |
That's inaccurate, and has been so since .NET 5.0 at least iirc, but probably even a bit earlier - link. |
My comment is about |
I swear I tested this in the past with generic methods, but presumably I must have tested it incorrectly. I think it would make more sense to allow it based on what the type parameters are in practice, as opposed to what they're constrained to anyway. So, what I would suggest, is that if the type parameters are |
That doesn't seem to be fully the case: Console.WriteLine(typeof(S<>).MakeGenericType(typeof(string)).FullName);
public struct S<T> where T : unmanaged
{
public T t;
} gives: System.ArgumentException: GenericArguments[0], 'System.String', on 'S`1[T]' violates the constraint of type 'T'.
---> System.TypeLoadException: GenericArguments[0], 'System.String', on 'S`1[T]' violates the constraint of type parameter 'T'.
at System.RuntimeTypeHandle.Instantiate(RuntimeType inst)
at System.RuntimeType.MakeGenericType(Type[] instantiation)
--- End of inner exception stack trace ---
at System.RuntimeType.ValidateGenericArguments(MemberInfo definition, RuntimeType[] genericArguments, Exception e)
at System.RuntimeType.MakeGenericType(Type[] instantiation)
at Program.<Main>$(String[] args)
at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr) |
Not sure I follow - I wrote unmanaged is same as struct constraint and yes, string is not a struct. |
Oh I thought you meant it as |
I wonder how this will interact with the ref/non-ref check in the runtime for something like this: [StructLayout(LayoutKind.Explicit)]
public struct S<T> where T : unmanaged
{
[FieldOffset(0)]
public T t;
[FieldOffset(8)]
public object i;
}
public struct TwoLongs {
public long a;
public long b;
} So |
I'd say that blocking such layouts with managed fields would be okay. I don't have any use cases for generic managed unions. |
My point isn't just that we need to block such structs. (But yes, we would need to block them) My point is that we don't have a check on generic instances right now, but if we allow an explicit layout on generics, we would need such a check. That might be fine - but right now the check isn't there. |
I'm curious about the use scenario for this. It makes me nervous since it would allow you to author a struct that looks memory and type safe but will be broken depending on the size of |
There are safe use cases. For example, when the field with the generic type is the last one in the memory layout, it won't be broken. Or, when the set of possible type arguments are limited and known at compile time, so the layout offsets can be calculated in a type safe way (see the problem below).
Although I'm not 100% familiar with the topic, e.g. this looks like a problem that could benefit from this. |
I dont' think this issue is about What we need is some logic in the runtime like this:
|
Currently the runtime errors out when trying to load such type:
with
System.TypeLoadException: Could not load type 'S`1' from assembly '_, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' because generic types cannot have explicit layout.
While determining proper offsets for generics is problematic due to unknown sizes, union types with all fields at 0 offset don't face such issues and since the generic is constrained to
unmanaged
, the runtime doesn't need to worry about managed types appearing in the layout.The text was updated successfully, but these errors were encountered: