*ifaces = g_hash_table_new (NULL, NULL);
if (g_hash_table_lookup (*ifaces, ic))
continue;
+ /* A gparam is not an implemented interface for the purposes of
+ * mono_class_get_implemented_interfaces */
+ if (mono_class_is_gparam (ic))
+ continue;
g_ptr_array_add (*res, ic);
g_hash_table_insert (*ifaces, ic, ic);
mono_class_init (ic);
for (i = 0; i < k->interface_count; i++) {
ic = k->interfaces [i];
- mono_class_init (ic);
+ /* A gparam does not have any interface_id set. */
+ if (! mono_class_is_gparam (ic))
+ mono_class_init (ic);
if (max_iid < ic->interface_id)
max_iid = ic->interface_id;
return mono_gparam_is_assignable_from (klass, oklass);
}
- if (MONO_CLASS_IS_INTERFACE (klass)) {
- 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;
+ /* This can happen if oklass is a tyvar that has a constraint which is another tyvar which in turn
+ * has a constraint which is a class type:
+ *
+ * class Foo { }
+ * class G<T1, T2> where T1 : T2 where T2 : Foo { }
+ *
+ * In this case, Foo is assignable from T1.
+ */
+ 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;
- }
+ if (constraints) {
+ for (i = 0; constraints [i]; ++i) {
+ if (mono_class_is_assignable_from (klass, constraints [i]))
+ return TRUE;
}
-
- return FALSE;
}
+ return mono_class_has_parent (oklass, klass);
+ }
+
+ if (MONO_CLASS_IS_INTERFACE (klass)) {
+
/* interface_offsets might not be set for dynamic classes */
if (mono_class_get_ref_info_handle (oklass) && !oklass->interface_bitmap) {
/*