return messages.Max(i => i.MessageID);
}
+ public static int test_0_partial_shared_method_in_nonshared_class () {
+ var c = new Class1<double> ();
+ return (c.Foo<string> (5).GetType () == typeof (Class1<string>)) ? 0 : 1;
+ }
+
class Message {
public int MessageID {
get; set;
public virtual void Do (Class2<T> t) {
t.Foo ();
}
+
+ public virtual object Foo<U> (T t) {
+ return new Class1<U> ();
+ }
}
public interface IFace1<T> {
#include "mini.h"
-//#define ALLOW_PARTIAL_SHARING TRUE
-#define ALLOW_PARTIAL_SHARING FALSE
+#define ALLOW_PARTIAL_SHARING TRUE
+//#define ALLOW_PARTIAL_SHARING FALSE
static void
mono_class_unregister_image_generic_subclasses (MonoImage *image, gpointer user_data);
return class;
}
+static gboolean
+generic_inst_is_sharable (MonoGenericInst *inst, gboolean allow_type_vars,
+ gboolean allow_partial)
+{
+ gboolean has_refs;
+ int i;
+
+ has_refs = FALSE;
+ for (i = 0; i < inst->type_argc; ++i) {
+ MonoType *type = inst->type_argv [i];
+
+ if (MONO_TYPE_IS_REFERENCE (type) || (allow_type_vars && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)))
+ has_refs = TRUE;
+ }
+
+ for (i = 0; i < inst->type_argc; ++i) {
+ MonoType *type = inst->type_argv [i];
+
+ if (MONO_TYPE_IS_REFERENCE (type) || (allow_type_vars && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)))
+ continue;
+
+ /*
+ * Allow non ref arguments, if there is at least one ref argument
+ * (partial sharing).
+ * FIXME: Allow more types
+ */
+ if (allow_partial && !type->byref && (((type->type >= MONO_TYPE_BOOLEAN) && (type->type <= MONO_TYPE_R8)) || (type->type == MONO_TYPE_I) || (type->type == MONO_TYPE_U)))
+ continue;
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
/*
* mono_is_partially_sharable_inst:
*
g_free (type_argv);
return mono_class_inflate_generic_class (class->generic_class->container_class, &shared_context);
+ } else if (!generic_inst_is_sharable (inst, TRUE, FALSE)) {
+ /* Happens for partially shared methods of nono-sharable generic class */
+ return class;
}
}
if (template)
return template;
- g_assert (get_shared_class (class) == class);
+ //g_assert (get_shared_class (class) == class);
template = alloc_template (class);
return mrgctx;
}
-static gboolean
-generic_inst_is_sharable (MonoGenericInst *inst, gboolean allow_type_vars,
- gboolean allow_partial)
-{
- gboolean has_refs;
- int i;
-
- has_refs = FALSE;
- for (i = 0; i < inst->type_argc; ++i) {
- MonoType *type = inst->type_argv [i];
-
- if (MONO_TYPE_IS_REFERENCE (type) || (allow_type_vars && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)))
- has_refs = TRUE;
- }
-
- for (i = 0; i < inst->type_argc; ++i) {
- MonoType *type = inst->type_argv [i];
-
- if (MONO_TYPE_IS_REFERENCE (type) || (allow_type_vars && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)))
- continue;
-
- /*
- * Allow non ref arguments, if there is at least one ref argument
- * (partial sharing).
- * FIXME: Allow more types
- */
- if (!type->byref && type->type == MONO_TYPE_I4 && has_refs && allow_partial)
- continue;
-
- return FALSE;
- }
-
- return TRUE;
-}
-
/*
* mono_generic_context_is_sharable_full:
* @context: a generic context