Skip to content

Commit

Permalink
Fix support for parameters with generic constraints in Type.IsAssigna…
Browse files Browse the repository at this point in the history
…bleFrom (). Fixes #691119.
  • Loading branch information
vargaz committed May 2, 2011
1 parent 0492784 commit 3945aed
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 2 deletions.
23 changes: 22 additions & 1 deletion mcs/class/corlib/Test/System/TypeTest.cs
Expand Up @@ -255,8 +255,12 @@ private string genTypeName ()
private void ByrefMethod (ref int i, ref Derived1 j, ref Base1 k)
{
}

#if NET_2_0
private void GenericMethod<Q> (Q q)
public interface IFace {
}

private void GenericMethod<Q, T1> (Q q, T1 t) where T1 : IFace
{
}
#endif
Expand Down Expand Up @@ -330,6 +334,10 @@ public void TestIsAssignableFrom ()
mi = typeof (TypeTest).GetMethod ("GenericMethod", BindingFlags.Instance|BindingFlags.NonPublic);
Assert.IsTrue (mi.GetParameters ()[0].ParameterType.IsAssignableFrom (mi.GetParameters ()[0].ParameterType));
Assert.IsFalse (mi.GetParameters ()[0].ParameterType.IsAssignableFrom (typeof (int)));

// Tests for parameters with generic constraints
mi = typeof (TypeTest).GetMethod ("GenericMethod", BindingFlags.Instance|BindingFlags.NonPublic);
Assert.IsTrue (typeof (IFace).IsAssignableFrom (mi.GetParameters ()[1].ParameterType));
#endif
}

Expand Down Expand Up @@ -1614,6 +1622,19 @@ public void GetInterfaces ()
Assert.AreEqual (2, t2.Length);
}

[Test]
public void GetInterfacesGenericVarWithConstraints ()
{
var a = typeof (TypeTest).GetMethod ("GenericMethod");

var p = a.GetParameters ();
var i = p[0].ParameterType.GetElementType ();
i.GetInterfaces ();
}

public static void GenericMethod<T, T2> (T[] arr) where T: IComparable<T> {
}

public int AField;

[Test]
Expand Down
14 changes: 13 additions & 1 deletion mono/metadata/class.c
Expand Up @@ -6768,8 +6768,20 @@ mono_class_is_assignable_from (MonoClass *klass, MonoClass *oklass)
return klass == oklass;

if (MONO_CLASS_IS_INTERFACE (klass)) {
if ((oklass->byval_arg.type == MONO_TYPE_VAR) || (oklass->byval_arg.type == MONO_TYPE_MVAR))
if ((oklass->byval_arg.type == MONO_TYPE_VAR) || (oklass->byval_arg.type == MONO_TYPE_MVAR)) {
MonoGenericParam *gparam = oklass->byval_arg.data.generic_param;
MonoClass **constraints = mono_generic_container_get_param_info (gparam->owner, gparam->num)->constraints;
int i;

if (constraints) {
for (i = 0; constraints [i]; ++i) {
if (mono_class_is_assignable_from (klass, constraints [i]))
return TRUE;
}
}

return FALSE;
}

/* interface_offsets might not be set for dynamic classes */
if (oklass->reflection_info && !oklass->interface_bitmap)
Expand Down

0 comments on commit 3945aed

Please sign in to comment.