return 0;
}
- struct Pair<T1, T2> {
+ interface IConstrainedCalls {
+ Pair<int, int> vtype_ret<T, T2>(T t, T2 t2) where T: IReturnVType;
+ }
+
+ public interface IReturnVType {
+ Pair<int, int> return_vtype ();
+ }
+
+ public class CConstrainedCalls : IConstrainedCalls {
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public Pair<int, int> vtype_ret<T, T2>(T t, T2 t2) where T : IReturnVType {
+ return t.return_vtype ();
+ }
+ }
+
+ class ReturnVType : IReturnVType {
+ public Pair<int, int> return_vtype () {
+ return new Pair<int, int> () { First = 1, Second = 2 };
+ }
+ }
+
+ public static int test_0_constrained_vtype_ret () {
+ IConstrainedCalls c = new CConstrainedCalls ();
+ var r = c.vtype_ret<ReturnVType, int> (new ReturnVType (), 1);
+ if (r.First != 1 || r.Second != 2)
+ return 1;
+ return 0;
+ }
+
+ public struct Pair<T1, T2> {
public T1 First;
public T2 Second;
}
} else if (cmethod->klass->image != mono_defaults.corlib && !(cmethod->klass->flags & TYPE_ATTRIBUTE_INTERFACE) && !cmethod->klass->valuetype) {
/* 'The type parameter is instantiated as a reference type' case below. */
} else if (((cmethod->klass == mono_defaults.object_class) || (cmethod->klass->flags & TYPE_ATTRIBUTE_INTERFACE) || (!cmethod->klass->valuetype && cmethod->klass->image != mono_defaults.corlib)) &&
- (MONO_TYPE_IS_VOID (fsig->ret) || MONO_TYPE_IS_PRIMITIVE (fsig->ret) || MONO_TYPE_IS_REFERENCE (fsig->ret) || mini_is_gsharedvt_type (cfg, fsig->ret)) &&
+ (MONO_TYPE_IS_VOID (fsig->ret) || MONO_TYPE_IS_PRIMITIVE (fsig->ret) || MONO_TYPE_IS_REFERENCE (fsig->ret) || MONO_TYPE_ISSTRUCT (fsig->ret) || mini_is_gsharedvt_type (cfg, fsig->ret)) &&
(fsig->param_count == 0 || (!fsig->hasthis && fsig->param_count == 1) || (fsig->param_count == 1 && (MONO_TYPE_IS_REFERENCE (fsig->params [0]) || mini_is_gsharedvt_type (cfg, fsig->params [0]))))) {
MonoInst *args [16];
if (mini_is_gsharedvt_type (cfg, fsig->ret)) {
ins = handle_unbox_gsharedvt (cfg, mono_class_from_mono_type (fsig->ret), ins, &bblock);
- } else if (MONO_TYPE_IS_PRIMITIVE (fsig->ret)) {
+ } else if (MONO_TYPE_IS_PRIMITIVE (fsig->ret) || MONO_TYPE_ISSTRUCT (fsig->ret)) {
MonoInst *add;
/* Unbox */