You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[metadata] Fields whose types are gparams with a reference type constraint aren't blittlable. (mono#15761)
* [metadata] Fields whose types are gparams with a reference type constraint
aren't blittlable.
Don't try to layout the field to find out if it's blittable.
For gshared gparams, follow the blittability of the constraint.
Fixes certain recursive examples.
```
using System;
namespace TestRecursiveType
{
class Program
{
static void Main(string[] args)
{
SubClass subC = new SubClass();
Console.WriteLine(subC.GetTest());
}
}
public struct ValueTest<U>
{
// When U is instantiated with T, from BaseClass, we know it'll be a
// reference field, so we know the instantiation ValueTest<T> won't
// be blittable.
public readonly U value;
}
public abstract class BaseClass<T> where T : BaseClass<T>
{
public ValueTest<T> valueTest = default(ValueTest<T>);
}
public class SubClass : BaseClass<SubClass>
{
private String test = "test";
public string GetTest()
{
return test;
}
}
}
```
Fixesmono#15760
---
The failure is happening when we are doing mono_class_setup_fields ("BaseClass<T>") which needs to decide for each field whether it is blittable or not. So therefore we are trying to decide if ValueTest<T> (that is: the ValueTest<U> field inside BaseClass<T>) is blittable or not.
So we instantiate U with T.
Now to decide whether VaueTest<T> is blittable or not, we look at every field.
So then we look at T value.
To decide if T is blittable we first check if it's a reference type.
That check is currently inadequate for generic parameters - what the PR adds is the ability to see if theres a T : class constraint or a T : C constraint - where C is some class. As soon as we know that T's constraint will force it to be a reference type we can definitely say that T won't be blittable without having to initialize C, at all.
Previously, Mono would see that T is some kind of type for which it couldn't definitively decide that it's a reference type and it would call: mono_class_setup_fields (field_class) which would then try to setup the fields of the parent class BaseClass<T>. And that would hit the recursion check.
Unity cherry-pick note: Needed to bring MONO_CLASS_IS_INTERFACE_INTERNAL
and mono_class_get_valuetype_class forward
0 commit comments