Move dynamic handling out of Binary::DoResolve to reduce stack size
[mono.git] / mcs / mcs / generic.cs
index 91eeadc751550b1cd0eb1639a57a0549737efc1c..972e3a8b1c4c5a9cc467b2cb60f0272f870c3aa8 100644 (file)
@@ -28,6 +28,50 @@ using System.Reflection.Emit;
 #endif
 
 namespace Mono.CSharp {
+       public class VarianceDecl
+       {
+               public VarianceDecl (Variance variance, Location loc)
+               {
+                       this.Variance = variance;
+                       this.Location = loc;
+               }
+
+               public Variance Variance { get; private set; }
+               public Location Location { get; private set; }
+
+               public static Variance CheckTypeVariance (TypeSpec t, Variance expected, IMemberContext member)
+               {
+                       var tp = t as TypeParameterSpec;
+                       if (tp != null) {
+                               var v = tp.Variance;
+                               if (expected == Variance.None && v != expected ||
+                                       expected == Variance.Covariant && v == Variance.Contravariant ||
+                                       expected == Variance.Contravariant && v == Variance.Covariant) {
+                                       ((TypeParameter) tp.MemberDefinition).ErrorInvalidVariance (member, expected);
+                               }
+
+                               return expected;
+                       }
+
+                       if (t.TypeArguments.Length > 0) {
+                               var targs_definition = t.MemberDefinition.TypeParameters;
+                               TypeSpec[] targs = TypeManager.GetTypeArguments (t);
+                               for (int i = 0; i < targs.Length; ++i) {
+                                       var v = targs_definition[i].Variance;
+                                       CheckTypeVariance (targs[i], (Variance) ((int) v * (int) expected), member);
+                               }
+
+                               return expected;
+                       }
+
+                       var ac = t as ArrayContainer;
+                       if (ac != null)
+                               return CheckTypeVariance (ac.Element, expected, member);
+
+                       return Variance.None;
+               }
+       }
+
        public enum Variance
        {
                //
@@ -235,7 +279,7 @@ namespace Mono.CSharp {
                                        // is valid with respect to T
                                        //
                                        if (tp.IsMethodTypeParameter) {
-                                               TypeManager.CheckTypeVariance (type, Variance.Contravariant, context);
+                                               VarianceDecl.CheckTypeVariance (type, Variance.Contravariant, context);
                                        }
 
                                        var tp_def = constraint_tp.MemberDefinition as TypeParameter;
@@ -312,7 +356,7 @@ namespace Mono.CSharp {
                                if (type.IsSealed || !type.IsClass) {
                                        context.Module.Compiler.Report.Error (701, loc,
                                                "`{0}' is not a valid constraint. A constraint must be an interface, a non-sealed class or a type parameter",
-                                               TypeManager.CSharpName (type));
+                                               type.GetSignatureForError ());
                                        continue;
                                }
 
@@ -358,24 +402,26 @@ namespace Mono.CSharp {
                
                Constraints constraints;
                GenericTypeParameterBuilder builder;
-               TypeParameterSpec spec;
+               readonly TypeParameterSpec spec;
 
-               public TypeParameter (int index, MemberName name, Constraints constraints, Attributes attrs, Variance variance)
+               public TypeParameter (int index, MemberName name, Constraints constraints, Attributes attrs, Variance Variance)
                        : base (null, name, attrs)
                {
                        this.constraints = constraints;
-                       this.spec = new TypeParameterSpec (null, index, this, SpecialConstraint.None, variance, null);
+                       this.spec = new TypeParameterSpec (null, index, this, SpecialConstraint.None, Variance, null);
                }
 
                //
                // Used by parser
                //
-               public TypeParameter (MemberName name, Attributes attrs, Variance variance)
+               public TypeParameter (MemberName name, Attributes attrs, VarianceDecl variance)
                        : base (null, name, attrs)
                {
-                       this.spec = new TypeParameterSpec (null, -1, this, SpecialConstraint.None, variance, null);
+                       var var = variance == null ? Variance.None : variance.Variance;
+                       this.spec = new TypeParameterSpec (null, -1, this, SpecialConstraint.None, var, null);
+                       this.VarianceDecl = variance;
                }
-
+               
                public TypeParameter (TypeParameterSpec spec, TypeSpec parentSpec, MemberName name, Attributes attrs)
                        : base (null, name, attrs)
                {
@@ -385,7 +431,7 @@ namespace Mono.CSharp {
                                TypeArguments = spec.TypeArguments
                        };
                }
-
+               
                #region Properties
 
                public override AttributeTargets AttributeTargets {
@@ -482,6 +528,8 @@ namespace Mono.CSharp {
                        }
                }
 
+               public VarianceDecl VarianceDecl { get; private set; }
+
                #endregion
 
                //
@@ -489,7 +537,7 @@ namespace Mono.CSharp {
                //
                // If partial type parameters constraints are not null and we don't
                // already have constraints they become our constraints. If we already
-               // have constraints, we must check that they're the same.
+               // have constraints, we must check that they're same.
                //
                public bool AddPartialConstraints (TypeDefinition part, TypeParameter tp)
                {
@@ -511,7 +559,7 @@ namespace Mono.CSharp {
 
                        // Copy constraint from resolved part to partial container
                        spec.SpecialConstraint = tp.spec.SpecialConstraint;
-                       spec.Interfaces = tp.spec.Interfaces;
+                       spec.InterfacesDefined = tp.spec.InterfacesDefined;
                        spec.TypeArguments = tp.spec.TypeArguments;
                        spec.BaseType = tp.spec.BaseType;
                        
@@ -545,15 +593,19 @@ namespace Mono.CSharp {
                // with SRE (by calling `DefineGenericParameters()' on the TypeBuilder /
                // MethodBuilder).
                //
-               public void Define (GenericTypeParameterBuilder type, TypeSpec declaringType, TypeContainer parent)
+               public void Create (TypeSpec declaringType, TypeContainer parent)
                {
                        if (builder != null)
                                throw new InternalErrorException ();
 
                        // Needed to get compiler reference
                        this.Parent = parent;
-                       this.builder = type;
                        spec.DeclaringType = declaringType;
+               }
+
+               public void Define (GenericTypeParameterBuilder type)
+               {
+                       this.builder = type;
                        spec.SetMetaInfo (type);
                }
 
@@ -579,8 +631,21 @@ namespace Mono.CSharp {
                        if (spec.InterfacesDefined != null)
                                builder.SetInterfaceConstraints (spec.InterfacesDefined.Select (l => l.GetMetaInfo ()).ToArray ());
 
-                       if (spec.TypeArguments != null)
-                               builder.SetInterfaceConstraints (spec.TypeArguments.Select (l => l.GetMetaInfo ()).ToArray ());
+                       if (spec.TypeArguments != null) {
+                               var meta_constraints = new List<MetaType> (spec.TypeArguments.Length);
+                               foreach (var c in spec.TypeArguments) {
+                                       //
+                                       // Inflated type parameters can collide with special constraint types, don't
+                                       // emit any such type parameter.
+                                       //
+                                       if (c.BuiltinType == BuiltinTypeSpec.Type.Object || c.BuiltinType == BuiltinTypeSpec.Type.ValueType)
+                                               continue;
+
+                                       meta_constraints.Add (c.GetMetaInfo ());
+                               }
+
+                               builder.SetInterfaceConstraints (meta_constraints.ToArray ());
+                       }
 
                        builder.SetGenericParameterAttributes (attr);
                }
@@ -760,23 +825,40 @@ namespace Mono.CSharp {
                        get {
                                if ((state & StateFlags.InterfacesExpanded) == 0) {
                                        if (ifaces != null) {
-                                               for (int i = 0; i < ifaces.Count; ++i ) {
-                                                       var iface_type = ifaces[i];
-                                                       if (iface_type.Interfaces != null) {
-                                                               if (ifaces_defined == null)
-                                                                       ifaces_defined = ifaces.ToArray ();
+                                               if (ifaces_defined == null)
+                                                       ifaces_defined = ifaces.ToArray ();
+
+                                               for (int i = 0; i < ifaces_defined.Length; ++i ) {
+                                                       var iface_type = ifaces_defined[i];
+                                                       var td = iface_type.MemberDefinition as TypeDefinition;
+                                                       if (td != null)
+                                                               td.DoExpandBaseInterfaces ();
 
+                                                       if (iface_type.Interfaces != null) {
                                                                for (int ii = 0; ii < iface_type.Interfaces.Count; ++ii) {
                                                                        var ii_iface_type = iface_type.Interfaces [ii];
-
                                                                        AddInterface (ii_iface_type);
                                                                }
                                                        }
                                                }
+                                       } else if (ifaces_defined == null) {
+                                               ifaces_defined = ifaces == null ? TypeSpec.EmptyTypes : ifaces.ToArray ();
                                        }
 
-                                       if (ifaces_defined == null)
-                                               ifaces_defined = ifaces == null ? TypeSpec.EmptyTypes : ifaces.ToArray ();
+                                       //
+                                       // Include all base type interfaces too, see ImportTypeBase for details
+                                       //
+                                       if (BaseType != null) {
+                                               var td = BaseType.MemberDefinition as TypeDefinition;
+                                               if (td != null)
+                                                       td.DoExpandBaseInterfaces ();
+
+                                               if (BaseType.Interfaces != null) {
+                                                       foreach (var iface in BaseType.Interfaces) {
+                                                               AddInterface (iface);
+                                                       }
+                                               }
+                                       }
 
                                        state |= StateFlags.InterfacesExpanded;
                                }
@@ -791,10 +873,7 @@ namespace Mono.CSharp {
                public TypeSpec[] InterfacesDefined {
                        get {
                                if (ifaces_defined == null) {
-                                       if (ifaces == null)
-                                               return null;
-
-                                       ifaces_defined = ifaces.ToArray ();
+                                       ifaces_defined = ifaces == null ? TypeSpec.EmptyTypes : ifaces.ToArray ();
                                }
 
                                return ifaces_defined.Length == 0 ? null : ifaces_defined;
@@ -802,7 +881,7 @@ namespace Mono.CSharp {
                        set {
                                ifaces_defined = value;
                                if (value != null && value.Length != 0)
-                                       ifaces = value;
+                                       ifaces = new List<TypeSpec> (value);
                        }
                }
 
@@ -1162,10 +1241,22 @@ namespace Mono.CSharp {
                public void InflateConstraints (TypeParameterInflator inflator, TypeParameterSpec tps)
                {
                        tps.BaseType = inflator.Inflate (BaseType);
+
+                       var defined = InterfacesDefined;
+                       if (defined != null) {
+                               tps.ifaces_defined = new TypeSpec[defined.Length];
+                               for (int i = 0; i < defined.Length; ++i)
+                                       tps.ifaces_defined [i] = inflator.Inflate (defined[i]);
+                       } else if (ifaces_defined == TypeSpec.EmptyTypes) {
+                               tps.ifaces_defined = TypeSpec.EmptyTypes;
+                       }
+
+                       var ifaces = Interfaces;
                        if (ifaces != null) {
                                tps.ifaces = new List<TypeSpec> (ifaces.Count);
                                for (int i = 0; i < ifaces.Count; ++i)
                                        tps.ifaces.Add (inflator.Inflate (ifaces[i]));
+                               tps.state |= StateFlags.InterfacesExpanded;
                        }
 
                        if (targs != null) {
@@ -1178,6 +1269,10 @@ namespace Mono.CSharp {
                public override MemberSpec InflateMember (TypeParameterInflator inflator)
                {
                        var tps = (TypeParameterSpec) MemberwiseClone ();
+#if DEBUG
+                       tps.ID += 1000000;
+#endif
+
                        InflateConstraints (inflator, tps);
                        return tps;
                }
@@ -1198,8 +1293,8 @@ namespace Mono.CSharp {
                        if (BaseType.BuiltinType != BuiltinTypeSpec.Type.Object && BaseType.BuiltinType != BuiltinTypeSpec.Type.ValueType)
                                cache.AddBaseType (BaseType);
 
-                       if (ifaces != null) {
-                               foreach (var iface_type in Interfaces) {
+                       if (InterfacesDefined != null) {
+                               foreach (var iface_type in InterfacesDefined) {
                                        cache.AddInterface (iface_type);
                                }
                        }
@@ -1210,8 +1305,11 @@ namespace Mono.CSharp {
                                        if (b_type.BuiltinType != BuiltinTypeSpec.Type.Object && b_type.BuiltinType != BuiltinTypeSpec.Type.ValueType)
                                                cache.AddBaseType (b_type);
 
-                                       if (ta.Interfaces != null) {
-                                               foreach (var iface_type in ta.Interfaces) {
+                                       var tps = ta as TypeParameterSpec;
+                                       var ifaces = tps != null ? tps.InterfacesDefined : ta.Interfaces;
+
+                                       if (ifaces != null) {
+                                               foreach (var iface_type in ifaces) {
                                                        cache.AddInterface (iface_type);
                                                }
                                        }
@@ -1347,6 +1445,9 @@ namespace Mono.CSharp {
                                return ac;
                        }
 
+                       if (type.Kind == MemberKind.MissingType)
+                               return type;
+
                        //
                        // When inflating a nested type, inflate its parent first
                        // in case it's using same type parameters (was inflated within the type)
@@ -1444,6 +1545,7 @@ namespace Mono.CSharp {
        {
                readonly TypeParameters mvar;
                readonly TypeParameters var;
+               readonly TypeParameterSpec[] src;
                Dictionary<TypeSpec, TypeSpec> mutated_typespec;
 
                public TypeParameterMutator (TypeParameters mvar, TypeParameters var)
@@ -1455,6 +1557,15 @@ namespace Mono.CSharp {
                        this.var = var;
                }
 
+               public TypeParameterMutator (TypeParameterSpec[] srcVar, TypeParameters destVar)
+               {
+                       if (srcVar.Length != destVar.Count)
+                               throw new ArgumentException ();
+
+                       this.src = srcVar;
+                       this.var = destVar;
+               }
+
                #region Properties
 
                public TypeParameters MethodTypeParameters {
@@ -1494,9 +1605,16 @@ namespace Mono.CSharp {
 
                public TypeParameterSpec Mutate (TypeParameterSpec tp)
                {
-                       for (int i = 0; i < mvar.Count; ++i) {
-                               if (mvar[i].Type == tp)
-                                       return var[i].Type;
+                       if (mvar != null) {
+                               for (int i = 0; i < mvar.Count; ++i) {
+                                       if (mvar[i].Type == tp)
+                                               return var[i].Type;
+                               }
+                       } else {
+                               for (int i = 0; i < src.Length; ++i) {
+                                       if (src[i] == tp)
+                                               return var[i].Type;
+                               }
                        }
 
                        return tp;
@@ -1612,7 +1730,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override bool IsGenericIterateInterface {
+               public override bool IsArrayGenericInterface {
                        get {
                                return (open_type.state & StateFlags.GenericIterateInterface) != 0;
                        }
@@ -1641,6 +1759,16 @@ namespace Mono.CSharp {
 
                #endregion
 
+               public override bool AddInterface (TypeSpec iface)
+               {
+                       var inflator = CreateLocalInflator (context);
+                       iface = inflator.Inflate (iface);
+                       if (iface == null)
+                               return false;
+
+                       return base.AddInterface (iface);
+               }
+
                public static bool ContainsTypeParameter (TypeSpec type)
                {
                        if (type.Kind == MemberKind.TypeParameter)
@@ -1711,7 +1839,7 @@ namespace Mono.CSharp {
                        return new TypeParameterInflator (context, this, tparams_full, targs_full);
                }
 
-               MetaType CreateMetaInfo (TypeParameterMutator mutator)
+               MetaType CreateMetaInfo ()
                {
                        //
                        // Converts nested type arguments into right order
@@ -1761,7 +1889,7 @@ namespace Mono.CSharp {
                public override MetaType GetMetaInfo ()
                {
                        if (info == null)
-                               info = CreateMetaInfo (null);
+                               info = CreateMetaInfo ();
 
                        return info;
                }
@@ -1850,7 +1978,7 @@ namespace Mono.CSharp {
                                                if (iface_inflated == null)
                                                        continue;
 
-                                               AddInterface (iface_inflated);
+                                               base.AddInterface (iface_inflated);
                                        }
                                }
 
@@ -2119,13 +2247,13 @@ namespace Mono.CSharp {
                        names.AddRange (tparams.names);
                }
 
-               public void Define (GenericTypeParameterBuilder[] buiders, TypeSpec declaringType, int parentOffset, TypeContainer parent)
+               public void Create (TypeSpec declaringType, int parentOffset, TypeContainer parent)
                {
                        types = new TypeParameterSpec[Count];
                        for (int i = 0; i < types.Length; ++i) {
                                var tp = names[i];
 
-                               tp.Define (buiders[i + parentOffset], declaringType, parent);
+                               tp.Create (declaringType, parent);
                                types[i] = tp.Type;
                                types[i].DeclaredPosition = i + parentOffset;
 
@@ -2135,6 +2263,14 @@ namespace Mono.CSharp {
                        }
                }
 
+               public void Define (GenericTypeParameterBuilder[] builders)
+               {
+                       for (int i = 0; i < types.Length; ++i) {
+                               var tp = names[i];
+                               tp.Define (builders [types [i].DeclaredPosition]);
+                       }
+               }
+
                public TypeParameter this[int index] {
                        get {
                                return names [index];
@@ -2174,6 +2310,44 @@ namespace Mono.CSharp {
                        return sb.ToString ();
                }
 
+
+               public void CheckPartialConstraints (Method part)
+               {
+                       var partTypeParameters = part.CurrentTypeParameters;
+
+                       for (int i = 0; i < Count; i++) {
+                               var tp_a = names[i];
+                               var tp_b = partTypeParameters [i];
+                               if (tp_a.Constraints == null) {
+                                       if (tp_b.Constraints == null)
+                                               continue;
+                               } else if (tp_b.Constraints != null && tp_a.Type.HasSameConstraintsDefinition (tp_b.Type)) {
+                                       continue;
+                               }
+
+                               part.Compiler.Report.SymbolRelatedToPreviousError (this[i].CurrentMemberDefinition.Location, "");
+                               part.Compiler.Report.Error (761, part.Location,
+                                       "Partial method declarations of `{0}' have inconsistent constraints for type parameter `{1}'",
+                                       part.GetSignatureForError (), partTypeParameters[i].GetSignatureForError ());
+                       }
+               }
+
+               public void UpdateConstraints (TypeDefinition part)
+               {
+                       var partTypeParameters = part.MemberName.TypeParameters;
+
+                       for (int i = 0; i < Count; i++) {
+                               var tp = names [i];
+                               if (tp.AddPartialConstraints (part, partTypeParameters [i]))
+                                       continue;
+
+                               part.Compiler.Report.SymbolRelatedToPreviousError (this[i].CurrentMemberDefinition);
+                               part.Compiler.Report.Error (265, part.Location,
+                                       "Partial declarations of `{0}' have inconsistent constraints for type parameter `{1}'",
+                                       part.GetSignatureForError (), tp.GetSignatureForError ());
+                       }
+               }
+
                public void VerifyClsCompliance ()
                {
                        foreach (var tp in names) {
@@ -2204,7 +2378,7 @@ namespace Mono.CSharp {
 
                public override string GetSignatureForError ()
                {
-                       return TypeManager.CSharpName (type);
+                       return type.GetSignatureForError ();
                }
 
                public override TypeSpec ResolveAsType (IMemberContext mc)
@@ -2352,7 +2526,7 @@ namespace Mono.CSharp {
                                if (mc != null) {
                                        mc.Module.Compiler.Report.Error (452, loc,
                                                "The type `{0}' must be a reference type in order to use it as type parameter `{1}' in the generic type or method `{2}'",
-                                               TypeManager.CSharpName (atype), tparam.GetSignatureForError (), context.GetSignatureForError ());
+                                               atype.GetSignatureForError (), tparam.GetSignatureForError (), context.GetSignatureForError ());
                                }
 
                                return false;
@@ -2362,7 +2536,7 @@ namespace Mono.CSharp {
                                if (mc != null) {
                                        mc.Module.Compiler.Report.Error (453, loc,
                                                "The type `{0}' must be a non-nullable value type in order to use it as type parameter `{1}' in the generic type or method `{2}'",
-                                               TypeManager.CSharpName (atype), tparam.GetSignatureForError (), context.GetSignatureForError ());
+                                               atype.GetSignatureForError (), tparam.GetSignatureForError (), context.GetSignatureForError ());
                                }
 
                                return false;
@@ -2385,13 +2559,14 @@ namespace Mono.CSharp {
                        //
                        // Check the interfaces constraints
                        //
-                       if (tparam.Interfaces != null) {
-                               foreach (TypeSpec iface in tparam.Interfaces) {
+                       if (tparam.InterfacesDefined != null) {
+                               foreach (TypeSpec iface in tparam.InterfacesDefined) {
                                        if (!CheckConversion (mc, context, atype, tparam, iface, loc)) {
                                                if (mc == null)
                                                        return false;
 
                                                ok = false;
+                                               break;
                                        }
                                }
                        }
@@ -2406,6 +2581,7 @@ namespace Mono.CSharp {
                                                        return false;
 
                                                ok = false;
+                                               break;
                                        }
                                }
                        }
@@ -2421,7 +2597,7 @@ namespace Mono.CSharp {
                                        mc.Module.Compiler.Report.SymbolRelatedToPreviousError (atype);
                                        mc.Module.Compiler.Report.Error (310, loc,
                                                "The type `{0}' must have a public parameterless constructor in order to use it as parameter `{1}' in the generic type or method `{2}'",
-                                               TypeManager.CSharpName (atype), tparam.GetSignatureForError (), context.GetSignatureForError ());
+                                               atype.GetSignatureForError (), tparam.GetSignatureForError (), context.GetSignatureForError ());
                                }
                                return false;
                        }
@@ -2527,40 +2703,6 @@ namespace Mono.CSharp {
                }
        }
 
-       public partial class TypeManager
-       {
-               public static Variance CheckTypeVariance (TypeSpec t, Variance expected, IMemberContext member)
-               {
-                       var tp = t as TypeParameterSpec;
-                       if (tp != null) {
-                               Variance v = tp.Variance;
-                               if (expected == Variance.None && v != expected ||
-                                       expected == Variance.Covariant && v == Variance.Contravariant ||
-                                       expected == Variance.Contravariant && v == Variance.Covariant) {
-                                       ((TypeParameter)tp.MemberDefinition).ErrorInvalidVariance (member, expected);
-                               }
-
-                               return expected;
-                       }
-
-                       if (t.TypeArguments.Length > 0) {
-                               var targs_definition = t.MemberDefinition.TypeParameters;
-                               TypeSpec[] targs = GetTypeArguments (t);
-                               for (int i = 0; i < targs.Length; ++i) {
-                                       Variance v = targs_definition[i].Variance;
-                                       CheckTypeVariance (targs[i], (Variance) ((int)v * (int)expected), member);
-                               }
-
-                               return expected;
-                       }
-
-                       if (t.IsArray)
-                               return CheckTypeVariance (GetElementType (t), expected, member);
-
-                       return Variance.None;
-               }
-       }
-
        //
        // Implements C# type inference
        //
@@ -2641,7 +2783,7 @@ namespace Mono.CSharp {
                                //
                                AnonymousMethodExpression am = a.Expr as AnonymousMethodExpression;
                                if (am != null) {
-                                       if (am.ExplicitTypeInference (ec, tic, method_parameter))
+                                       if (am.ExplicitTypeInference (tic, method_parameter))
                                                --score; 
                                        continue;
                                }
@@ -3156,6 +3298,11 @@ namespace Mono.CSharp {
                //
                public bool IsReturnTypeNonDependent (ResolveContext ec, MethodSpec invoke, TypeSpec returnType)
                {
+                       AParametersCollection d_parameters = invoke.Parameters;
+
+                       if (d_parameters.IsEmpty)
+                               return true;
+
                        while (returnType.IsArray)
                                returnType = ((ArrayContainer) returnType).Element;
 
@@ -3163,11 +3310,6 @@ namespace Mono.CSharp {
                                if (IsFixed (returnType))
                                    return false;
                        } else if (TypeManager.IsGenericType (returnType)) {
-                               if (returnType.IsDelegate) {
-                                       invoke = Delegate.GetInvokeMethod (returnType);
-                                       return IsReturnTypeNonDependent (ec, invoke, invoke.ReturnType);
-                               }
-                                       
                                TypeSpec[] g_args = TypeManager.GetTypeArguments (returnType);
                                
                                // At least one unfixed return type has to exist 
@@ -3178,10 +3320,9 @@ namespace Mono.CSharp {
                        }
 
                        // All generic input arguments have to be fixed
-                       AParametersCollection d_parameters = invoke.Parameters;
                        return AllTypesAreFixed (d_parameters.Types);
                }
-               
+
                bool IsFixed (TypeSpec type)
                {
                        return IsUnfixed (type) == -1;
@@ -3238,7 +3379,7 @@ namespace Mono.CSharp {
                                        return LowerBoundInference (u_ac.Element, v_ac.Element, inversed);
                                }
 
-                               if (u_ac.Rank != 1 || !v.IsGenericIterateInterface)
+                               if (u_ac.Rank != 1 || !v.IsArrayGenericInterface)
                                        return 0;
 
                                var v_i = TypeManager.GetTypeArguments (v) [0];
@@ -3267,12 +3408,12 @@ namespace Mono.CSharp {
                                        //
                                        if (t.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
                                                u_candidates.Add (t);
+                               }
 
-                                       if (t.Interfaces != null) {
-                                               foreach (var iface in t.Interfaces) {
-                                                       if (open_v == iface.MemberDefinition)
-                                                               u_candidates.Add (iface);
-                                               }
+                               if (u.Interfaces != null) {
+                                       foreach (var iface in u.Interfaces) {
+                                               if (open_v == iface.MemberDefinition)
+                                                       u_candidates.Add (iface);
                                        }
                                }
 
@@ -3388,7 +3529,7 @@ namespace Mono.CSharp {
                                var invoke = Delegate.GetInvokeMethod (t);
                                TypeSpec rtype = invoke.ReturnType;
 
-                               if (!rtype.IsGenericParameter && !TypeManager.IsGenericType (rtype))
+                               if (!IsReturnTypeNonDependent (ec, invoke, rtype))
                                        return 0;
 
                                // LAMESPEC: Standard does not specify that all methodgroup arguments
@@ -3401,14 +3542,11 @@ namespace Mono.CSharp {
                                        if (inflated == null)
                                                return 0;
 
-                                       if (IsUnfixed (inflated) >= 0)
-                                               return 0;
-
                                        param_types[i] = inflated;
                                }
 
                                MethodGroupExpr mg = (MethodGroupExpr) e;
-                               Arguments args = DelegateCreation.CreateDelegateMethodArguments (invoke.Parameters, param_types, e.Location);
+                               Arguments args = DelegateCreation.CreateDelegateMethodArguments (ec, invoke.Parameters, param_types, e.Location);
                                mg = mg.OverloadResolve (ec, ref args, null, OverloadResolver.Restrictions.CovariantDelegate | OverloadResolver.Restrictions.ProbingOnly);
                                if (mg == null)
                                        return 0;