Merge pull request #1991 from esdrubal/seq_test_fix
[mono.git] / mcs / mcs / ecore.cs
index c127621703527d227f18e23d204edf5b7fabb1d0..ce055dcbc3139d9fc071da68dd444b936968d027 100644 (file)
@@ -819,7 +819,8 @@ namespace Mono.CSharp {
                        ReadAccess = 1 << 3,
                        EmptyArguments = 1 << 4,
                        IgnoreArity = 1 << 5,
-                       IgnoreAmbiguity = 1 << 6
+                       IgnoreAmbiguity = 1 << 6,
+                       NameOfExcluded = 1 << 7,
                }
 
                //
@@ -832,107 +833,117 @@ namespace Mono.CSharp {
                        if (members == null)
                                return null;
 
-                       MemberSpec non_method = null;
-                       MemberSpec ambig_non_method = null;
+                       Expression expr;
                        do {
-                               for (int i = 0; i < members.Count; ++i) {
-                                       var member = members[i];
+                               expr = MemberLookupToExpression (rc, members, errorMode, queried_type, name, arity, restrictions, loc);
+                               if (expr != null)
+                                       return expr;
 
-                                       // HACK: for events because +=/-= can appear at same class only, should use OverrideToBase there
-                                       if ((member.Modifiers & Modifiers.OVERRIDE) != 0 && member.Kind != MemberKind.Event)
-                                               continue;
+                               if (members [0].DeclaringType.BaseType == null)
+                                       members = null;
+                               else
+                                       members = MemberCache.FindMembers (members [0].DeclaringType.BaseType, name, false);
+                       } while (members != null);
 
-                                       if ((member.Modifiers & Modifiers.BACKING_FIELD) != 0 || member.Kind == MemberKind.Operator)
-                                               continue;
+                       return expr;
+               }
 
-                                       if ((arity > 0 || (restrictions & MemberLookupRestrictions.ExactArity) != 0) && member.Arity != arity)
-                                               continue;
+               public static Expression MemberLookupToExpression (IMemberContext rc, IList<MemberSpec> members, bool errorMode, TypeSpec queried_type, string name, int arity, MemberLookupRestrictions restrictions, Location loc)
+               {
+                       MemberSpec non_method = null;
+                       MemberSpec ambig_non_method = null;
 
-                                       if (!errorMode) {
-                                               if (!member.IsAccessible (rc))
-                                                       continue;
+                       for (int i = 0; i < members.Count; ++i) {
+                               var member = members [i];
 
-                                               //
-                                               // With runtime binder we can have a situation where queried type is inaccessible
-                                               // because it came via dynamic object, the check about inconsisted accessibility
-                                               // had no effect as the type was unknown during compilation
-                                               //
-                                               // class A {
-                                               //              private class N { }
-                                               //
-                                               //              public dynamic Foo ()
-                                               //              {
-                                               //                      return new N ();
-                                               //              }
-                                               //      }
-                                               //
-                                               if (rc.Module.Compiler.IsRuntimeBinder && !member.DeclaringType.IsAccessible (rc))
-                                                       continue;
-                                       }
+                               // HACK: for events because +=/-= can appear at same class only, should use OverrideToBase there
+                               if ((member.Modifiers & Modifiers.OVERRIDE) != 0 && member.Kind != MemberKind.Event)
+                                       continue;
 
-                                       if ((restrictions & MemberLookupRestrictions.InvocableOnly) != 0) {
-                                               if (member is MethodSpec) {
-                                                       //
-                                                       // Interface members that are hidden by class members are removed from the set. This
-                                                       // step only has an effect if T is a type parameter and T has both an effective base 
-                                                       // class other than object and a non-empty effective interface set
-                                                       //
-                                                       var tps = queried_type as TypeParameterSpec;
-                                                       if (tps != null && tps.HasTypeConstraint)
-                                                               members = RemoveHiddenTypeParameterMethods (members);
+                               if ((member.Modifiers & Modifiers.BACKING_FIELD) != 0 || member.Kind == MemberKind.Operator)
+                                       continue;
 
-                                                       return new MethodGroupExpr (members, queried_type, loc);
-                                               }
+                               if ((arity > 0 || (restrictions & MemberLookupRestrictions.ExactArity) != 0) && member.Arity != arity)
+                                       continue;
 
-                                               if (!Invocation.IsMemberInvocable (member))
-                                                       continue;
-                                       }
+                               if (!errorMode) {
+                                       if (!member.IsAccessible (rc))
+                                               continue;
 
-                                       if (non_method == null || member is MethodSpec || non_method.IsNotCSharpCompatible) {
-                                               non_method = member;
-                                       } else if (!errorMode && !member.IsNotCSharpCompatible) {
-                                               //
-                                               // Interface members that are hidden by class members are removed from the set when T is a type parameter and
-                                               // T has both an effective base class other than object and a non-empty effective interface set.
+                                       //
+                                       // With runtime binder we can have a situation where queried type is inaccessible
+                                       // because it came via dynamic object, the check about inconsisted accessibility
+                                       // had no effect as the type was unknown during compilation
+                                       //
+                                       // class A {
+                                       //              private class N { }
+                                       //
+                                       //              public dynamic Foo ()
+                                       //              {
+                                       //                      return new N ();
+                                       //              }
+                                       //      }
+                                       //
+                                       if (rc.Module.Compiler.IsRuntimeBinder && !member.DeclaringType.IsAccessible (rc))
+                                               continue;
+                               }
+
+                               if ((restrictions & MemberLookupRestrictions.InvocableOnly) != 0) {
+                                       if (member is MethodSpec) {
                                                //
-                                               // The spec has more complex rules but we simply remove all members declared in an interface declaration.
+                                               // Interface members that are hidden by class members are removed from the set. This
+                                               // step only has an effect if T is a type parameter and T has both an effective base 
+                                               // class other than object and a non-empty effective interface set
                                                //
                                                var tps = queried_type as TypeParameterSpec;
-                                               if (tps != null && tps.HasTypeConstraint) {
-                                                       if (non_method.DeclaringType.IsClass && member.DeclaringType.IsInterface)
-                                                               continue;
+                                               if (tps != null && tps.HasTypeConstraint)
+                                                       members = RemoveHiddenTypeParameterMethods (members);
 
-                                                       if (non_method.DeclaringType.IsInterface && member.DeclaringType.IsInterface) {
-                                                               non_method = member;
-                                                               continue;
-                                                       }
-                                               }
-
-                                               ambig_non_method = member;
+                                               return new MethodGroupExpr (members, queried_type, loc);
                                        }
+
+                                       if (!Invocation.IsMemberInvocable (member))
+                                               continue;
                                }
 
-                               if (non_method != null) {
-                                       if (ambig_non_method != null && rc != null && (restrictions & MemberLookupRestrictions.IgnoreAmbiguity) == 0) {
-                                               var report = rc.Module.Compiler.Report;
-                                               report.SymbolRelatedToPreviousError (non_method);
-                                               report.SymbolRelatedToPreviousError (ambig_non_method);
-                                               report.Error (229, loc, "Ambiguity between `{0}' and `{1}'",
-                                                       non_method.GetSignatureForError (), ambig_non_method.GetSignatureForError ());
+                               if (non_method == null || member is MethodSpec || non_method.IsNotCSharpCompatible) {
+                                       non_method = member;
+                               } else if (!errorMode && !member.IsNotCSharpCompatible) {
+                                       //
+                                       // Interface members that are hidden by class members are removed from the set when T is a type parameter and
+                                       // T has both an effective base class other than object and a non-empty effective interface set.
+                                       //
+                                       // The spec has more complex rules but we simply remove all members declared in an interface declaration.
+                                       //
+                                       var tps = queried_type as TypeParameterSpec;
+                                       if (tps != null && tps.HasTypeConstraint) {
+                                               if (non_method.DeclaringType.IsClass && member.DeclaringType.IsInterface)
+                                                       continue;
+
+                                               if (non_method.DeclaringType.IsInterface && member.DeclaringType.IsInterface) {
+                                                       non_method = member;
+                                                       continue;
+                                               }
                                        }
 
-                                       if (non_method is MethodSpec)
-                                               return new MethodGroupExpr (members, queried_type, loc);
+                                       ambig_non_method = member;
+                               }
+                       }
 
-                                       return ExprClassFromMemberInfo (non_method, loc);
+                       if (non_method != null) {
+                               if (ambig_non_method != null && rc != null && (restrictions & MemberLookupRestrictions.IgnoreAmbiguity) == 0) {
+                                       var report = rc.Module.Compiler.Report;
+                                       report.SymbolRelatedToPreviousError (non_method);
+                                       report.SymbolRelatedToPreviousError (ambig_non_method);
+                                       report.Error (229, loc, "Ambiguity between `{0}' and `{1}'",
+                                               non_method.GetSignatureForError (), ambig_non_method.GetSignatureForError ());
                                }
 
-                               if (members[0].DeclaringType.BaseType == null)
-                                       members = null;
-                               else
-                                       members = MemberCache.FindMembers (members[0].DeclaringType.BaseType, name, false);
+                               if (non_method is MethodSpec)
+                                       return new MethodGroupExpr (members, queried_type, loc);
 
-                       } while (members != null);
+                               return ExprClassFromMemberInfo (non_method, loc);
+                       }
 
                        return null;
                }
@@ -972,6 +983,9 @@ namespace Mono.CSharp {
                                        if (!TypeSpecComparer.Override.IsEqual (candidate.Parameters, method.Parameters))
                                                continue;
 
+                                       if (!AParametersCollection.HasSameParameterDefaults (candidate.Parameters, method.Parameters))
+                                               continue;
+
                                        if (!copied) {
                                                copied = true;
                                                members = new List<MemberSpec> (members);
@@ -985,6 +999,11 @@ namespace Mono.CSharp {
                        return members;
                }
 
+               protected static void Error_NamedArgument (NamedArgument na, Report Report)
+               {
+                       Report.Error (1742, na.Location, "An element access expression cannot use named argument");
+               }
+
                protected virtual void Error_NegativeArrayIndex (ResolveContext ec, Location loc)
                {
                        throw new NotImplementedException ();
@@ -1009,6 +1028,11 @@ namespace Mono.CSharp {
                        rc.Report.Error (8072, loc, "An expression tree cannot contain a null propagating operator");
                }
 
+               protected void Error_NullPropagatingLValue (ResolveContext rc)
+               {
+                       rc.Report.Error (-1030, loc, "The left-hand side of an assignment cannot contain a null propagating operator");
+               }
+
                public virtual void FlowAnalysis (FlowAnalysisContext fc)
                {
                }
@@ -1158,7 +1182,7 @@ namespace Mono.CSharp {
                        if (source.type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
                                Arguments args = new Arguments (1);
                                args.Add (new Argument (source));
-                               return new DynamicConversion (btypes.Int, CSharpBinderFlags.ConvertArrayIndex, args, loc).Resolve (ec);
+                               return new DynamicConversion (btypes.Int, CSharpBinderFlags.ConvertArrayIndex, args, source.loc).Resolve (ec);
                        }
 
                        Expression converted;
@@ -1195,6 +1219,27 @@ namespace Mono.CSharp {
                        return new ArrayIndexCast (converted, btypes.Int).Resolve (ec);
                }
 
+               public Expression MakePointerAccess (ResolveContext rc, TypeSpec type, Arguments args)
+               {
+                       if (args.Count != 1){
+                               rc.Report.Error (196, loc, "A pointer must be indexed by only one value");
+                               return null;
+                       }
+
+                       var arg = args [0];
+                       if (arg is NamedArgument)
+                               Error_NamedArgument ((NamedArgument) arg, rc.Report);
+
+                       var index = arg.Expr.Resolve (rc);
+                       if (index == null)
+                               return null;
+
+                       index = ConvertExpressionToArrayIndex (rc, index, true);
+
+                       Expression p = new PointerArithmetic (Binary.Operator.Addition, this, index, type, loc);
+                       return new Indirection (p, loc);
+               }
+
                //
                // Derived classes implement this method by cloning the fields that
                // could become altered during the Resolve stage
@@ -1293,8 +1338,14 @@ namespace Mono.CSharp {
                                return null;
 
                        ExpressionStatement es = e as ExpressionStatement;
-                       if (es == null || e is AnonymousMethodBody)
+                       if (es == null || e is AnonymousMethodBody) {
+                               var reduced = e as IReducedExpressionStatement;
+                               if (reduced != null) {
+                                       return EmptyExpressionStatement.Instance;
+                               }
+
                                Error_InvalidExpressionStatement (ec);
+                       }
 
                        //
                        // This is quite expensive warning, try to limit the damage
@@ -1361,6 +1412,10 @@ namespace Mono.CSharp {
                }
        }
 
+       interface IReducedExpressionStatement
+       {
+       }
+
        /// <summary>
        ///   This kind of cast is used to encapsulate the child
        ///   whose type is child.Type into an expression that is
@@ -2168,7 +2223,7 @@ namespace Mono.CSharp {
        //
        public class ReducedExpression : Expression
        {
-               public sealed class ReducedConstantExpression : EmptyConstantCast
+               public class ReducedConstantExpression : EmptyConstantCast
                {
                        readonly Expression orig_expr;
 
@@ -2218,6 +2273,14 @@ namespace Mono.CSharp {
                        }
                }
 
+               sealed class ReducedConstantStatement : ReducedConstantExpression, IReducedExpressionStatement
+               {
+                       public ReducedConstantStatement (Constant expr, Expression origExpr)
+                               : base (expr, origExpr)
+                       {
+                       }
+               }
+
                sealed class ReducedExpressionStatement : ExpressionStatement
                {
                        readonly Expression orig_expr;
@@ -2299,12 +2362,15 @@ namespace Mono.CSharp {
                //
                // Creates fully resolved expression switcher
                //
-               public static Constant Create (Constant expr, Expression original_expr)
+               public static Constant Create (Constant expr, Expression originalExpr)
                {
                        if (expr.eclass == ExprClass.Unresolved)
                                throw new ArgumentException ("Unresolved expression");
 
-                       return new ReducedConstantExpression (expr, original_expr);
+                       if (originalExpr is ExpressionStatement)
+                               return new ReducedConstantStatement (expr, originalExpr);
+
+                       return new ReducedConstantExpression (expr, originalExpr);
                }
 
                public static ExpressionStatement Create (ExpressionStatement s, Expression orig)
@@ -2521,7 +2587,7 @@ namespace Mono.CSharp {
                }
 
                protected ATypeNameExpression (string name, int arity, Location l)
-                       : this (name, new UnboundTypeArguments (arity), l)
+                       : this (name, new UnboundTypeArguments (arity, l), l)
                {
                }
 
@@ -2563,11 +2629,6 @@ namespace Mono.CSharp {
                                (targs == null || targs.Equals (atne.targs));
                }
 
-               protected void Error_OpenGenericTypeIsNotAllowed (IMemberContext mc)
-               {
-                       mc.Module.Compiler.Report.Error (7003, Location, "Unbound generic name is not valid in this context");
-               }
-
                public override int GetHashCode ()
                {
                        return Name.GetHashCode ();
@@ -2703,8 +2764,7 @@ namespace Mono.CSharp {
                                                return ct;
                                        }
 
-                                       if (!allowUnboundTypeArguments)
-                                               Error_OpenGenericTypeIsNotAllowed (mc);
+                                       targs.Resolve (mc, allowUnboundTypeArguments);
 
                                        return new GenericOpenTypeExpr (fne.Type, loc);
                                }
@@ -2716,7 +2776,7 @@ namespace Mono.CSharp {
                                        return fne;
                        }
 
-                       if (Arity == 0 && Name == "dynamic" && mc.Module.Compiler.Settings.Version > LanguageVersion.V_3) {
+                       if (Arity == 0 && Name == "dynamic" && !(mc is NamespaceContainer) && mc.Module.Compiler.Settings.Version > LanguageVersion.V_3) {
                                if (!mc.Module.PredefinedAttributes.Dynamic.IsDefined) {
                                        mc.Module.Compiler.Report.Error (1980, Location,
                                                "Dynamic keyword requires `{0}' to be defined. Are you missing System.Core.dll assembly reference?",
@@ -2739,6 +2799,11 @@ namespace Mono.CSharp {
                        return mc.LookupNamespaceOrType (Name, Arity, LookupMode.Probing, loc) != null;
                }
 
+               public bool IsPossibleType (IMemberContext mc)
+               {
+                       return mc.LookupNamespaceOrType (Name, Arity, LookupMode.Probing, loc) is TypeExpr;
+               }
+
                public override Expression LookupNameExpression (ResolveContext rc, MemberLookupRestrictions restrictions)
                {
                        int lookup_arity = Arity;
@@ -2807,12 +2872,6 @@ namespace Mono.CSharp {
                                                        ErrorIsInaccesible (rc, me.GetSignatureForError (), loc);
                                                }
                                        } else {
-                                               // LAMESPEC: again, ignores InvocableOnly
-                                               if (variable != null) {
-                                                       rc.Report.SymbolRelatedToPreviousError (variable.Location, Name);
-                                                       rc.Report.Error (135, loc, "`{0}' conflicts with a declaration in a child block", Name);
-                                               }
-
                                                //
                                                // MemberLookup does not check accessors availability, this is actually needed for properties only
                                                //
@@ -2826,8 +2885,16 @@ namespace Mono.CSharp {
 
                                                                pe.Getter = pe.PropertyInfo.Get;
                                                        } else {
-                                                               if (!pe.PropertyInfo.HasSet || !pe.PropertyInfo.Set.IsAccessible (rc))
+                                                               if (rc.HasSet (ResolveContext.Options.ConstructorScope) && pe.IsAutoPropertyAccess &&
+                                                                       pe.PropertyInfo.DeclaringType == rc.CurrentType && pe.IsStatic == rc.IsStatic) {
+                                                                       var p = (Property) pe.PropertyInfo.MemberDefinition;
+                                                                       return new FieldExpr (p.BackingField, loc);
+                                                               }
+
+                                                               if (!pe.PropertyInfo.HasSet || !pe.PropertyInfo.Set.IsAccessible (rc)) {
+                                                                       variable_found = true;
                                                                        break;
+                                                               }
 
                                                                pe.Setter = pe.PropertyInfo.Set;
                                                        }
@@ -2839,7 +2906,7 @@ namespace Mono.CSharp {
                                        me = me.ResolveMemberAccess (rc, null, null);
 
                                        if (Arity > 0) {
-                                               targs.Resolve (rc);
+                                               targs.Resolve (rc, false);
                                                me.SetTypeArguments (rc, targs);
                                        }
 
@@ -2851,25 +2918,23 @@ namespace Mono.CSharp {
                                //
                                if ((restrictions & MemberLookupRestrictions.InvocableOnly) == 0 && !variable_found) {
                                        if (IsPossibleTypeOrNamespace (rc)) {
-                                               if (variable != null) {
-                                                       rc.Report.SymbolRelatedToPreviousError (variable.Location, Name);
-                                                       rc.Report.Error (135, loc, "`{0}' conflicts with a declaration in a child block", Name);
-                                               }
-
                                                return ResolveAsTypeOrNamespace (rc, false);
                                        }
                                }
 
-                               var mg = NamespaceContainer.LookupStaticUsings (rc, Name, Arity, loc);
-                               if (mg != null) {
+                               var expr = NamespaceContainer.LookupStaticUsings (rc, Name, Arity, loc);
+                               if (expr != null) {
                                        if (Arity > 0) {
-                                               targs.Resolve (rc);
-                                               mg.SetTypeArguments (rc, targs);
+                                               targs.Resolve (rc, false);
+
+                                               var me = expr as MemberExpr;
+                                               if (me != null)
+                                                       me.SetTypeArguments (rc, targs);
                                        }
-                                       return mg;
+                                       return expr;
                                }
 
-                               if (Name == "nameof")
+                               if ((restrictions & MemberLookupRestrictions.NameOfExcluded) == 0 && Name == "nameof")
                                        return new NameOf (this);
 
                                if (errorMode) {
@@ -3034,11 +3099,10 @@ namespace Mono.CSharp {
                        // Obsolete checks cannot be done when resolving base context as they
                        // require type dependencies to be set but we are in process of resolving them
                        //
-                       if (!(mc is TypeDefinition.BaseContext) && !(mc is UsingAliasNamespace.AliasContext)) {
-                               ObsoleteAttribute obsolete_attr = type.GetAttributeObsolete ();
-                               if (obsolete_attr != null && !mc.IsObsolete) {
-                                       AttributeTester.Report_ObsoleteMessage (obsolete_attr, te.GetSignatureForError (), Location, mc.Module.Compiler.Report);
-                               }
+                       if (mc is ResolveContext) {
+                               var oa = type.GetAttributeObsolete ();
+                               if (oa != null && !mc.IsObsolete)
+                                       AttributeTester.Report_ObsoleteMessage (oa, type.GetSignatureForError (), fne.Location, mc.Module.Compiler.Report);
                        }
 
                        return type;
@@ -3130,7 +3194,7 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               public void Error_NamespaceDoesNotExist (IMemberContext ctx, string name, int arity)
+               public void Error_NamespaceDoesNotExist (IMemberContext ctx, string name, int arity, Location loc)
                {
                        var retval = Namespace.LookupType (ctx, name, arity, LookupMode.IgnoreAccessibility, loc);
                        if (retval != null) {
@@ -3436,11 +3500,7 @@ namespace Mono.CSharp {
                                ImportedTypeDefinition.Error_MissingDependency (rc, dep, loc);
                        }
 
-                       if (!rc.IsObsolete) {
-                               ObsoleteAttribute oa = member.GetAttributeObsolete ();
-                               if (oa != null)
-                                       AttributeTester.Report_ObsoleteMessage (oa, member.GetSignatureForError (), loc, rc.Report);
-                       }
+                       member.CheckObsoleteness (rc, loc);
 
                        if (!(member is FieldSpec))
                                member.MemberDefinition.SetIsUsed ();
@@ -3539,10 +3599,7 @@ namespace Mono.CSharp {
                                        if (InstanceExpression is TypeExpr) {
                                                var t = InstanceExpression.Type;
                                                do {
-                                                       ObsoleteAttribute oa = t.GetAttributeObsolete ();
-                                                       if (oa != null && !rc.IsObsolete) {
-                                                               AttributeTester.Report_ObsoleteMessage (oa, t.GetSignatureForError (), loc, rc.Report);
-                                                       }
+                                                       t.CheckObsoleteness (rc, loc);
 
                                                        t = t.DeclaringType;
                                                } while (t != null);
@@ -3726,7 +3783,7 @@ namespace Mono.CSharp {
 
                        int arity = type_arguments == null ? 0 : type_arguments.Count;
 
-                       candidates = candidates.Container.LookupExtensionMethod (candidates.Context, ExtensionExpression.Type, Name, arity, candidates.LookupIndex);
+                       candidates = candidates.Container.LookupExtensionMethod (candidates.Context, Name, arity, candidates.LookupIndex);
                        if (candidates == null)
                                return null;
 
@@ -3748,6 +3805,10 @@ namespace Mono.CSharp {
 
                public bool ResolveNameOf (ResolveContext rc, MemberAccess ma)
                {
+                       rc.Report.Error (8093, ma.Location, "An argument to nameof operator cannot be extension method group");
+
+                       // Not included in C#6
+                       /*
                        ExtensionExpression = ExtensionExpression.Resolve (rc);
                        if (ExtensionExpression == null)
                                return false;
@@ -3761,6 +3822,7 @@ namespace Mono.CSharp {
                        // TODO: Scan full hierarchy
 
                        ma.Error_TypeDoesNotContainDefinition (rc, argType, ma.Name);
+                       */
                        return false;
                }
 
@@ -3816,14 +3878,15 @@ namespace Mono.CSharp {
                bool OverloadResolver.IErrorHandler.ArgumentMismatch (ResolveContext rc, MemberSpec best, Argument arg, int index)
                {
                        rc.Report.SymbolRelatedToPreviousError (best);
-                       rc.Report.Error (1928, loc,
-                               "Type `{0}' does not contain a member `{1}' and the best extension method overload `{2}' has some invalid arguments",
-                               queried_type.GetSignatureForError (), Name, best.GetSignatureForError ());
 
                        if (index == 0) {
                                rc.Report.Error (1929, loc,
-                                       "Extension method instance type `{0}' cannot be converted to `{1}'",
-                                       arg.Type.GetSignatureForError (), ((MethodSpec)best).Parameters.ExtensionMethodType.GetSignatureForError ());
+                                       "Type `{0}' does not contain a member `{1}' and the best extension method overload `{2}' requires an instance of type `{3}'",
+                                       queried_type.GetSignatureForError (), Name, best.GetSignatureForError (), ((MethodSpec)best).Parameters.ExtensionMethodType.GetSignatureForError ());
+                       } else {
+                               rc.Report.Error (1928, loc,
+                                       "Type `{0}' does not contain a member `{1}' and the best extension method overload `{2}' has some invalid arguments",
+                                       queried_type.GetSignatureForError (), Name, best.GetSignatureForError ());
                        }
 
                        return true;
@@ -4031,6 +4094,16 @@ namespace Mono.CSharp {
                                Name, target.GetSignatureForError ());
                }
 
+               public bool HasAccessibleCandidate (ResolveContext rc)
+               {
+                       foreach (var candidate in Candidates) {
+                               if (candidate.IsAccessible (rc))
+                                       return true;
+                       }
+
+                       return false;
+               }
+
                public static bool IsExtensionMethodArgument (Expression expr)
                {
                        //
@@ -4180,7 +4253,7 @@ namespace Mono.CSharp {
                                return null;
 
                        int arity = type_arguments == null ? 0 : type_arguments.Count;
-                       var methods = rc.LookupExtensionMethod (InstanceExpression.Type, Methods[0].Name, arity);
+                       var methods = rc.LookupExtensionMethod (Methods[0].Name, arity);
                        if (methods == null)
                                return null;
 
@@ -4675,6 +4748,9 @@ namespace Mono.CSharp {
                                var cand_param = candidate_pd.FixedParameters [j];
                                var best_param = best_pd.FixedParameters [j];
 
+                               if (cand_param.HasDefaultValue != best_param.HasDefaultValue)
+                                       return cand_param.HasDefaultValue;
+
                                if (candidate_pd.Count == best_pd.Count) {
                                        //
                                        // LAMESPEC:
@@ -4682,8 +4758,6 @@ namespace Mono.CSharp {
                                        // void Foo (int i = 0) is better than void Foo (params int[]) for Foo ()
                                        // void Foo (string[] s, string value = null) is better than Foo (string s, params string[]) for Foo (null) or Foo ()
                                        //
-                                       if (cand_param.HasDefaultValue != best_param.HasDefaultValue)
-                                               return cand_param.HasDefaultValue;
 
                                        if (cand_param.HasDefaultValue) {
                                                ++j;
@@ -4697,8 +4771,7 @@ namespace Mono.CSharp {
                                        // void Foo (string s, int i = 0) <-> Foo (string s, byte i = 0)
                                        // void Foo (string s, params int[]) <-> Foo (string s, params byte[])
                                        //
-                                       if (cand_param.HasDefaultValue && best_param.HasDefaultValue)
-                                               return false;
+                                       return false;
                                }
 
                                break;
@@ -5155,7 +5228,7 @@ namespace Mono.CSharp {
                        //
                        // 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) {
+                       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) {
@@ -5294,6 +5367,7 @@ namespace Mono.CSharp {
                        Arguments candidate_args = args;
                        bool error_mode = false;
                        MemberSpec invocable_member = null;
+                       int applicable_candidates = 0;
 
                        while (true) {
                                best_candidate = null;
@@ -5366,6 +5440,7 @@ namespace Mono.CSharp {
                                                        if (candidate_rate < 0)
                                                                return null;
 
+                                                       applicable_candidates = 1;
                                                        if ((restrictions & Restrictions.GetEnumeratorLookup) != 0 && candidate_args.Count != 0) {
                                                                // Only parameterless methods are considered
                                                        } else {
@@ -5388,6 +5463,7 @@ namespace Mono.CSharp {
                                                                        continue;
                                                        }
 
+                                                       ++applicable_candidates;
                                                        bool is_better;
                                                        if (best_candidate.DeclaringType.IsInterface && member.DeclaringType.ImplementsInterface (best_candidate.DeclaringType, false)) {
                                                                //
@@ -5493,7 +5569,7 @@ namespace Mono.CSharp {
                                //
                                // Check type constraints only when explicit type arguments are used
                                //
-                               if (best_candidate.IsGeneric && type_arguments != null) {
+                               if (applicable_candidates == 1 && best_candidate.IsGeneric && type_arguments != null) {
                                        MethodSpec bc = best_candidate as MethodSpec;
                                        if (bc != null && TypeParameterSpec.HasAnyTypeParameterConstrained (bc.GenericDefinition)) {
                                                ConstraintChecker cc = new ConstraintChecker (rc);
@@ -5560,9 +5636,7 @@ namespace Mono.CSharp {
                                //
                                // 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);
+                               best_candidate.CheckObsoleteness (rc, loc);
 
                                best_candidate.MemberDefinition.SetIsUsed ();
                        }
@@ -5836,7 +5910,14 @@ namespace Mono.CSharp {
                                        continue;
 
                                if ((restrictions & Restrictions.CovariantDelegate) != 0 && !Delegate.IsTypeCovariant (ec, a.Expr.Type, pt)) {
-                                       custom_errors.NoArgumentMatch (ec, member);
+                                       if (a.IsExtensionType) {
+                                               // TODO: Should report better message type, something similar to CS1928/1929 instead of
+                                               // CS1061 but that still better than confusing CS0123
+                                               var ma = new MemberAccess (a.Expr, member.Name, loc);
+                                               ma.Error_TypeDoesNotContainDefinition (ec, a.Expr.Type, ma.Name);
+                                       } else {
+                                               custom_errors.NoArgumentMatch (ec, member);
+                                       }
                                        return false;
                                }
 
@@ -6315,8 +6396,8 @@ namespace Mono.CSharp {
 
                public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
                {
-                       if (ConditionalAccess)
-                               throw new NotSupportedException ("null propagating operator assignment");
+                       if (HasConditionalAccess ())
+                               Error_NullPropagatingLValue (ec);
 
                        if (spec is FixedFieldSpec) {
                                // It could be much better error message but we want to be error compatible
@@ -6377,8 +6458,13 @@ namespace Mono.CSharp {
                                        return;
                                }
 
-                               if (TypeSpec.IsValueType (InstanceExpression.Type) && InstanceExpression is VariableReference)
+                               if (TypeSpec.IsValueType (InstanceExpression.Type)) {
+                                       var le = SkipLeftValueTypeAccess (InstanceExpression);
+                                       if (le != null)
+                                               le.FlowAnalysis (fc);
+
                                        return;
+                               }
                        }
 
                        base.FlowAnalysis (fc);
@@ -6387,6 +6473,24 @@ namespace Mono.CSharp {
                                fc.ConditionalAccessEnd ();
                }
 
+               static Expression SkipLeftValueTypeAccess (Expression expr)
+               {
+                       if (!TypeSpec.IsValueType (expr.Type))
+                               return expr;
+
+                       if (expr is VariableReference)
+                               return null;
+
+                       var fe = expr as FieldExpr;
+                       if (fe == null)
+                               return expr;
+
+                       if (fe.InstanceExpression == null)
+                               return expr;
+
+                       return SkipLeftValueTypeAccess (fe.InstanceExpression);
+               }
+
                public override int GetHashCode ()
                {
                        return spec.GetHashCode ();
@@ -6943,6 +7047,14 @@ namespace Mono.CSharp {
                        if (!rc.HasSet (ResolveContext.Options.ConstructorScope))
                                return false;
 
+                       if (prop.Parent.PartialContainer != rc.CurrentMemberDefinition.Parent.PartialContainer) {
+                               var ps = MemberCache.FindMember (rc.CurrentType, MemberFilter.Property (prop.ShortName, prop.MemberType), BindingRestriction.DeclaredOnly) as PropertySpec;
+                               if (ps == null)
+                                       return false;
+
+                               prop = (Property) ps.MemberDefinition;
+                       }
+
                        var spec = prop.BackingField;
                        if (spec == null)
                                return false;
@@ -7051,8 +7163,8 @@ namespace Mono.CSharp {
 
                public override Expression DoResolveLValue (ResolveContext rc, Expression right_side)
                {
-                       if (ConditionalAccess)
-                               throw new NotSupportedException ("null propagating operator assignment");
+                       if (HasConditionalAccess ())
+                               Error_NullPropagatingLValue (rc);
 
                        if (right_side == EmptyExpression.OutAccess) {
                                // TODO: best_candidate can be null at this point
@@ -7259,11 +7371,7 @@ namespace Mono.CSharp {
 
                                        spec.MemberDefinition.SetIsUsed ();
 
-                                       if (!ec.IsObsolete) {
-                                               ObsoleteAttribute oa = spec.GetAttributeObsolete ();
-                                               if (oa != null)
-                                                       AttributeTester.Report_ObsoleteMessage (oa, spec.GetSignatureForError (), loc, ec.Report);
-                                       }
+                                       spec.CheckObsoleteness (ec, loc);
 
                                        if ((spec.Modifiers & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
                                                Error_AssignmentEventOnly (ec);
@@ -7297,6 +7405,9 @@ namespace Mono.CSharp {
                                return null;
                        }
 
+                       if (HasConditionalAccess ())
+                               Error_NullPropagatingLValue (ec);
+
                        op = CandidateToBaseOverride (ec, op);
                        return this;
                }
@@ -7440,9 +7551,9 @@ namespace Mono.CSharp {
                    }
                }
 
-               public static TemporaryVariableReference Create (TypeSpec type, Block block, Location loc)
+               public static TemporaryVariableReference Create (TypeSpec type, Block block, Location loc, bool writeToSymbolFile = false)
                {
-                       var li = LocalVariable.CreateCompilerGenerated (type, block, loc);
+                       var li = LocalVariable.CreateCompilerGenerated (type, block, loc, writeToSymbolFile);
                        return new TemporaryVariableReference (li, loc);
                }
 
@@ -7535,6 +7646,7 @@ namespace Mono.CSharp {
                                ec.Report.Error (815, loc,
                                        "An implicitly typed local variable declaration cannot be initialized with `{0}'",
                                        type.GetSignatureForError ());
+                               type = InternalType.ErrorType;
                                return false;
                        }