Merge pull request #495 from nicolas-raoul/fix-for-issue2907-with-no-formatting-changes
[mono.git] / mcs / mcs / ecore.cs
index 2ae9bcd2f9a471397b4dda4c82234bda19baedd5..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.
 //
 //
 
@@ -323,14 +323,7 @@ namespace Mono.CSharp {
                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");
                        }
@@ -367,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 ();
@@ -1031,15 +1045,30 @@ namespace Mono.CSharp {
                        if (es == null)
                                Error_InvalidExpressionStatement (ec);
 
-                       if (ec.CurrentAnonymousMethod is AsyncInitializer && !(e is Assign) &&
-                               (e.Type.IsGenericTask || e.Type == ec.Module.PredefinedTypes.Task.TypeSpec)) {
-                               ec.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");
+                       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
@@ -2277,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;
                        }
@@ -2290,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)
@@ -2401,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 ()
@@ -2763,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;
@@ -2908,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) {
@@ -2969,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;
                                }
 
@@ -2993,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;
@@ -3168,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;
@@ -3439,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);
                }
@@ -3721,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;
 
                                //
@@ -3738,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;
+                                       }
                                }
 
                                //
@@ -3957,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;
                        }
 
                        //
@@ -4031,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,
@@ -4046,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)
                {
@@ -4082,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);
@@ -4167,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)
@@ -4212,17 +4338,21 @@ namespace Mono.CSharp {
                                        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;
                                }
@@ -4271,18 +4401,8 @@ namespace Mono.CSharp {
                                        // if the type matches
                                        //
                                        Expression e = fp.DefaultValue;
-                                       if (!(e is Constant) || e.Type.IsGenericOrParentIsGeneric || e.Type.IsGenericParameter) {
-                                               //
-                                               // LAMESPEC: No idea what the exact rules are for System.Reflection.Missing.Value instead of null
-                                               //
-                                               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);
-                                               }
-
-                                               e = e.Resolve (ec);
+                                       if (e != null) {
+                                               e = ResolveDefaultValueArgument (ec, ptypes[i], e, loc);
                                        }
 
                                        if ((fp.ModFlags & Parameter.Modifier.CallerMask) != 0) {
@@ -4375,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
@@ -4449,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);
 
@@ -4559,6 +4712,11 @@ namespace Mono.CSharp {
                                                // 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;
@@ -4680,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;
                        }
@@ -4733,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;
                }
@@ -4767,7 +4936,7 @@ namespace Mono.CSharp {
                        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;
                                }
@@ -4801,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);
                        }
                }
@@ -5211,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 ());
 
@@ -5232,6 +5417,8 @@ namespace Mono.CSharp {
 
                protected override Expression DoResolve (ResolveContext ec)
                {
+                       spec.MemberDefinition.SetIsUsed ();
+
                        return DoResolve (ec, null);
                }
 
@@ -5273,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)) {
@@ -5451,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);
@@ -5633,6 +5818,8 @@ namespace Mono.CSharp {
        //
        sealed class PropertyExpr : PropertyOrIndexerExpr<PropertySpec>
        {
+               Arguments arguments;
+
                public PropertyExpr (PropertySpec spec, Location l)
                        : base (l)
                {
@@ -5644,9 +5831,10 @@ namespace Mono.CSharp {
 
                protected override Arguments Arguments {
                        get {
-                               return null;
+                               return arguments;
                        }
                        set {
+                               arguments = value;
                        }
                }
 
@@ -5803,7 +5991,7 @@ namespace Mono.CSharp {
                                        }
                                }
                        } else {
-                               args = new Arguments (1);
+                               args = arguments == null ? new Arguments (1) : arguments;
 
                                if (leave_copy) {
                                        source.Emit (ec);
@@ -5853,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;
                }
 
@@ -5932,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)
@@ -6040,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);
                                }
                        }