* MonoTouch/MonoPInvokeCallbackAttribute.cs: Added.
[mono.git] / mcs / mcs / generic.cs
index 99f23607f401412dbc7f5b288e66c8f60187cf56..999d6d9bbaaa0ac7a075fcf00b3ad1451aec7fdc 100644 (file)
@@ -250,11 +250,14 @@ namespace Mono.CSharp {
                ///   Resolve the constraints - but only resolve things into Expression's, not
                ///   into actual types.
                /// </summary>
-               public bool Resolve (IResolveContext ec, TypeParameter tp)
+               public bool Resolve (MemberCore ec, TypeParameter tp, Report Report)
                {
                        if (resolved)
                                return true;
 
+                       if (ec == null)
+                               return false;
+
                        iface_constraints = new ArrayList (2);  // TODO: Too expensive allocation
                        type_param_constraints = new ArrayList ();
 
@@ -299,7 +302,7 @@ namespace Mono.CSharp {
                                        if (errors != Report.Errors)
                                                return false;
 
-                                       NamespaceEntry.Error_NamespaceNotFound (loc, ((Expression)obj).GetSignatureForError ());
+                                       NamespaceEntry.Error_NamespaceNotFound (loc, ((Expression)obj).GetSignatureForError (), Report);
                                        return false;
                                }
 
@@ -313,16 +316,15 @@ namespace Mono.CSharp {
                                if ((expr == null) || (expr.Type == null))
                                        return false;
 
-                               if (!ec.GenericDeclContainer.IsAccessibleAs (fn.Type)) {
+                               if (!ec.IsAccessibleAs (fn.Type)) {
                                        Report.SymbolRelatedToPreviousError (fn.Type);
                                        Report.Error (703, loc,
                                                "Inconsistent accessibility: constraint type `{0}' is less accessible than `{1}'",
-                                               fn.GetSignatureForError (), ec.GenericDeclContainer.GetSignatureForError ());
+                                               fn.GetSignatureForError (), ec.GetSignatureForError ());
                                        return false;
                                }
 
-                               TypeParameterExpr texpr = expr as TypeParameterExpr;
-                               if (texpr != null)
+                               if (TypeManager.IsGenericParameter (expr.Type))
                                        type_param_constraints.Add (expr);
                                else if (expr.IsInterface)
                                        iface_constraints.Add (expr);
@@ -367,7 +369,7 @@ namespace Mono.CSharp {
                                list.Add (iface_constraint.Type);
                        }
 
-                       foreach (TypeParameterExpr expr in type_param_constraints) {
+                       foreach (TypeExpr expr in type_param_constraints) {
                                foreach (Type type in list) {
                                        if (!type.Equals (expr.Type))
                                                continue;
@@ -414,6 +416,11 @@ namespace Mono.CSharp {
                                                      TypeManager.CSharpName (class_constraint_type));
                                        return false;
                                }
+
+                               if (TypeManager.IsDynamicType (class_constraint_type)) {
+                                       Report.Error (1967, loc, "A constraint cannot be the dynamic type");
+                                       return false;
+                               }
                        }
 
                        if (class_constraint_type != null)
@@ -430,11 +437,11 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               bool CheckTypeParameterConstraints (TypeParameter tparam, ref TypeExpr prevConstraint, ArrayList seen)
+               bool CheckTypeParameterConstraints (Type tparam, ref TypeExpr prevConstraint, ArrayList seen, Report Report)
                {
                        seen.Add (tparam);
 
-                       Constraints constraints = tparam.Constraints;
+                       Constraints constraints = TypeManager.LookupTypeParameter (tparam).Constraints;
                        if (constraints == null)
                                return true;
 
@@ -472,15 +479,15 @@ namespace Mono.CSharp {
                        if (constraints.type_param_constraints == null)
                                return true;
 
-                       foreach (TypeParameterExpr expr in constraints.type_param_constraints) {
-                               if (seen.Contains (expr.TypeParameter)) {
+                       foreach (TypeExpr expr in constraints.type_param_constraints) {
+                               if (seen.Contains (expr.Type)) {
                                        Report.Error (454, loc, "Circular constraint " +
                                                      "dependency involving `{0}' and `{1}'",
                                                      tparam.Name, expr.GetSignatureForError ());
                                        return false;
                                }
 
-                               if (!CheckTypeParameterConstraints (expr.TypeParameter, ref prevConstraint, seen))
+                               if (!CheckTypeParameterConstraints (expr.Type, ref prevConstraint, seen, Report))
                                        return false;
                        }
 
@@ -490,7 +497,7 @@ namespace Mono.CSharp {
                /// <summary>
                ///   Resolve the constraints into actual types.
                /// </summary>
-               public bool ResolveTypes (IResolveContext ec)
+               public bool ResolveTypes (IMemberContext ec, Report r)
                {
                        if (resolved_types)
                                return true;
@@ -509,8 +516,8 @@ namespace Mono.CSharp {
                        if (type_param_constraints.Count != 0) {
                                ArrayList seen = new ArrayList ();
                                TypeExpr prev_constraint = class_constraint;
-                               foreach (TypeParameterExpr expr in type_param_constraints) {
-                                       if (!CheckTypeParameterConstraints (expr.TypeParameter, ref prev_constraint, seen))
+                               foreach (TypeExpr expr in type_param_constraints) {
+                                       if (!CheckTypeParameterConstraints (expr.Type, ref prev_constraint, seen, r))
                                                return false;
                                        seen.Clear ();
                                }
@@ -625,21 +632,21 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               public void VerifyClsCompliance ()
+               public void VerifyClsCompliance (Report r)
                {
                        if (class_constraint_type != null && !AttributeTester.IsClsCompliant (class_constraint_type))
-                               Warning_ConstrainIsNotClsCompliant (class_constraint_type, class_constraint.Location);
+                               Warning_ConstrainIsNotClsCompliant (class_constraint_type, class_constraint.Location, r);
 
                        if (iface_constraint_types != null) {
                                for (int i = 0; i < iface_constraint_types.Length; ++i) {
                                        if (!AttributeTester.IsClsCompliant (iface_constraint_types [i]))
                                                Warning_ConstrainIsNotClsCompliant (iface_constraint_types [i],
-                                                       ((TypeExpr)iface_constraints [i]).Location);
+                                                       ((TypeExpr)iface_constraints [i]).Location, r);
                                }
                        }
                }
 
-               void Warning_ConstrainIsNotClsCompliant (Type t, Location loc)
+               void Warning_ConstrainIsNotClsCompliant (Type t, Location loc, Report Report)
                {
                        Report.SymbolRelatedToPreviousError (t);
                        Report.Warning (3024, 1, loc, "Constraint type `{0}' is not CLS-compliant",
@@ -708,9 +715,9 @@ namespace Mono.CSharp {
                        TypeManager.AddTypeParameter (type, this);
                }
 
-               public void ErrorInvalidVariance (MemberCore mc, Variance expected)
+               public void ErrorInvalidVariance (IMemberContext mc, Variance expected)
                {
-                       Report.SymbolRelatedToPreviousError (mc);
+// TODO:       Report.SymbolRelatedToPreviousError (mc);
                        string input_variance = Variance == Variance.Contravariant ? "contravariant" : "covariant";
                        string gtype_variance;
                        switch (expected) {
@@ -743,7 +750,7 @@ namespace Mono.CSharp {
                public bool Resolve (DeclSpace ds)
                {
                        if (constraints != null) {
-                               if (!constraints.Resolve (ds, this)) {
+                               if (!constraints.Resolve (ds, this, Report)) {
                                        constraints = null;
                                        return false;
                                }
@@ -762,10 +769,10 @@ namespace Mono.CSharp {
                ///   Note that we may have circular dependencies on type parameters - this
                ///   is why Resolve() and ResolveType() are separate.
                /// </summary>
-               public bool ResolveType (IResolveContext ec)
+               public bool ResolveType (IMemberContext ec)
                {
                        if (constraints != null) {
-                               if (!constraints.ResolveTypes (ec)) {
+                               if (!constraints.ResolveTypes (ec, Report)) {
                                        constraints = null;
                                        return false;
                                }
@@ -779,7 +786,7 @@ namespace Mono.CSharp {
                ///   process.  We're called after everything is fully resolved and actually
                ///   register the constraints with SRE and the TypeManager.
                /// </summary>
-               public bool DefineType (IResolveContext ec)
+               public bool DefineType (IMemberContext ec)
                {
                        return DefineType (ec, null, null, false);
                }
@@ -792,7 +799,7 @@ namespace Mono.CSharp {
                ///   The `builder', `implementing' and `is_override' arguments are only
                ///   applicable to method type parameters.
                /// </summary>
-               public bool DefineType (IResolveContext ec, MethodBuilder builder,
+               public bool DefineType (IMemberContext ec, MethodBuilder builder,
                                        MethodInfo implementing, bool is_override)
                {
                        if (!ResolveType (ec))
@@ -857,6 +864,16 @@ namespace Mono.CSharp {
                        return true;
                }
 
+               public static TypeParameter FindTypeParameter (TypeParameter[] tparams, string name)
+               {
+                       foreach (var tp in tparams) {
+                               if (tp.Name == name)
+                                       return tp;
+                       }
+
+                       return null;
+               }
+
                public void SetConstraints (GenericTypeParameterBuilder type)
                {
                        GenericParameterAttributes attr = GenericParameterAttributes.None;
@@ -885,7 +902,7 @@ namespace Mono.CSharp {
                ///   check that they're the same.
                ///   con
                /// </summary>
-               public bool UpdateConstraints (IResolveContext ec, Constraints new_constraints)
+               public bool UpdateConstraints (MemberCore ec, Constraints new_constraints)
                {
                        if (type == null)
                                throw new InvalidOperationException ();
@@ -893,9 +910,9 @@ namespace Mono.CSharp {
                        if (new_constraints == null)
                                return true;
 
-                       if (!new_constraints.Resolve (ec, this))
+                       if (!new_constraints.Resolve (ec, this, Report))
                                return false;
-                       if (!new_constraints.ResolveTypes (ec))
+                       if (!new_constraints.ResolveTypes (ec, Report))
                                return false;
 
                        if (constraints != null) 
@@ -1130,29 +1147,21 @@ namespace Mono.CSharp {
        ///   A TypeExpr which already resolved to a type parameter.
        /// </summary>
        public class TypeParameterExpr : TypeExpr {
-               TypeParameter type_parameter;
-
-               public TypeParameter TypeParameter {
-                       get {
-                               return type_parameter;
-                       }
-               }
                
                public TypeParameterExpr (TypeParameter type_parameter, Location loc)
                {
-                       this.type_parameter = type_parameter;
+                       this.type = type_parameter.Type;
+                       this.eclass = ExprClass.TypeParameter;
                        this.loc = loc;
                }
 
-               protected override TypeExpr DoResolveAsTypeStep (IResolveContext ec)
+               protected override TypeExpr DoResolveAsTypeStep (IMemberContext ec)
                {
                        throw new NotSupportedException ();
                }
 
-               public override FullNamedExpression ResolveAsTypeStep (IResolveContext ec, bool silent)
+               public override FullNamedExpression ResolveAsTypeStep (IMemberContext ec, bool silent)
                {
-                       type = type_parameter.Type;
-                       eclass = ExprClass.TypeParameter;
                        return this;
                }
 
@@ -1160,7 +1169,7 @@ namespace Mono.CSharp {
                        get { return false; }
                }
 
-               public override bool CheckAccessLevel (DeclSpace ds)
+               public override bool CheckAccessLevel (IMemberContext ds)
                {
                        return true;
                }
@@ -1232,7 +1241,7 @@ namespace Mono.CSharp {
                /// <summary>
                ///   Resolve the type arguments.
                /// </summary>
-               public bool Resolve (IResolveContext ec)
+               public bool Resolve (IMemberContext ec)
                {
                        if (atypes != null)
                                return atypes.Length != 0;
@@ -1252,13 +1261,13 @@ namespace Mono.CSharp {
                                atypes[i] = te.Type;
 
                                if (te.Type.IsSealed && te.Type.IsAbstract) {
-                                       Report.Error (718, te.Location, "`{0}': static classes cannot be used as generic arguments",
+                                       ec.Compiler.Report.Error (718, te.Location, "`{0}': static classes cannot be used as generic arguments",
                                                te.GetSignatureForError ());
                                        ok = false;
                                }
 
                                if (te.Type.IsPointer || TypeManager.IsSpecialType (te.Type)) {
-                                       Report.Error (306, te.Location,
+                                       ec.Compiler.Report.Error (306, te.Location,
                                                "The type `{0}' may not be used as a type argument",
                                                te.GetSignatureForError ());
                                        ok = false;
@@ -1359,7 +1368,7 @@ namespace Mono.CSharp {
                        return TypeManager.CSharpName (type);
                }
 
-               protected override TypeExpr DoResolveAsTypeStep (IResolveContext ec)
+               protected override TypeExpr DoResolveAsTypeStep (IMemberContext ec)
                {
                        if (eclass != ExprClass.Invalid)
                                return this;
@@ -1388,14 +1397,14 @@ namespace Mono.CSharp {
                ///   Check the constraints; we're called from ResolveAsTypeTerminal()
                ///   after fully resolving the constructed type.
                /// </summary>
-               public bool CheckConstraints (IResolveContext ec)
+               public bool CheckConstraints (IMemberContext ec)
                {
                        return ConstraintChecker.CheckConstraints (ec, open_type, gen_params, args.Arguments, loc);
                }
        
-               public override bool CheckAccessLevel (DeclSpace ds)
+               public override bool CheckAccessLevel (IMemberContext mc)
                {
-                       return ds.CheckAccessLevel (open_type);
+                       return mc.CurrentTypeDefinition.CheckAccessLevel (open_type);
                }
 
                public override bool IsClass {
@@ -1437,19 +1446,21 @@ namespace Mono.CSharp {
                protected readonly Type[] gen_params;
                protected readonly Type[] atypes;
                protected readonly Location loc;
+               protected Report Report;
 
-               protected ConstraintChecker (Type[] gen_params, Type[] atypes, Location loc)
+               protected ConstraintChecker (Type[] gen_params, Type[] atypes, Location loc, Report r)
                {
                        this.gen_params = gen_params;
                        this.atypes = atypes;
                        this.loc = loc;
+                       this.Report = r;
                }
 
                /// <summary>
                ///   Check the constraints; we're called from ResolveAsTypeTerminal()
                ///   after fully resolving the constructed type.
                /// </summary>
-               public bool CheckConstraints (IResolveContext ec)
+               public bool CheckConstraints (IMemberContext ec)
                {
                        for (int i = 0; i < gen_params.Length; i++) {
                                if (!CheckConstraints (ec, i))
@@ -1459,7 +1470,7 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               protected bool CheckConstraints (IResolveContext ec, int index)
+               protected bool CheckConstraints (IMemberContext ec, int index)
                {
                        Type atype = atypes [index];
                        Type ptype = gen_params [index];
@@ -1477,8 +1488,15 @@ namespace Mono.CSharp {
                        if (atype.IsGenericParameter) {
                                GenericConstraints agc = TypeManager.GetTypeParameterConstraints (atype);
                                if (agc != null) {
-                                       if (agc is Constraints)
-                                               ((Constraints) agc).Resolve (ec, null);
+                                       if (agc is Constraints) {
+                                               // FIXME: No constraints can be resolved here, we are in
+                                               // completely wrong/different context. This path is hit
+                                               // when resolving base type of unresolved generic type
+                                               // with constraints. We are waiting with CheckConsttraints
+                                               // after type-definition but not in this case
+                                               if (!((Constraints) agc).Resolve (null, null, Report))
+                                                       return true;
+                                       }
                                        is_class = agc.IsReferenceType;
                                        is_struct = agc.IsValueType;
                                } else {
@@ -1537,7 +1555,7 @@ namespace Mono.CSharp {
                        if (!gc.HasConstructorConstraint)
                                return true;
 
-                       if (TypeManager.IsBuiltinType (atype) || TypeManager.IsValueType (atype))
+                       if (TypeManager.IsValueType (atype))
                                return true;
 
                        if (HasDefaultConstructor (atype))
@@ -1555,9 +1573,13 @@ namespace Mono.CSharp {
                        return false;
                }
 
-               protected bool CheckConstraint (IResolveContext ec, Type ptype, Expression expr,
+               protected bool CheckConstraint (IMemberContext ec, Type ptype, Expression expr,
                                                Type ctype)
                {
+                       //
+                       // All this is needed because we don't have
+                       // real inflated type hierarchy
+                       //
                        if (TypeManager.HasGenericArguments (ctype)) {
                                Type[] types = TypeManager.GetTypeArguments (ctype);
 
@@ -1568,7 +1590,12 @@ namespace Mono.CSharp {
 
                                        if (t.IsGenericParameter) {
                                                int pos = t.GenericParameterPosition;
-                                               t = atypes [pos];
+                                               if (t.DeclaringMethod == null && this is MethodConstraintChecker) {
+                                                       Type parent = ((MethodConstraintChecker) this).declaring_type;
+                                                       t = parent.GetGenericArguments ()[pos];
+                                               } else {
+                                                       t = atypes [pos];
+                                               }
                                        }
                                        new_args.Add (new TypeExpression (t, loc));
                                }
@@ -1664,21 +1691,21 @@ namespace Mono.CSharp {
                protected abstract string GetSignatureForError ();
                protected abstract void Report_SymbolRelatedToPreviousError ();
 
-               public static bool CheckConstraints (EmitContext ec, MethodBase definition,
+               public static bool CheckConstraints (IMemberContext ec, MethodBase definition,
                                                     MethodBase instantiated, Location loc)
                {
                        MethodConstraintChecker checker = new MethodConstraintChecker (
-                               definition, definition.GetGenericArguments (),
-                               instantiated.GetGenericArguments (), loc);
+                               definition, instantiated.DeclaringType, definition.GetGenericArguments (),
+                               instantiated.GetGenericArguments (), loc, ec.Compiler.Report);
 
                        return checker.CheckConstraints (ec);
                }
 
-               public static bool CheckConstraints (IResolveContext ec, Type gt, Type[] gen_params,
+               public static bool CheckConstraints (IMemberContext ec, Type gt, Type[] gen_params,
                                                     Type[] atypes, Location loc)
                {
                        TypeConstraintChecker checker = new TypeConstraintChecker (
-                               gt, gen_params, atypes, loc);
+                               gt, gen_params, atypes, loc, ec.Compiler.Report);
 
                        return checker.CheckConstraints (ec);
                }
@@ -1686,11 +1713,13 @@ namespace Mono.CSharp {
                protected class MethodConstraintChecker : ConstraintChecker
                {
                        MethodBase definition;
+                       public Type declaring_type;
 
-                       public MethodConstraintChecker (MethodBase definition, Type[] gen_params,
-                                                       Type[] atypes, Location loc)
-                               : base (gen_params, atypes, loc)
+                       public MethodConstraintChecker (MethodBase definition, Type declaringType, Type[] gen_params,
+                                                       Type[] atypes, Location loc, Report r)
+                               : base (gen_params, atypes, loc, r)
                        {
+                               this.declaring_type = declaringType;
                                this.definition = definition;
                        }
 
@@ -1710,8 +1739,8 @@ namespace Mono.CSharp {
                        Type gt;
 
                        public TypeConstraintChecker (Type gt, Type[] gen_params, Type[] atypes,
-                                                     Location loc)
-                               : base (gen_params, atypes, loc)
+                                                     Location loc, Report r)
+                               : base (gen_params, atypes, loc, r)
                        {
                                this.gt = gt;
                        }
@@ -1744,6 +1773,18 @@ namespace Mono.CSharp {
                        this.parameters = parameters;
                }
 
+               public override TypeContainer CurrentTypeDefinition {
+                       get {
+                               return Parent.CurrentTypeDefinition;
+                       }
+               }
+
+               public override TypeParameter[] CurrentTypeParameters {
+                       get {
+                               return base.type_params;
+                       }
+               }
+
                public override TypeBuilder DefineType ()
                {
                        throw new Exception ();
@@ -1774,7 +1815,7 @@ namespace Mono.CSharp {
                                        if (b == null)
                                                b = new Block (null);
 
-                                       b.Error_AlreadyDeclaredTypeParameter (parameters [i].Location,
+                                       b.Error_AlreadyDeclaredTypeParameter (Report, parameters [i].Location,
                                                type_argument_name, "method parameter");
                                }
                                
@@ -1799,7 +1840,7 @@ namespace Mono.CSharp {
                /// <summary>
                ///   We're called from MethodData.Define() after creating the MethodBuilder.
                /// </summary>
-               public bool DefineType (EmitContext ec, MethodBuilder mb,
+               public bool DefineType (IMemberContext ec, MethodBuilder mb,
                                        MethodInfo implementing, bool is_override)
                {
                        for (int i = 0; i < TypeParameters.Length; i++)
@@ -1828,7 +1869,12 @@ namespace Mono.CSharp {
                                                        MemberFilter filter, object criteria)
                {
                        throw new Exception ();
-               }               
+               }
+
+               public override string GetSignatureForError ()
+               {
+                       return base.GetSignatureForError () + parameters.GetSignatureForError ();
+               }
 
                public override MemberCache MemberCache {
                        get {
@@ -1852,7 +1898,7 @@ namespace Mono.CSharp {
                                if (tp.Constraints == null)
                                        continue;
 
-                               tp.Constraints.VerifyClsCompliance ();
+                               tp.Constraints.VerifyClsCompliance (Report);
                        }
                }
        }
@@ -1883,7 +1929,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               public static Variance CheckTypeVariance (Type t, Variance expected, MemberCore member)
+               public static Variance CheckTypeVariance (Type t, Variance expected, IMemberContext member)
                {
                        TypeParameter tp = LookupTypeParameter (t);
                        if (tp != null) {
@@ -2076,7 +2122,7 @@ namespace Mono.CSharp {
                ///   when resolving an Invocation or a DelegateInvocation and the user
                ///   did not explicitly specify type arguments.
                /// </summary>
-               public static int InferTypeArguments (EmitContext ec, Arguments arguments, ref MethodBase method)
+               public static int InferTypeArguments (ResolveContext ec, Arguments arguments, ref MethodBase method)
                {
                        ATypeInference ti = ATypeInference.CreateInstance (arguments);
                        Type[] i_args = ti.InferMethodArguments (ec, method);
@@ -2090,22 +2136,21 @@ namespace Mono.CSharp {
                        return 0;
                }
 
-               /// <summary>
-               ///   Type inference.
-               /// </summary>
-               public static bool InferTypeArguments (AParametersCollection param, ref MethodBase method)
+/*
+               public static bool InferTypeArguments (ResolveContext ec, AParametersCollection param, ref MethodBase method)
                {
                        if (!TypeManager.IsGenericMethod (method))
                                return true;
 
                        ATypeInference ti = ATypeInference.CreateInstance (DelegateCreation.CreateDelegateMethodArguments (param, Location.Null));
-                       Type[] i_args = ti.InferDelegateArguments (method);
+                       Type[] i_args = ti.InferDelegateArguments (ec, method);
                        if (i_args == null)
                                return false;
 
                        method = ((MethodInfo) method).MakeGenericMethod (i_args);
                        return true;
                }
+*/
        }
 
        abstract class ATypeInference
@@ -2131,8 +2176,8 @@ namespace Mono.CSharp {
                        }
                }
 
-               public abstract Type[] InferMethodArguments (EmitContext ec, MethodBase method);
-               public abstract Type[] InferDelegateArguments (MethodBase method);
+               public abstract Type[] InferMethodArguments (ResolveContext ec, MethodBase method);
+//             public abstract Type[] InferDelegateArguments (ResolveContext ec, MethodBase method);
        }
 
        //
@@ -2156,7 +2201,8 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override Type[] InferDelegateArguments (MethodBase method)
+/*
+               public override Type[] InferDelegateArguments (ResolveContext ec, MethodBase method)
                {
                        AParametersCollection pd = TypeManager.GetParameterData (method);
                        if (arg_count != pd.Count)
@@ -2175,13 +2221,13 @@ namespace Mono.CSharp {
                                context.LowerBoundInference (arguments [i].Expr.Type, t);
                        }
 
-                       if (!context.FixAllTypes ())
+                       if (!context.FixAllTypes (ec))
                                return null;
 
                        return context.InferredTypeArguments;
                }
-
-               public override Type[] InferMethodArguments (EmitContext ec, MethodBase method)
+*/
+               public override Type[] InferMethodArguments (ResolveContext ec, MethodBase method)
                {
                        Type[] method_generic_args = method.GetGenericArguments ();
                        TypeInferenceContext context = new TypeInferenceContext (method_generic_args);
@@ -2198,7 +2244,7 @@ namespace Mono.CSharp {
                //
                // Implements method type arguments inference
                //
-               bool InferInPhases (EmitContext ec, TypeInferenceContext tic, AParametersCollection methodParameters)
+               bool InferInPhases (ResolveContext ec, TypeInferenceContext tic, AParametersCollection methodParameters)
                {
                        int params_arguments_start;
                        if (methodParameters.HasParams) {
@@ -2236,7 +2282,7 @@ namespace Mono.CSharp {
                                //
                                AnonymousMethodExpression am = a.Expr as AnonymousMethodExpression;
                                if (am != null) {
-                                       if (am.ExplicitTypeInference (tic, method_parameter))
+                                       if (am.ExplicitTypeInference (ec, tic, method_parameter))
                                                --score; 
                                        continue;
                                }
@@ -2265,16 +2311,16 @@ namespace Mono.CSharp {
                        // we don't need to call it in cycle
                        //
                        bool fixed_any = false;
-                       if (!tic.FixIndependentTypeArguments (ptypes, ref fixed_any))
+                       if (!tic.FixIndependentTypeArguments (ec, ptypes, ref fixed_any))
                                return false;
 
                        return DoSecondPhase (ec, tic, ptypes, !fixed_any);
                }
 
-               bool DoSecondPhase (EmitContext ec, TypeInferenceContext tic, Type[] methodParameters, bool fixDependent)
+               bool DoSecondPhase (ResolveContext ec, TypeInferenceContext tic, Type[] methodParameters, bool fixDependent)
                {
                        bool fixed_any = false;
-                       if (fixDependent && !tic.FixDependentTypes (ref fixed_any))
+                       if (fixDependent && !tic.FixDependentTypes (ec, ref fixed_any))
                                return false;
 
                        // If no further unfixed type variables exist, type inference succeeds
@@ -2299,7 +2345,7 @@ namespace Mono.CSharp {
                                        t_i = t_i.GetGenericArguments () [0];
                                }
 
-                               MethodInfo mi = Delegate.GetInvokeMethod (t_i, t_i);
+                               MethodInfo mi = Delegate.GetInvokeMethod (ec.Compiler, t_i, t_i);
                                Type rtype = mi.ReturnType;
 
 #if MS_COMPATIBLE
@@ -2308,7 +2354,7 @@ namespace Mono.CSharp {
                                rtype = g_args[rtype.GenericParameterPosition];
 #endif
 
-                               if (tic.IsReturnTypeNonDependent (mi, rtype))
+                               if (tic.IsReturnTypeNonDependent (ec, mi, rtype))
                                        score -= tic.OutputTypeInference (ec, arguments [i].Expr, t_i);
                        }
 
@@ -2373,12 +2419,29 @@ namespace Mono.CSharp {
                        }
                }
 
+               // 
+               // Used together with AddCommonTypeBound fo implement
+               // 7.4.2.13 Finding the best common type of a set of expressions
+               //
+               public TypeInferenceContext ()
+               {
+                       fixed_types = new Type [1];
+                       unfixed_types = new Type [1];
+                       unfixed_types[0] = InternalType.Arglist; // it can be any internal type
+                       bounds = new ArrayList [1];
+               }
+
                public Type[] InferredTypeArguments {
                        get {
                                return fixed_types;
                        }
                }
 
+               public void AddCommonTypeBound (Type type)
+               {
+                       AddToBounds (new BoundInfo (type, BoundKind.Lower), 0);
+               }
+
                void AddToBounds (BoundInfo bound, int index)
                {
                        //
@@ -2467,10 +2530,10 @@ namespace Mono.CSharp {
                        return 1;
                }
 
-               public bool FixAllTypes ()
+               public bool FixAllTypes (ResolveContext ec)
                {
                        for (int i = 0; i < unfixed_types.Length; ++i) {
-                               if (!FixType (i))
+                               if (!FixType (ec, i))
                                        return false;
                        }
                        return true;
@@ -2481,7 +2544,7 @@ namespace Mono.CSharp {
                // a, There is at least one type variable Xj that depends on Xi
                // b, Xi has a non-empty set of bounds
                // 
-               public bool FixDependentTypes (ref bool fixed_any)
+               public bool FixDependentTypes (ResolveContext ec, ref bool fixed_any)
                {
                        for (int i = 0; i < unfixed_types.Length; ++i) {
                                if (unfixed_types[i] == null)
@@ -2490,7 +2553,7 @@ namespace Mono.CSharp {
                                if (bounds[i] == null)
                                        continue;
 
-                               if (!FixType (i))
+                               if (!FixType (ec, i))
                                        return false;
                                
                                fixed_any = true;
@@ -2502,7 +2565,7 @@ namespace Mono.CSharp {
                //
                // All unfixed type variables Xi which depend on no Xj are fixed
                //
-               public bool FixIndependentTypeArguments (Type[] methodParameters, ref bool fixed_any)
+               public bool FixIndependentTypeArguments (ResolveContext ec, Type[] methodParameters, ref bool fixed_any)
                {
                        ArrayList types_to_fix = new ArrayList (unfixed_types);
                        for (int i = 0; i < methodParameters.Length; ++i) {
@@ -2518,7 +2581,7 @@ namespace Mono.CSharp {
                                if (t.IsGenericParameter)
                                        continue;
 
-                               MethodInfo invoke = Delegate.GetInvokeMethod (t, t);
+                               MethodInfo invoke = Delegate.GetInvokeMethod (ec.Compiler, t, t);
                                Type rtype = invoke.ReturnType;
                                if (!rtype.IsGenericParameter && !rtype.IsGenericType)
                                        continue;
@@ -2539,7 +2602,7 @@ namespace Mono.CSharp {
                                        continue;
 
                                int idx = IsUnfixed (t);
-                               if (idx >= 0 && !FixType (idx)) {
+                               if (idx >= 0 && !FixType (ec, idx)) {
                                        return false;
                                }
                        }
@@ -2551,7 +2614,7 @@ namespace Mono.CSharp {
                //
                // 26.3.3.10 Fixing
                //
-               public bool FixType (int i)
+               public bool FixType (ResolveContext ec, int i)
                {
                        // It's already fixed
                        if (unfixed_types[i] == null)
@@ -2566,7 +2629,11 @@ namespace Mono.CSharp {
 
                        if (candidates.Count == 1) {
                                unfixed_types[i] = null;
-                               fixed_types[i] = ((BoundInfo) candidates[0]).Type;
+                               Type t = ((BoundInfo) candidates[0]).Type;
+                               if (t == TypeManager.null_type)
+                                       return false;
+
+                               fixed_types [i] = t;
                                return true;
                        }
 
@@ -2596,7 +2663,7 @@ namespace Mono.CSharp {
 
                                        if (bound.Kind == BoundKind.Exact || cbound.Kind == BoundKind.Exact) {
                                                if (cbound.Kind != BoundKind.Exact) {
-                                                       if (!Convert.ImplicitConversionExists (null, new TypeExpression (cbound.Type, Location.Null), bound.Type)) {
+                                                       if (!Convert.ImplicitConversionExists (ec, new TypeExpression (cbound.Type, Location.Null), bound.Type)) {
                                                                break;
                                                        }
 
@@ -2604,7 +2671,7 @@ namespace Mono.CSharp {
                                                }
                                                
                                                if (bound.Kind != BoundKind.Exact) {
-                                                       if (!Convert.ImplicitConversionExists (null, new TypeExpression (bound.Type, Location.Null), cbound.Type)) {
+                                                       if (!Convert.ImplicitConversionExists (ec, new TypeExpression (bound.Type, Location.Null), cbound.Type)) {
                                                                break;
                                                        }
 
@@ -2616,11 +2683,11 @@ namespace Mono.CSharp {
                                        }
 
                                        if (bound.Kind == BoundKind.Lower) {
-                                               if (!Convert.ImplicitConversionExists (null, new TypeExpression (cbound.Type, Location.Null), bound.Type)) {
+                                               if (!Convert.ImplicitConversionExists (ec, new TypeExpression (cbound.Type, Location.Null), bound.Type)) {
                                                        break;
                                                }
                                        } else {
-                                               if (!Convert.ImplicitConversionExists (null, new TypeExpression (bound.Type, Location.Null), cbound.Type)) {
+                                               if (!Convert.ImplicitConversionExists (ec, new TypeExpression (bound.Type, Location.Null), cbound.Type)) {
                                                        break;
                                                }
                                        }
@@ -2673,15 +2740,15 @@ namespace Mono.CSharp {
                // Tests whether all delegate input arguments are fixed and generic output type
                // requires output type inference 
                //
-               public bool IsReturnTypeNonDependent (MethodInfo invoke, Type returnType)
+               public bool IsReturnTypeNonDependent (ResolveContext ec, MethodInfo invoke, Type returnType)
                {
                        if (returnType.IsGenericParameter) {
                                if (IsFixed (returnType))
                                    return false;
                        } else if (returnType.IsGenericType) {
                                if (TypeManager.IsDelegateType (returnType)) {
-                                       invoke = Delegate.GetInvokeMethod (returnType, returnType);
-                                       return IsReturnTypeNonDependent (invoke, invoke.ReturnType);
+                                       invoke = Delegate.GetInvokeMethod (ec.Compiler, returnType, returnType);
+                                       return IsReturnTypeNonDependent (ec, invoke, invoke.ReturnType);
                                }
                                        
                                Type[] g_args = returnType.GetGenericArguments ();
@@ -2849,13 +2916,13 @@ namespace Mono.CSharp {
                //
                // 26.3.3.6 Output Type Inference
                //
-               public int OutputTypeInference (EmitContext ec, Expression e, Type t)
+               public int OutputTypeInference (ResolveContext ec, Expression e, Type t)
                {
                        // If e is a lambda or anonymous method with inferred return type
                        AnonymousMethodExpression ame = e as AnonymousMethodExpression;
                        if (ame != null) {
                                Type rt = ame.InferReturnType (ec, this, t);
-                               MethodInfo invoke = Delegate.GetInvokeMethod (t, t);
+                               MethodInfo invoke = Delegate.GetInvokeMethod (ec.Compiler, t, t);
 
                                if (rt == null) {
                                        AParametersCollection pd = TypeManager.GetParameterData (invoke);
@@ -2882,7 +2949,7 @@ namespace Mono.CSharp {
                                if (!TypeManager.IsDelegateType (t))
                                        return 0;
 
-                               MethodInfo invoke = Delegate.GetInvokeMethod (t, t);
+                               MethodInfo invoke = Delegate.GetInvokeMethod (ec.Compiler, t, t);
                                Type rtype = invoke.ReturnType;
 #if MS_COMPATIBLE
                                // Blablabla, because reflection does not work with dynamic types