Merge pull request #495 from nicolas-raoul/fix-for-issue2907-with-no-formatting-changes
[mono.git] / mcs / mcs / ecore.cs
index 1d34ba369885b6e1653d7dba884600b8ffabe8c7..e990acb244ea9586af2c472696b8c2061f6c75b2 100644 (file)
@@ -3,11 +3,11 @@
 //
 // Author:
 //   Miguel de Icaza (miguel@ximian.com)
-//   Marek Safar (marek.safar@seznam.cz)
+//   Marek Safar (marek.safar@gmail.com)
 //
 // Copyright 2001, 2002, 2003 Ximian, Inc.
 // Copyright 2003-2008 Novell, Inc.
-// Copyright 2011 Xamarin Inc.
+// Copyright 2011-2012 Xamarin Inc.
 //
 //
 
@@ -118,6 +118,11 @@ namespace Mono.CSharp {
                bool IsFixed { get; }
        }
 
+       public interface IExpressionCleanup
+       {
+               void EmitCleanup (EmitContext ec);
+       }
+
        /// <remarks>
        ///   Base class for expressions
        /// </remarks>
@@ -222,8 +227,7 @@ namespace Mono.CSharp {
 
                public static void Error_InvalidExpressionStatement (Report Report, Location loc)
                {
-                       Report.Error (201, loc, "Only assignment, call, increment, decrement, and new object " +
-                                      "expressions can be used as a statement");
+                       Report.Error (201, loc, "Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement");
                }
                
                public void Error_InvalidExpressionStatement (BlockContext ec)
@@ -236,7 +240,7 @@ namespace Mono.CSharp {
                        Report.Error (1547, loc, "Keyword `void' cannot be used in this context");
                }
 
-               public virtual void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
+               public virtual void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl)
                {
                        Error_ValueCannotBeConvertedCore (ec, loc, target, expl);
                }
@@ -316,17 +320,10 @@ namespace Mono.CSharp {
                                TypeManager.CSharpName (type), name);
                }
 
-               public void Error_ValueAssignment (ResolveContext rc, Expression rhs)
+               public virtual void Error_ValueAssignment (ResolveContext rc, Expression rhs)
                {
                        if (rhs == EmptyExpression.LValueMemberAccess || rhs == EmptyExpression.LValueMemberOutAccess) {
-                               rc.Report.SymbolRelatedToPreviousError (type);
-                               if (rc.CurrentInitializerVariable != null) {
-                                       rc.Report.Error (1918, loc, "Members of value type `{0}' cannot be assigned using a property `{1}' object initializer",
-                                               type.GetSignatureForError (), GetSignatureForError ());
-                               } else {
-                                       rc.Report.Error (1612, loc, "Cannot modify a value type return value of `{0}'. Consider storing the value in a temporary variable",
-                                               GetSignatureForError ());
-                               }
+                               // Already reported as CS1612
                        } else {
                                rc.Report.Error (131, loc, "The left-hand side of an assignment must be a variable, a property or an indexer");
                        }
@@ -363,6 +360,27 @@ namespace Mono.CSharp {
                        }
                }
 
+               //
+               // Implements identical simple name and type-name resolution
+               //
+               public Expression ProbeIdenticalTypeName (ResolveContext rc, Expression left, SimpleName name)
+               {
+                       var t = left.Type;
+                       if (t.Kind == MemberKind.InternalCompilerType || t is ElementTypeSpec || t.Arity > 0)
+                               return left;
+
+                       // In a member access of the form E.I, if E is a single identifier, and if the meaning of E as a simple-name is
+                       // a constant, field, property, local variable, or parameter with the same type as the meaning of E as a type-name
+
+                       if (left is MemberExpr || left is VariableReference) {
+                               var identical_type = rc.LookupNamespaceOrType (name.Name, 0, LookupMode.Probing, loc) as TypeExpr;
+                               if (identical_type != null && identical_type.Type == left.Type)
+                                       return identical_type;
+                       }
+
+                       return left;
+               }
+
                public virtual string GetSignatureForError ()
                {
                        return type.GetDefinition ().GetSignatureForError ();
@@ -536,38 +554,40 @@ namespace Mono.CSharp {
                                ec.EmitThis ();
 
                        // Emit original code
-                       EmitToFieldSource (ec);
-
-                       //
-                       // Store the result to temporary field when we
-                       // cannot load `this' directly
-                       //
-                       var field = ec.GetTemporaryField (type);
-                       if (needs_temporary) {
+                       var field = EmitToFieldSource (ec);
+                       if (field == null) {
                                //
-                               // Create temporary local (we cannot load `this' before Emit)
+                               // Store the result to temporary field when we
+                               // cannot load `this' directly
                                //
-                               var temp = ec.GetTemporaryLocal (type);
-                               ec.Emit (OpCodes.Stloc, temp);
+                               field = ec.GetTemporaryField (type);
+                               if (needs_temporary) {
+                                       //
+                                       // Create temporary local (we cannot load `this' before Emit)
+                                       //
+                                       var temp = ec.GetTemporaryLocal (type);
+                                       ec.Emit (OpCodes.Stloc, temp);
 
-                               ec.EmitThis ();
-                               ec.Emit (OpCodes.Ldloc, temp);
-                               field.EmitAssignFromStack (ec);
+                                       ec.EmitThis ();
+                                       ec.Emit (OpCodes.Ldloc, temp);
+                                       field.EmitAssignFromStack (ec);
 
-                               ec.FreeTemporaryLocal (temp, type);
-                       } else {
-                               field.EmitAssignFromStack (ec);
+                                       ec.FreeTemporaryLocal (temp, type);
+                               } else {
+                                       field.EmitAssignFromStack (ec);
+                               }
                        }
 
                        return field;
                }
 
-               protected virtual void EmitToFieldSource (EmitContext ec)
+               protected virtual FieldExpr EmitToFieldSource (EmitContext ec)
                {
                        //
                        // Default implementation calls Emit method
                        //
                        Emit (ec);
+                       return null;
                }
 
                protected static void EmitExpressionsList (EmitContext ec, List<Expression> expressions)
@@ -909,7 +929,7 @@ namespace Mono.CSharp {
                                        converted = Convert.ImplicitConversion (ec, source, btypes.ULong, source.loc);
 
                                if (converted == null) {
-                                       source.Error_ValueCannotBeConverted (ec, source.loc, btypes.Int, false);
+                                       source.Error_ValueCannotBeConverted (ec, btypes.Int, false);
                                        return null;
                                }
                        }
@@ -1025,9 +1045,30 @@ namespace Mono.CSharp {
                        if (es == null)
                                Error_InvalidExpressionStatement (ec);
 
+                       if (!(e is Assign) && (e.Type.IsGenericTask || e.Type == ec.Module.PredefinedTypes.Task.TypeSpec)) {
+                               WarningAsyncWithoutWait (ec, e);
+                       }
+
                        return es;
                }
 
+               static void WarningAsyncWithoutWait (BlockContext bc, Expression e)
+               {
+                       if (bc.CurrentAnonymousMethod is AsyncInitializer) {
+                               bc.Report.Warning (4014, 1, e.Location,
+                                       "The statement is not awaited and execution of current method continues before the call is completed. Consider using `await' operator");
+                               return;
+                       }
+
+                       var inv = e as Invocation;
+                       if (inv != null && inv.MethodGroup != null && inv.MethodGroup.BestCandidate.IsAsync) {
+                               // The warning won't be reported for imported methods to maintain warning compatiblity with csc 
+                               bc.Report.Warning (4014, 1, e.Location,
+                                       "The statement is not awaited and execution of current method continues before the call is completed. Consider using `await' operator or calling `Wait' method");
+                               return;
+                       }
+               }
+
                /// <summary>
                ///   Requests the expression to be emitted in a `statement'
                ///   context.  This means that no new value is left on the
@@ -1926,6 +1967,12 @@ namespace Mono.CSharp {
 
                #region Properties
 
+               public override bool IsSideEffectFree {
+                       get {
+                               return expr.IsSideEffectFree;
+                       }
+               }
+
                public Expression OriginalExpression {
                        get {
                                return orig_expr;
@@ -1998,6 +2045,11 @@ namespace Mono.CSharp {
                        expr.Emit (ec);
                }
 
+               public override Expression EmitToField (EmitContext ec)
+               {
+                       return expr.EmitToField(ec);
+               }
+
                public override void EmitBranchable (EmitContext ec, Label target, bool on_true)
                {
                        expr.EmitBranchable (ec, target, on_true);
@@ -2254,9 +2306,11 @@ namespace Mono.CSharp {
                                }
                        }
 
+                       var report = ctx.Module.Compiler.Report;
+
                        var retval = ctx.LookupNamespaceOrType (Name, Arity, LookupMode.IgnoreAccessibility, loc);
                        if (retval != null) {
-                               ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (retval.Type);
+                               report.SymbolRelatedToPreviousError (retval.Type);
                                ErrorIsInaccesible (ctx, retval.GetSignatureForError (), loc);
                                return;
                        }
@@ -2267,7 +2321,17 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       NamespaceContainer.Error_NamespaceNotFound (loc, Name, ctx.Module.Compiler.Report);
+                       var ns_candidates = ctx.Module.GlobalRootNamespace.FindTypeNamespaces (ctx, Name, Arity);
+                       if (ns_candidates != null) {
+                               string usings = string.Join ("' or `", ns_candidates.ToArray ());
+                               report.Error (246, loc,
+                                       "The type or namespace name `{0}' could not be found. Are you missing `{1}' using directive?",
+                                       Name, usings);
+                       } else {
+                               report.Error (246, loc,
+                                       "The type or namespace name `{0}' could not be found. Are you missing an assembly reference?",
+                                       Name);
+                       }
                }
 
                public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext ec)
@@ -2378,7 +2442,7 @@ namespace Mono.CSharp {
                                                        } else {
                                                                break;
                                                        }
-                                               } else if (me is MethodGroupExpr) {
+                                               } else if (me is MethodGroupExpr || me is PropertyExpr || me is IndexerExpr) {
                                                        // Leave it to overload resolution to report correct error
                                                } else {
                                                        // TODO: rc.Report.SymbolRelatedToPreviousError ()
@@ -2473,6 +2537,12 @@ namespace Mono.CSharp {
                                                                ErrorIsInaccesible (rc, e.GetSignatureForError (), loc);
                                                                return e;
                                                        }
+                                               } else {
+                                                       var me = MemberLookup (rc, false, rc.CurrentType, Name, Arity, restrictions & ~MemberLookupRestrictions.InvocableOnly, loc) as MemberExpr;
+                                                       if (me != null) {
+                                                               me.Error_UnexpectedKind (rc, me, "method group", me.KindName, loc);
+                                                               return ErrorExpression.Instance;
+                                                       }
                                                }
 
                                                e = rc.LookupNamespaceOrType (Name, -System.Math.Max (1, Arity), LookupMode.Probing, loc);
@@ -2734,7 +2804,7 @@ namespace Mono.CSharp {
                                //
                                TypeSpec[] targs = null;
                                if (method.DeclaringType != InstanceExpression.Type) {
-                                       var base_override = MemberCache.FindMember (InstanceExpression.Type, new MemberFilter (method), BindingRestriction.InstanceOnly) as MethodSpec;
+                                       var base_override = MemberCache.FindMember (InstanceExpression.Type, new MemberFilter (method), BindingRestriction.InstanceOnly | BindingRestriction.OverrideOnly) as MethodSpec;
                                        if (base_override != null && base_override.DeclaringType != method.DeclaringType) {
                                                if (base_override.IsGeneric)
                                                        targs = method.TypeArguments;
@@ -2743,8 +2813,14 @@ namespace Mono.CSharp {
                                        }
                                }
 
-                               // TODO: For now we do it for any hoisted call even if it's needed for
-                               // hoisted stories only but that requires a new expression wrapper
+                               //
+                               // When base access is used inside anonymous method/iterator/etc we need to
+                               // get back to the context of original type. We do it by emiting proxy
+                               // method in original class and rewriting base call to this compiler
+                               // generated method call which does the actual base invocation. This may
+                               // introduce redundant storey but with `this' only but it's tricky to avoid
+                               // at this stage as we don't know what expressions follow base
+                               //
                                if (rc.CurrentAnonymousMethod != null) {
                                        if (targs == null && method.IsGeneric) {
                                                targs = method.TypeArguments;
@@ -2758,8 +2834,9 @@ namespace Mono.CSharp {
 
                                        // Ideally this should apply to any proxy rewrite but in the case of unary mutators on
                                        // get/set member expressions second call would fail to proxy because left expression
-                                       // would be of 'this' and not 'base'
-                                       if (rc.CurrentType.IsStruct)
+                                       // would be of 'this' and not 'base' because we share InstanceExpression for get/set
+                                       // FIXME: The async check is another hack but will probably fail with mutators
+                                       if (rc.CurrentType.IsStruct || rc.CurrentAnonymousMethod.Storey is AsyncTaskStorey)
                                                InstanceExpression = new This (loc).Resolve (rc);
                                }
 
@@ -2872,28 +2949,31 @@ namespace Mono.CSharp {
                                member.GetSignatureForError (), qualifier.GetSignatureForError (), rc.CurrentType.GetSignatureForError ());
                }
 
-               //
-               // Implements identicial simple name and type-name
-               //
-               public Expression ProbeIdenticalTypeName (ResolveContext rc, Expression left, SimpleName name)
+               public bool ResolveInstanceExpression (ResolveContext rc, Expression rhs)
                {
-                       var t = left.Type;
-                       if (t.Kind == MemberKind.InternalCompilerType || t is ElementTypeSpec || t.Arity > 0)
-                               return left;
+                       if (!ResolveInstanceExpressionCore (rc, rhs))
+                               return false;
 
-                       // In a member access of the form E.I, if E is a single identifier, and if the meaning of E as a simple-name is
-                       // a constant, field, property, local variable, or parameter with the same type as the meaning of E as a type-name
+                       //
+                       // Check intermediate value modification which won't have any effect
+                       //
+                       if (rhs != null && InstanceExpression.Type.IsStruct &&
+                               (InstanceExpression is PropertyExpr || InstanceExpression is IndexerExpr || InstanceExpression is Invocation)) {
 
-                       if (left is MemberExpr || left is VariableReference) {
-                               var identical_type = rc.LookupNamespaceOrType (name.Name, 0, LookupMode.Probing, loc) as TypeExpr;
-                               if (identical_type != null && identical_type.Type == left.Type)
-                                       return identical_type;
+                               if (rc.CurrentInitializerVariable != null) {
+                                       rc.Report.Error (1918, loc, "Members of value type `{0}' cannot be assigned using a property `{1}' object initializer",
+                                               InstanceExpression.Type.GetSignatureForError (), InstanceExpression.GetSignatureForError ());
+                               } else {
+                                       rc.Report.Error (1612, loc,
+                                               "Cannot modify a value type return value of `{0}'. Consider storing the value in a temporary variable",
+                                               InstanceExpression.GetSignatureForError ());
+                               }
                        }
 
-                       return left;
+                       return true;
                }
 
-               public bool ResolveInstanceExpression (ResolveContext rc, Expression rhs)
+               bool ResolveInstanceExpressionCore (ResolveContext rc, Expression rhs)
                {
                        if (IsStatic) {
                                if (InstanceExpression != null) {
@@ -2933,7 +3013,7 @@ namespace Mono.CSharp {
                                                        "An object reference is required to access non-static member `{0}'",
                                                        GetSignatureForError ());
 
-                                       InstanceExpression = new CompilerGeneratedThis (type, loc).Resolve (rc);
+                                       InstanceExpression = new CompilerGeneratedThis (rc.CurrentType, loc).Resolve (rc);
                                        return false;
                                }
 
@@ -2957,14 +3037,17 @@ namespace Mono.CSharp {
 
                        var me = InstanceExpression as MemberExpr;
                        if (me != null) {
-                               me.ResolveInstanceExpression (rc, rhs);
-
-                               var fe = me as FieldExpr;
-                               if (fe != null && fe.IsMarshalByRefAccess (rc)) {
-                                       rc.Report.SymbolRelatedToPreviousError (me.DeclaringType);
-                                       rc.Report.Warning (1690, 1, loc,
-                                               "Cannot call methods, properties, or indexers on `{0}' because it is a value type member of a marshal-by-reference class",
-                                               me.GetSignatureForError ());
+                               me.ResolveInstanceExpressionCore (rc, rhs);
+
+                               // Using this check to detect probing instance expression resolve
+                               if (!rc.OmitStructFlowAnalysis) {
+                                       var fe = me as FieldExpr;
+                                       if (fe != null && fe.IsMarshalByRefAccess (rc)) {
+                                               rc.Report.SymbolRelatedToPreviousError (me.DeclaringType);
+                                               rc.Report.Warning (1690, 1, loc,
+                                                       "Cannot call methods, properties, or indexers on `{0}' because it is a value type member of a marshal-by-reference class",
+                                                       me.GetSignatureForError ());
+                                       }
                                }
 
                                return true;
@@ -3132,8 +3215,12 @@ namespace Mono.CSharp {
                        }
 
                        var me = ExtensionExpression as MemberExpr;
-                       if (me != null)
+                       if (me != null) {
                                me.ResolveInstanceExpression (ec, null);
+                               var fe = me as FieldExpr;
+                               if (fe != null)
+                                       fe.Spec.MemberDefinition.SetIsUsed ();
+                       }
 
                        InstanceExpression = null;
                        return this;
@@ -3325,7 +3412,7 @@ namespace Mono.CSharp {
                        call.Emit (ec, best_candidate, arguments, loc);                 
                }
 
-               public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
+               public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl)
                {
                        ec.Report.Error (428, loc, "Cannot convert method group `{0}' to non-delegate type `{1}'. Consider using parentheses to invoke the method",
                                Name, TypeManager.CSharpName (target));
@@ -3403,11 +3490,35 @@ namespace Mono.CSharp {
                                best_candidate_return = best_candidate.ReturnType;
                        }
 
+                       if (best_candidate.IsGeneric && TypeParameterSpec.HasAnyTypeParameterConstrained (best_candidate.GenericDefinition)) {
+                               ConstraintChecker cc = new ConstraintChecker (ec);
+                               cc.CheckAll (best_candidate.GetGenericMethodDefinition (), best_candidate.TypeArguments, best_candidate.Constraints, loc);
+                       }
+
+                       //
+                       // Additional check for possible imported base override method which
+                       // could not be done during IsOverrideMethodBaseTypeAccessible
+                       //
+                       if (best_candidate.IsVirtual && (best_candidate.DeclaringType.Modifiers & Modifiers.PROTECTED) != 0 &&
+                               best_candidate.MemberDefinition.IsImported && !best_candidate.DeclaringType.IsAccessible (ec)) {
+                               ec.Report.SymbolRelatedToPreviousError (best_candidate);
+                               ErrorIsInaccesible (ec, best_candidate.GetSignatureForError (), loc);
+                       }
+
                        return this;
                }
 
                public override MemberExpr ResolveMemberAccess (ResolveContext ec, Expression left, SimpleName original)
                {
+                       var fe = left as FieldExpr;
+                       if (fe != null) {
+                               //
+                               // Using method-group on struct fields makes the struct assigned. I am not sure
+                               // why but that's what .net does
+                               //
+                               fe.Spec.MemberDefinition.SetIsAssigned ();
+                       }
+
                        simple_name = original;
                        return base.ResolveMemberAccess (ec, left, original);
                }
@@ -3553,7 +3664,6 @@ namespace Mono.CSharp {
                TypeSpec best_candidate_return_type;
 
                SessionReportPrinter lambda_conv_msgs;
-               ReportPrinter prev_recorder;
 
                public OverloadResolver (IList<MemberSpec> members, Restrictions restrictions, Location loc)
                        : this (members, null, restrictions, loc)
@@ -3686,7 +3796,9 @@ namespace Mono.CSharp {
                                if (!TypeSpecComparer.Equals (p_m.Parameters.Types, q_m.Parameters.Types))
                                        return 0;
 
+                               var orig_p = p;
                                p = p_m.ReturnType;
+                               var orig_q = q;
                                q = q_m.ReturnType;
 
                                //
@@ -3703,21 +3815,30 @@ namespace Mono.CSharp {
                                        return p.Kind != MemberKind.Void ? 1: 0;
                                }
 
+                               var am = (AnonymousMethodExpression) a.Expr;
+
                                //
                                // When anonymous method is an asynchronous, and P has a return type Task<Y1>, and Q has a return type Task<Y2>
                                // better conversion is performed between underlying types Y1 and Y2
                                //
                                if (p.IsGenericTask || q.IsGenericTask) {
-                                       var async_am = a.Expr as AnonymousMethodExpression;
-                                       if (async_am != null && async_am.Block.IsAsync) {
-
-                                               if (p.IsGenericTask != q.IsGenericTask) {
-                                                       return 0;
-                                               }
-
+                                       if (am.Block.IsAsync && p.IsGenericTask && q.IsGenericTask) {
                                                q = q.TypeArguments[0];
                                                p = p.TypeArguments[0];
                                        }
+                               } else if (q != p) {
+                                       //
+                                       // LAMESPEC: Lambda expression returning dynamic type has identity (better) conversion to delegate returning object type
+                                       //
+                                       if (q.BuiltinType == BuiltinTypeSpec.Type.Object) {
+                                               var am_rt = am.InferReturnType (ec, null, orig_q);
+                                               if (am_rt != null && am_rt.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
+                                                       return 2;
+                                       } else if (p.BuiltinType == BuiltinTypeSpec.Type.Object) {
+                                               var am_rt = am.InferReturnType (ec, null, orig_p);
+                                               if (am_rt != null && am_rt.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
+                                                       return 1;
+                                       }
                                }
 
                                //
@@ -3922,19 +4043,20 @@ namespace Mono.CSharp {
                        //
                        //  Foo (int i) is better than Foo (int i, long l = 0)
                        //  Foo (params int[] args) is better than Foo (int i = 0, params int[] args)
+                       //  Foo (string s, params string[] args) is better than Foo (params string[] args)
                        //
                        // Prefer non-optional version
                        //
                        // LAMESPEC: Specification claims this should be done at last but the opposite is true
                        //
                        if (candidate_params == best_params && candidate_pd.Count != best_pd.Count) {
-                               if (candidate_pd.Count >= best_pd.Count)
-                                       return false;
-
                                if (j < candidate_pd.Count && candidate_pd.FixedParameters[j].HasDefaultValue)
                                        return false;
 
-                               return true;
+                               if (j < best_pd.Count && best_pd.FixedParameters[j].HasDefaultValue)
+                                       return true;
+
+                               return candidate_pd.Count >= best_pd.Count;
                        }
 
                        //
@@ -3996,6 +4118,32 @@ namespace Mono.CSharp {
                        return false;
                }
 
+               static bool CheckInflatedArguments (MethodSpec ms)
+               {
+                       if (!TypeParameterSpec.HasAnyTypeParameterTypeConstrained (ms.GenericDefinition))
+                               return true;
+
+                       // Setup constraint checker for probing only
+                       ConstraintChecker cc = new ConstraintChecker (null);
+
+                       var mp = ms.Parameters.Types;
+                       for (int i = 0; i < mp.Length; ++i) {
+                               var type = mp[i] as InflatedTypeSpec;
+                               if (type == null)
+                                       continue;
+
+                               var targs = type.TypeArguments;
+                               if (targs.Length == 0)
+                                       continue;
+
+                               // TODO: Checking inflated MVAR arguments should be enough
+                               if (!cc.CheckAll (type.GetDefinition (), targs, type.Constraints, Location.Null))
+                                       return false;
+                       }
+
+                       return true;
+               }
+
                public static void Error_ConstructorMismatch (ResolveContext rc, TypeSpec type, int argCount, Location loc)
                {
                        rc.Report.Error (1729, loc,
@@ -4011,6 +4159,7 @@ namespace Mono.CSharp {
                //
                // A return value rates candidate method compatibility,
                // 0 = the best, int.MaxValue = the worst
+               // -1 = fatal error
                //
                int IsApplicable (ResolveContext ec, ref Arguments arguments, int arg_count, ref MemberSpec candidate, IParametersMember pm, ref bool params_expanded_form, ref bool dynamicArgument, ref TypeSpec returnType)
                {
@@ -4026,10 +4175,15 @@ namespace Mono.CSharp {
                        Arguments orig_args = arguments;
 
                        if (arg_count != param_count) {
-                               for (int i = 0; i < pd.Count; ++i) {
-                                       if (pd.FixedParameters[i].HasDefaultValue) {
-                                               optional_count = pd.Count - i;
-                                               break;
+                               //
+                               // No arguments expansion when doing exact match for delegates
+                               //
+                               if ((restrictions & Restrictions.CovariantDelegate) == 0) {
+                                       for (int i = 0; i < pd.Count; ++i) {
+                                               if (pd.FixedParameters[i].HasDefaultValue) {
+                                                       optional_count = pd.Count - i;
+                                                       break;
+                                               }
                                        }
                                }
 
@@ -4042,6 +4196,9 @@ namespace Mono.CSharp {
                                        } else if (arg_count > param_count) {
                                                int args_gap = System.Math.Abs (arg_count - param_count);
                                                return int.MaxValue - 10000 + args_gap;
+                                       } else if (arg_count < param_count - optional_count) {
+                                               int args_gap = System.Math.Abs (param_count - optional_count - arg_count);
+                                               return int.MaxValue - 10000 + args_gap;
                                        }
                                } else if (arg_count != param_count) {
                                        int args_gap = System.Math.Abs (arg_count - param_count);
@@ -4127,15 +4284,24 @@ namespace Mono.CSharp {
                                arg_count = arguments.Count;
                        }
 
+                       //
+                       // Don't do any expensive checks when the candidate cannot succeed
+                       //
+                       if (arg_count != param_count && !cpd.HasParams)
+                               return (param_count - arg_count) * 2 + 1;
+
+                       var dep = candidate.GetMissingDependencies ();
+                       if (dep != null) {
+                               ImportedTypeDefinition.Error_MissingDependency (ec, dep, loc);
+                               return -1;
+                       }
+
                        //
                        // 1. Handle generic method using type arguments when specified or type inference
                        //
                        TypeSpec[] ptypes;
                        var ms = candidate as MethodSpec;
                        if (ms != null && ms.IsGeneric) {
-                               // Setup constraint checker for probing only
-                               ConstraintChecker cc = new ConstraintChecker (null);
-
                                if (type_arguments != null) {
                                        var g_args_count = ms.Arity;
                                        if (g_args_count != type_arguments.Count)
@@ -4143,31 +4309,50 @@ namespace Mono.CSharp {
 
                                        ms = ms.MakeGenericMethod (ec, type_arguments.Arguments);
                                } else {
-                                       // TODO: It should not be here (we don't know yet whether any argument is lambda) but
-                                       // for now it simplifies things. I should probably add a callback to ResolveContext
+                                       //
+                                       // Deploy custom error reporting for infered anonymous expression or lambda methods. When
+                                       // probing lambda methods keep all errors reported in separate set and once we are done and no best
+                                       // candidate was found use the set to report more details about what was wrong with lambda body.
+                                       // The general idea is to distinguish between code errors and errors caused by
+                                       // trial-and-error type inference
+                                       //
                                        if (lambda_conv_msgs == null) {
-                                               lambda_conv_msgs = new SessionReportPrinter ();
-                                               prev_recorder = ec.Report.SetPrinter (lambda_conv_msgs);
+                                               for (int i = 0; i < arg_count; i++) {
+                                                       Argument a = arguments[i];
+                                                       if (a == null)
+                                                               continue;
+
+                                                       var am = a.Expr as AnonymousMethodExpression;
+                                                       if (am != null) {
+                                                               if (lambda_conv_msgs == null)
+                                                                       lambda_conv_msgs = new SessionReportPrinter ();
+
+                                                               am.TypeInferenceReportPrinter = lambda_conv_msgs;
+                                                       }
+                                               }
                                        }
 
                                        var ti = new TypeInference (arguments);
                                        TypeSpec[] i_args = ti.InferMethodArguments (ec, ms);
-                                       lambda_conv_msgs.EndSession ();
 
                                        if (i_args == null)
                                                return ti.InferenceScore - 20000;
 
+                                       //
+                                       // Clear any error messages when the result was success
+                                       //
+                                       if (lambda_conv_msgs != null)
+                                               lambda_conv_msgs.ClearSession ();
+
                                        if (i_args.Length != 0) {
                                                ms = ms.MakeGenericMethod (ec, i_args);
                                        }
-
-                                       cc.IgnoreInferredDynamic = true;
                                }
 
                                //
                                // Type arguments constraints have to match for the method to be applicable
                                //
-                               if (!cc.CheckAll (ms.GetGenericMethodDefinition (), ms.TypeArguments, ms.Constraints, loc)) {
+                               if (!CheckInflatedArguments (ms)) {
                                        candidate = ms;
                                        return int.MaxValue - 25000;
                                }
@@ -4216,18 +4401,21 @@ namespace Mono.CSharp {
                                        // if the type matches
                                        //
                                        Expression e = fp.DefaultValue;
-                                       if (!(e is Constant) || e.Type.IsGenericOrParentIsGeneric || e.Type.IsGenericParameter) {
+                                       if (e != null) {
+                                               e = ResolveDefaultValueArgument (ec, ptypes[i], e, loc);
+                                       }
+
+                                       if ((fp.ModFlags & Parameter.Modifier.CallerMask) != 0) {
                                                //
-                                               // LAMESPEC: No idea what the exact rules are for System.Reflection.Missing.Value instead of null
+                                               // LAMESPEC: Attributes can be mixed together with build-in priority
                                                //
-                                               if (e == EmptyExpression.MissingValue && ptypes[i].BuiltinType == BuiltinTypeSpec.Type.Object || ptypes[i].BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
-                                                       e = new MemberAccess (new MemberAccess (new MemberAccess (
-                                                               new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "System", loc), "Reflection", loc), "Missing", loc), "Value", loc);
-                                               } else {
-                                                       e = new DefaultValueExpression (new TypeExpression (ptypes [i], loc), loc);
+                                               if ((fp.ModFlags & Parameter.Modifier.CallerLineNumber) != 0) {
+                                                       e = new IntLiteral (ec.BuiltinTypes, loc.Row, loc);
+                                               } else if ((fp.ModFlags & Parameter.Modifier.CallerFilePath) != 0) {
+                                                       e = new StringLiteral (ec.BuiltinTypes, loc.NameFullPath, loc);
+                                               } else if (ec.MemberContext.CurrentMemberDefinition != null) {
+                                                       e = new StringLiteral (ec.BuiltinTypes, ec.MemberContext.CurrentMemberDefinition.GetCallerMemberName (), loc);
                                                }
-
-                                               e = e.Resolve (ec);
                                        }
 
                                        arguments[i] = new Argument (e, Argument.AType.Default);
@@ -4307,6 +4495,39 @@ namespace Mono.CSharp {
                        return 0;
                }
 
+               public static Expression ResolveDefaultValueArgument (ResolveContext ec, TypeSpec ptype, Expression e, Location loc)
+               {
+                       if (e is Constant && e.Type == ptype)
+                               return e;
+
+                       //
+                       // LAMESPEC: No idea what the exact rules are for System.Reflection.Missing.Value instead of null
+                       //
+                       if (e == EmptyExpression.MissingValue && ptype.BuiltinType == BuiltinTypeSpec.Type.Object || ptype.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
+                               e = new MemberAccess (new MemberAccess (new MemberAccess (
+                                       new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "System", loc), "Reflection", loc), "Missing", loc), "Value", loc);
+                       } else if (e is Constant) {
+                               //
+                               // Handles int to int? conversions
+                               //
+                               e = Convert.ImplicitConversionStandard (ec, e, ptype, loc);
+
+                               //
+                               // When constant type paramter contains type argument
+                               //
+                               // Foo (T[] arg = null)
+                               //
+                               if (e == null) {
+                                       e = new DefaultValueExpression (new TypeExpression (ptype, loc), loc);
+                               }
+                       } else {
+                               e = new DefaultValueExpression (new TypeExpression (ptype, loc), loc);
+                       }
+
+
+                       return e.Resolve (ec);
+               }
+
                //
                // Tests argument compatibility with the parameter
                // The possible return values are
@@ -4351,28 +4572,11 @@ namespace Mono.CSharp {
                                if (argument.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic && (restrictions & Restrictions.CovariantDelegate) == 0)
                                        return -1;
 
-                               //
-                               // Deploy custom error reporting for lambda methods. When probing lambda methods
-                               // keep all errors reported in separate set and once we are done and no best
-                               // candidate was found, this set is used to report more details about what was wrong
-                               // with lambda body
-                               //
-                               if (argument.Expr.Type == InternalType.AnonymousMethod) {
-                                       if (lambda_conv_msgs == null) {
-                                               lambda_conv_msgs = new SessionReportPrinter ();
-                                               prev_recorder = ec.Report.SetPrinter (lambda_conv_msgs);
-                                       }
-                               }
-
                                //
                                // Use implicit conversion in all modes to return same candidates when the expression
                                // is used as argument or delegate conversion
                                //
                                if (!Convert.ImplicitConversionExists (ec, argument.Expr, parameter)) {
-                                       if (lambda_conv_msgs != null) {
-                                               lambda_conv_msgs.EndSession ();
-                                       }
-
                                        return 2;
                                }
                        }
@@ -4398,7 +4602,7 @@ namespace Mono.CSharp {
                                        return p;
                                if (specific == ac_q.Element)
                                        return q;
-                       } else if (TypeManager.IsGenericType (p)) {
+                       } else if (p.IsGeneric && q.IsGeneric) {
                                var pargs = TypeManager.GetTypeArguments (p);
                                var qargs = TypeManager.GetTypeArguments (q);
 
@@ -4442,147 +4646,148 @@ namespace Mono.CSharp {
                        bool error_mode = false;
                        MemberSpec invocable_member = null;
 
-                       // Be careful, cannot return until error reporter is restored
                        while (true) {
                                best_candidate = null;
                                best_candidate_rate = int.MaxValue;
 
                                var type_members = members;
-                               try {
+                               do {
+                                       for (int i = 0; i < type_members.Count; ++i) {
+                                               var member = type_members[i];
+
+                                               //
+                                               // Methods in a base class are not candidates if any method in a derived
+                                               // class is applicable
+                                               //
+                                               if ((member.Modifiers & Modifiers.OVERRIDE) != 0)
+                                                       continue;
 
-                                       do {
-                                               for (int i = 0; i < type_members.Count; ++i) {
-                                                       var member = type_members[i];
+                                               if (!error_mode) {
+                                                       if (!member.IsAccessible (rc))
+                                                               continue;
+
+                                                       if (rc.IsRuntimeBinder && !member.DeclaringType.IsAccessible (rc))
+                                                               continue;
+
+                                                       if ((member.Modifiers & (Modifiers.PROTECTED | Modifiers.STATIC)) == Modifiers.PROTECTED &&
+                                                               instance_qualifier != null && !instance_qualifier.CheckProtectedMemberAccess (rc, member)) {
+                                                               continue;
+                                                       }
+                                               }
 
+                                               IParametersMember pm = member as IParametersMember;
+                                               if (pm == null) {
                                                        //
-                                                       // Methods in a base class are not candidates if any method in a derived
-                                                       // class is applicable
+                                                       // Will use it later to report ambiguity between best method and invocable member
                                                        //
-                                                       if ((member.Modifiers & Modifiers.OVERRIDE) != 0)
-                                                               continue;
+                                                       if (Invocation.IsMemberInvocable (member))
+                                                               invocable_member = member;
 
-                                                       if (!error_mode) {
-                                                               if (!member.IsAccessible (rc))
-                                                                       continue;
+                                                       continue;
+                                               }
 
-                                                               if (rc.IsRuntimeBinder && !member.DeclaringType.IsAccessible (rc))
-                                                                       continue;
+                                               //
+                                               // Overload resolution is looking for base member but using parameter names
+                                               // and default values from the closest member. That means to do expensive lookup
+                                               // for the closest override for virtual or abstract members
+                                               //
+                                               if ((member.Modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT)) != 0) {
+                                                       var override_params = base_provider.GetOverrideMemberParameters (member);
+                                                       if (override_params != null)
+                                                               pm = override_params;
+                                               }
+
+                                               //
+                                               // Check if the member candidate is applicable
+                                               //
+                                               bool params_expanded_form = false;
+                                               bool dynamic_argument = false;
+                                               TypeSpec rt = pm.MemberType;
+                                               int candidate_rate = IsApplicable (rc, ref candidate_args, args_count, ref member, pm, ref params_expanded_form, ref dynamic_argument, ref rt);
+
+                                               if (lambda_conv_msgs != null)
+                                                       lambda_conv_msgs.EndSession ();
 
-                                                               if ((member.Modifiers & (Modifiers.PROTECTED | Modifiers.STATIC)) == Modifiers.PROTECTED &&
-                                                                       instance_qualifier != null && !instance_qualifier.CheckProtectedMemberAccess (rc, member)) {
+                                               //
+                                               // How does it score compare to others
+                                               //
+                                               if (candidate_rate < best_candidate_rate) {
+
+                                                       // Fatal error (missing dependency), cannot continue
+                                                       if (candidate_rate < 0)
+                                                               return null;
+
+                                                       best_candidate_rate = candidate_rate;
+                                                       best_candidate = member;
+                                                       best_candidate_args = candidate_args;
+                                                       best_candidate_params = params_expanded_form;
+                                                       best_candidate_dynamic = dynamic_argument;
+                                                       best_parameter_member = pm;
+                                                       best_candidate_return_type = rt;
+                                               } else if (candidate_rate == 0) {
+                                                       //
+                                                       // The member look is done per type for most operations but sometimes
+                                                       // it's not possible like for binary operators overload because they
+                                                       // are unioned between 2 sides
+                                                       //
+                                                       if ((restrictions & Restrictions.BaseMembersIncluded) != 0) {
+                                                               if (TypeSpec.IsBaseClass (best_candidate.DeclaringType, member.DeclaringType, true))
                                                                        continue;
-                                                               }
                                                        }
 
-                                                       IParametersMember pm = member as IParametersMember;
-                                                       if (pm == null) {
+                                                       bool is_better;
+                                                       if (best_candidate.DeclaringType.IsInterface && member.DeclaringType.ImplementsInterface (best_candidate.DeclaringType, false)) {
+                                                               //
+                                                               // We pack all interface members into top level type which makes the overload resolution
+                                                               // more complicated for interfaces. We compensate it by removing methods with same
+                                                               // signature when building the cache hence this path should not really be hit often
                                                                //
-                                                               // Will use it later to report ambiguity between best method and invocable member
+                                                               // Example:
+                                                               // interface IA { void Foo (int arg); }
+                                                               // interface IB : IA { void Foo (params int[] args); }
                                                                //
-                                                               if (Invocation.IsMemberInvocable (member))
-                                                                       invocable_member = member;
+                                                               // IB::Foo is the best overload when calling IB.Foo (1)
+                                                               //
+                                                               is_better = true;
+                                                               if (ambiguous_candidates != null) {
+                                                                       foreach (var amb_cand in ambiguous_candidates) {
+                                                                               if (member.DeclaringType.ImplementsInterface (best_candidate.DeclaringType, false)) {
+                                                                                       continue;
+                                                                               }
 
-                                                               continue;
-                                                       }
+                                                                               is_better = false;
+                                                                               break;
+                                                                       }
 
-                                                       //
-                                                       // Overload resolution is looking for base member but using parameter names
-                                                       // and default values from the closest member. That means to do expensive lookup
-                                                       // for the closest override for virtual or abstract members
-                                                       //
-                                                       if ((member.Modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT)) != 0) {
-                                                               var override_params = base_provider.GetOverrideMemberParameters (member);
-                                                               if (override_params != null)
-                                                                       pm = override_params;
+                                                                       if (is_better)
+                                                                               ambiguous_candidates = null;
+                                                               }
+                                                       } else {
+                                                               // Is the new candidate better
+                                                               is_better = BetterFunction (rc, candidate_args, member, pm.Parameters, params_expanded_form, best_candidate, best_parameter_member.Parameters, best_candidate_params);
                                                        }
 
-                                                       //
-                                                       // Check if the member candidate is applicable
-                                                       //
-                                                       bool params_expanded_form = false;
-                                                       bool dynamic_argument = false;
-                                                       TypeSpec rt = pm.MemberType;
-                                                       int candidate_rate = IsApplicable (rc, ref candidate_args, args_count, ref member, pm, ref params_expanded_form, ref dynamic_argument, ref rt);
-
-                                                       //
-                                                       // How does it score compare to others
-                                                       //
-                                                       if (candidate_rate < best_candidate_rate) {
-                                                               best_candidate_rate = candidate_rate;
+                                                       if (is_better) {
                                                                best_candidate = member;
                                                                best_candidate_args = candidate_args;
                                                                best_candidate_params = params_expanded_form;
                                                                best_candidate_dynamic = dynamic_argument;
                                                                best_parameter_member = pm;
                                                                best_candidate_return_type = rt;
-                                                       } else if (candidate_rate == 0) {
-                                                               //
-                                                               // The member look is done per type for most operations but sometimes
-                                                               // it's not possible like for binary operators overload because they
-                                                               // are unioned between 2 sides
-                                                               //
-                                                               if ((restrictions & Restrictions.BaseMembersIncluded) != 0) {
-                                                                       if (TypeSpec.IsBaseClass (best_candidate.DeclaringType, member.DeclaringType, true))
-                                                                               continue;
-                                                               }
-
-                                                               bool is_better;
-                                                               if (best_candidate.DeclaringType.IsInterface && member.DeclaringType.ImplementsInterface (best_candidate.DeclaringType, false)) {
-                                                                       //
-                                                                       // We pack all interface members into top level type which makes the overload resolution
-                                                                       // more complicated for interfaces. We compensate it by removing methods with same
-                                                                       // signature when building the cache hence this path should not really be hit often
-                                                                       //
-                                                                       // Example:
-                                                                       // interface IA { void Foo (int arg); }
-                                                                       // interface IB : IA { void Foo (params int[] args); }
-                                                                       //
-                                                                       // IB::Foo is the best overload when calling IB.Foo (1)
-                                                                       //
-                                                                       is_better = true;
-                                                                       if (ambiguous_candidates != null) {
-                                                                               foreach (var amb_cand in ambiguous_candidates) {
-                                                                                       if (member.DeclaringType.ImplementsInterface (best_candidate.DeclaringType, false)) {
-                                                                                               continue;
-                                                                                       }
-
-                                                                                       is_better = false;
-                                                                                       break;
-                                                                               }
-
-                                                                               if (is_better)
-                                                                                       ambiguous_candidates = null;
-                                                                       }
-                                                               } else {
-                                                                       // Is the new candidate better
-                                                                       is_better = BetterFunction (rc, candidate_args, member, pm.Parameters, params_expanded_form, best_candidate, best_parameter_member.Parameters, best_candidate_params);
-                                                               }
+                                                       } else {
+                                                               // It's not better but any other found later could be but we are not sure yet
+                                                               if (ambiguous_candidates == null)
+                                                                       ambiguous_candidates = new List<AmbiguousCandidate> ();
 
-                                                               if (is_better) {
-                                                                       best_candidate = member;
-                                                                       best_candidate_args = candidate_args;
-                                                                       best_candidate_params = params_expanded_form;
-                                                                       best_candidate_dynamic = dynamic_argument;
-                                                                       best_parameter_member = pm;
-                                                                       best_candidate_return_type = rt;
-                                                               } else {
-                                                                       // It's not better but any other found later could be but we are not sure yet
-                                                                       if (ambiguous_candidates == null)
-                                                                               ambiguous_candidates = new List<AmbiguousCandidate> ();
-
-                                                                       ambiguous_candidates.Add (new AmbiguousCandidate (member, pm.Parameters, params_expanded_form));
-                                                               }
+                                                               ambiguous_candidates.Add (new AmbiguousCandidate (member, pm.Parameters, params_expanded_form));
                                                        }
-
-                                                       // Restore expanded arguments
-                                                       if (candidate_args != args)
-                                                               candidate_args = args;
                                                }
-                                       } while (best_candidate_rate != 0 && (type_members = base_provider.GetBaseMembers (type_members[0].DeclaringType.BaseType)) != null);
-                               } finally {
-                                       if (prev_recorder != null)
-                                               rc.Report.SetPrinter (prev_recorder);
-                               }
+
+                                               // Restore expanded arguments
+                                               if (candidate_args != args)
+                                                       candidate_args = args;
+                                       }
+                               } while (best_candidate_rate != 0 && (type_members = base_provider.GetBaseMembers (type_members[0].DeclaringType.BaseType)) != null);
 
                                //
                                // We've found exact match
@@ -4633,6 +4838,17 @@ namespace Mono.CSharp {
                                                args [0].Type.GetSignatureForError (), best_candidate.Name, best_candidate.GetSignatureForError ());
                                }
 
+                               //
+                               // Check type constraints only when explicit type arguments are used
+                               //
+                               if (best_candidate.IsGeneric && type_arguments != null) {
+                                       MethodSpec bc = best_candidate as MethodSpec;
+                                       if (bc != null && TypeParameterSpec.HasAnyTypeParameterConstrained (bc.GenericDefinition)) {
+                                               ConstraintChecker cc = new ConstraintChecker (rc);
+                                               cc.CheckAll (bc.GetGenericMethodDefinition (), bc.TypeArguments, bc.Constraints, loc);
+                                       }
+                               }
+
                                BestCandidateIsDynamic = true;
                                return null;
                        }
@@ -4686,19 +4902,19 @@ namespace Mono.CSharp {
                                return null;
 
                        //
-                       // Check ObsoleteAttribute on the best method
+                       // Don't run possibly expensive checks in probing mode
                        //
-                       ObsoleteAttribute oa = best_candidate.GetAttributeObsolete ();
-                       if (oa != null && !rc.IsObsolete)
-                               AttributeTester.Report_ObsoleteMessage (oa, best_candidate.GetSignatureForError (), loc, rc.Report);
+                       if (!rc.IsInProbingMode) {
+                               //
+                               // Check ObsoleteAttribute on the best method
+                               //
+                               ObsoleteAttribute oa = best_candidate.GetAttributeObsolete ();
+                               if (oa != null && !rc.IsObsolete)
+                                       AttributeTester.Report_ObsoleteMessage (oa, best_candidate.GetSignatureForError (), loc, rc.Report);
 
-                       var dep = best_candidate.GetMissingDependencies ();
-                       if (dep != null) {
-                               ImportedTypeDefinition.Error_MissingDependency (rc, dep, loc);
+                               best_candidate.MemberDefinition.SetIsUsed ();
                        }
 
-                       best_candidate.MemberDefinition.SetIsUsed ();
-
                        args = best_candidate_args;
                        return (T) best_candidate;
                }
@@ -4714,10 +4930,13 @@ namespace Mono.CSharp {
                        if (custom_errors != null && custom_errors.ArgumentMismatch (ec, method, a, idx))
                                return;
 
+                       if (a.Type == InternalType.ErrorType)
+                               return;
+
                        if (a is CollectionElementInitializer.ElementInitializerArgument) {
                                ec.Report.SymbolRelatedToPreviousError (method);
                                if ((expected_par.FixedParameters[idx].ModFlags & Parameter.Modifier.RefOutMask) != 0) {
-                                       ec.Report.Error (1954, loc, "The best overloaded collection initalizer method `{0}' cannot have 'ref', or `out' modifier",
+                                       ec.Report.Error (1954, loc, "The best overloaded collection initalizer method `{0}' cannot have `ref' or `out' modifier",
                                                TypeManager.CSharpSignature (method));
                                        return;
                                }
@@ -4726,7 +4945,7 @@ namespace Mono.CSharp {
                        } else if (IsDelegateInvoke) {
                                ec.Report.Error (1594, loc, "Delegate `{0}' has some invalid arguments",
                                        DelegateType.GetSignatureForError ());
-                       } else if (a.Type != InternalType.ErrorType) {
+                       } else {
                                ec.Report.SymbolRelatedToPreviousError (method);
                                ec.Report.Error (1502, loc, "The best overloaded method match for `{0}' has some invalid arguments",
                                        method.GetSignatureForError ());
@@ -4742,7 +4961,7 @@ namespace Mono.CSharp {
                                else
                                        ec.Report.Error (1620, loc, "Argument `#{0}' is missing `{1}' modifier",
                                                index, Parameter.GetModifierSignature (mod));
-                       } else if (a.Type != InternalType.ErrorType) {
+                       } else {
                                string p1 = a.GetSignatureForError ();
                                string p2 = TypeManager.CSharpName (paramType);
 
@@ -4751,7 +4970,12 @@ namespace Mono.CSharp {
                                        p2 = paramType.GetSignatureForErrorIncludingAssemblyName ();
                                }
 
-                               ec.Report.Error (1503, loc,
+                               if ((mod & Parameter.Modifier.RefOutMask) != 0) {
+                                       p1 = Parameter.GetModifierSignature (a.Modifier) + " " + p1;
+                                       p2 = Parameter.GetModifierSignature (a.Modifier) + " " + p2;
+                               }
+
+                               ec.Report.Error (1503, a.Expr.Location,
                                        "Argument `#{0}' cannot convert `{1}' expression to type `{2}'", index, p1, p2);
                        }
                }
@@ -4770,9 +4994,8 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       if (lambda_conv_msgs != null) {
-                               if (lambda_conv_msgs.Merge (rc.Report.Printer))
-                                       return;
+                       if (lambda_conv_msgs != null && lambda_conv_msgs.Merge (rc.Report.Printer)) {
+                               return;
                        }
 
 
@@ -5162,14 +5385,25 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (ResolveContext ec)
                {
+                       return CreateExpressionTree (ec, true);
+               }
+
+               public Expression CreateExpressionTree (ResolveContext ec, bool convertInstance)
+               {
+                       Arguments args;
                        Expression instance;
+
                        if (InstanceExpression == null) {
                                instance = new NullLiteral (loc);
-                       } else {
+                       } else if (convertInstance) {
                                instance = InstanceExpression.CreateExpressionTree (ec);
+                       } else {
+                               args = new Arguments (1);
+                               args.Add (new Argument (InstanceExpression));
+                               instance = CreateExpressionFactoryCall (ec, "Constant", args);
                        }
 
-                       Arguments args = Arguments.CreateForExpressionTree (ec, null,
+                       args = Arguments.CreateForExpressionTree (ec, null,
                                instance,
                                CreateTypeOfExpression ());
 
@@ -5183,6 +5417,8 @@ namespace Mono.CSharp {
 
                protected override Expression DoResolve (ResolveContext ec)
                {
+                       spec.MemberDefinition.SetIsUsed ();
+
                        return DoResolve (ec, null);
                }
 
@@ -5224,7 +5460,7 @@ namespace Mono.CSharp {
                        if (lvalue_instance && var != null && var.VariableInfo != null) {
                                var.VariableInfo.SetStructFieldAssigned (ec, Name);
                        }
-                       
+
                        if (fb != null) {
                                IFixedExpression fe = InstanceExpression as IFixedExpression;
                                if (!ec.HasSet (ResolveContext.Options.FixedInitializerScope) && (fe == null || !fe.IsFixed)) {
@@ -5402,8 +5638,6 @@ namespace Mono.CSharp {
                {
                        bool is_volatile = (spec.Modifiers & Modifiers.VOLATILE) != 0;
 
-                       spec.MemberDefinition.SetIsUsed ();
-                       
                        if (IsStatic){
                                if (is_volatile)
                                        ec.Emit (OpCodes.Volatile);
@@ -5510,7 +5744,7 @@ namespace Mono.CSharp {
                                base.EmitSideEffect (ec);
                }
 
-               public void AddressOf (EmitContext ec, AddressOp mode)
+               public virtual void AddressOf (EmitContext ec, AddressOp mode)
                {
                        if ((mode & AddressOp.Store) != 0)
                                spec.MemberDefinition.SetIsAssigned ();
@@ -5584,6 +5818,8 @@ namespace Mono.CSharp {
        //
        sealed class PropertyExpr : PropertyOrIndexerExpr<PropertySpec>
        {
+               Arguments arguments;
+
                public PropertyExpr (PropertySpec spec, Location l)
                        : base (l)
                {
@@ -5595,9 +5831,10 @@ namespace Mono.CSharp {
 
                protected override Arguments Arguments {
                        get {
-                               return null;
+                               return arguments;
                        }
                        set {
+                               arguments = value;
                        }
                }
 
@@ -5754,7 +5991,7 @@ namespace Mono.CSharp {
                                        }
                                }
                        } else {
-                               args = new Arguments (1);
+                               args = arguments == null ? new Arguments (1) : arguments;
 
                                if (leave_copy) {
                                        source.Emit (ec);
@@ -5804,6 +6041,22 @@ namespace Mono.CSharp {
                        }
 
                        DoBestMemberChecks (rc, best_candidate);
+
+                       // Handling of com-imported properties with any number of default property parameters
+                       if (best_candidate.HasGet && !best_candidate.Get.Parameters.IsEmpty) {
+                               var p = best_candidate.Get.Parameters;
+                               arguments = new Arguments (p.Count);
+                               for (int i = 0; i < p.Count; ++i) {
+                                       arguments.Add (new Argument (OverloadResolver.ResolveDefaultValueArgument (rc, p.Types [i], p.FixedParameters [i].DefaultValue, loc)));
+                               }
+                       } else if (best_candidate.HasSet && best_candidate.Set.Parameters.Count > 1) {
+                               var p = best_candidate.Set.Parameters;
+                               arguments = new Arguments (p.Count - 1);
+                               for (int i = 0; i < p.Count - 1; ++i) {
+                                       arguments.Add (new Argument (OverloadResolver.ResolveDefaultValueArgument (rc, p.Types [i], p.FixedParameters [i].DefaultValue, loc)));
+                               }
+                       }
+
                        return this;
                }
 
@@ -5883,11 +6136,6 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       // if the property/indexer returns a value type, and we try to set a field in it
-                       if (right_side == EmptyExpression.LValueMemberAccess || right_side == EmptyExpression.LValueMemberOutAccess) {
-                               Error_ValueAssignment (ec, right_side);
-                       }
-
                        if (eclass == ExprClass.Unresolved) {
                                var expr = OverloadResolve (ec, right_side);
                                if (expr == null)
@@ -5937,10 +6185,11 @@ namespace Mono.CSharp {
                        Emit (ec, false);
                }
 
-               protected override void EmitToFieldSource (EmitContext ec)
+               protected override FieldExpr EmitToFieldSource (EmitContext ec)
                {
                        has_await_arguments = true;
                        Emit (ec, false);
+                       return null;
                }
 
                public abstract SLE.Expression MakeAssignExpression (BuilderContext ctx, Expression source);
@@ -5990,7 +6239,7 @@ namespace Mono.CSharp {
                                                GetSignatureForError ());
                                } else {
                                        rc.Report.SymbolRelatedToPreviousError (best_candidate.Set);
-                                       ErrorIsInaccesible (rc, best_candidate.Set.GetSignatureForError (), loc);
+                                       ErrorIsInaccesible (rc, best_candidate.GetSignatureForError (), loc);
                                }
                        }
 
@@ -6244,9 +6493,10 @@ namespace Mono.CSharp {
 
                        //
                        // Don't capture temporary variables except when using
-                       // state machine redirection
+                       // state machine redirection and block yields
                        //
-                       if (ec.CurrentAnonymousMethod != null && ec.CurrentAnonymousMethod is StateMachineInitializer && ec.IsVariableCapturingRequired) {
+                       if (ec.CurrentAnonymousMethod != null && ec.CurrentAnonymousMethod.IsIterator &&
+                               ec.CurrentBlock.Explicit.HasYield && ec.IsVariableCapturingRequired) {
                                AnonymousMethodStorey storey = li.Block.Explicit.CreateAnonymousMethodStorey (ec);
                                storey.CaptureLocalVariable (ec, li);
                        }