Don't emit reaonly. prefix for reference loads
[mono.git] / mcs / mcs / ecore.cs
index bc23213ab487c5a2393ab9b0329ddbbce4ffe7ce..4316031cbaf9573d09dd945ca01ddf092f02e255 100644 (file)
@@ -183,66 +183,16 @@ namespace Mono.CSharp {
                // This is used if the expression should be resolved as a type or namespace name.
                // the default implementation fails.   
                //
-               public virtual FullNamedExpression ResolveAsTypeStep (IMemberContext rc,  bool silent)
+               public virtual TypeSpec ResolveAsType (IMemberContext mc)
                {
-                       if (!silent) {
-                               ResolveContext ec = new ResolveContext (rc);
-                               Expression e = Resolve (ec);
-                               if (e != null)
-                                       e.Error_UnexpectedKind (ec, ResolveFlags.Type, loc);
-                       }
+                       ResolveContext ec = new ResolveContext (mc);
+                       Expression e = Resolve (ec);
+                       if (e != null)
+                               e.Error_UnexpectedKind (ec, ResolveFlags.Type, loc);
 
                        return null;
                }
 
-               //
-               // This is used to resolve the expression as a type, a null
-               // value will be returned if the expression is not a type
-               // reference
-               //
-               public virtual TypeExpr ResolveAsTypeTerminal (IMemberContext ec , bool silent)
-               {
-                       // FIXME: THIS IS TOO SLOW and it should not be needed either
-                       int errors = ec.Module.Compiler.Report.Errors;
-
-                       FullNamedExpression fne = ResolveAsTypeStep (ec, silent);
-
-                       if (fne == null)
-                               return null;
-                               
-                       TypeExpr te = fne as TypeExpr;                          
-                       if (te == null) {
-                               if (!silent && errors == ec.Module.Compiler.Report.Errors)
-                                       fne.Error_UnexpectedKind (ec.Module.Compiler.Report, null, "type", loc);
-                               return null;
-                       }
-
-                       if (!te.type.IsAccessible (ec)) {
-                               ec.Module.Compiler.Report.SymbolRelatedToPreviousError (te.Type);
-                               ErrorIsInaccesible (ec, te.Type.GetSignatureForError (), loc);
-                       }
-
-                       te.loc = loc;
-
-                       var dep = te.type.GetMissingDependencies ();
-                       if (dep != null) {
-                               ImportedTypeDefinition.Error_MissingDependency (ec, dep, loc);
-                       }
-
-                       //
-                       // Obsolete checks cannot be done when resolving base context as they
-                       // require type dependecies to be set but we are just resolving them
-                       //
-                       if (!silent && !(ec is TypeContainer.BaseContext)) {
-                               ObsoleteAttribute obsolete_attr = te.Type.GetAttributeObsolete ();
-                               if (obsolete_attr != null && !ec.IsObsolete) {
-                                       AttributeTester.Report_ObsoleteMessage (obsolete_attr, te.GetSignatureForError (), Location, ec.Module.Compiler.Report);
-                               }
-                       }
-
-                       return te;
-               }
-       
                public static void ErrorIsInaccesible (IMemberContext rc, string member, Location loc)
                {
                        rc.Module.Compiler.Report.Error (122, loc, "`{0}' is inaccessible due to its protection level", member);
@@ -313,10 +263,11 @@ namespace Mono.CSharp {
                        }
                }
 
-               public void Error_TypeArgumentsCannotBeUsed (Report report, Location loc, MemberSpec member, int arity)
+               public void Error_TypeArgumentsCannotBeUsed (IMemberContext context, MemberSpec member, int arity, Location loc)
                {
                        // Better message for possible generic expressions
                        if (member != null && (member.Kind & MemberKind.GenericMask) != 0) {
+                               var report = context.Module.Compiler.Report;
                                report.SymbolRelatedToPreviousError (member);
                                if (member is TypeSpec)
                                        member = ((TypeSpec) member).GetDefinition ();
@@ -332,13 +283,13 @@ namespace Mono.CSharp {
                                                name, member.GetSignatureForError ());
                                }
                        } else {
-                               Error_TypeArgumentsCannotBeUsed (report, ExprClassName, GetSignatureForError (), loc);
+                               Error_TypeArgumentsCannotBeUsed (context, ExprClassName, GetSignatureForError (), loc);
                        }
                }
 
-               public void Error_TypeArgumentsCannotBeUsed (Report report, string exprType, string name, Location loc)
+               public void Error_TypeArgumentsCannotBeUsed (IMemberContext context, string exprType, string name, Location loc)
                {
-                       report.Error (307, loc, "The {0} `{1}' cannot be used with type arguments",
+                       context.Module.Compiler.Report.Error (307, loc, "The {0} `{1}' cannot be used with type arguments",
                                exprType, name);
                }
 
@@ -561,7 +512,15 @@ namespace Mono.CSharp {
                        }
 
                        var r = new OverloadResolver (ctors, OverloadResolver.Restrictions.NoBaseMembers, loc);
-                       return r.ResolveMember<MethodSpec> (rc, ref args);
+                       var ctor = r.ResolveMember<MethodSpec> (rc, ref args);
+                       if (ctor == null)
+                               return null;
+
+                       if ((ctor.Modifiers & Modifiers.PROTECTED) != 0 && !rc.HasSet (ResolveContext.Options.BaseInitializer)) {
+                               MemberExpr.CheckProtectedMemberAccess (rc, ctor, ctor.DeclaringType, loc);
+                       }
+
+                       return ctor;
                }
 
                [Flags]
@@ -626,9 +585,9 @@ namespace Mono.CSharp {
                                                        continue;
                                        }
 
-                                       if (non_method == null || member is MethodSpec) {
+                                       if (non_method == null || member is MethodSpec || non_method.IsNotCSharpCompatible) {
                                                non_method = member;
-                                       } else if (!errorMode) {
+                                       } else if (!errorMode && !member.IsNotCSharpCompatible) {
                                                ambig_non_method = member;
                                        }
                                }
@@ -998,7 +957,7 @@ namespace Mono.CSharp {
                {
                        Arguments args = new Arguments (2);
                        args.Add (new Argument (child.CreateExpressionTree (ec)));
-                       args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
+                       args.Add (new Argument (new TypeOf (type, loc)));
 
                        if (type.IsPointer || child.Type.IsPointer)
                                Error_PointerInsideExpressionTree (ec);
@@ -1149,7 +1108,7 @@ namespace Mono.CSharp {
                {
                        Arguments args = Arguments.CreateForExpressionTree (ec, null,
                                child.CreateExpressionTree (ec),
-                               new TypeOf (new TypeExpression (type, loc), loc));
+                               new TypeOf (type, loc));
 
                        if (type.IsPointer)
                                Error_PointerInsideExpressionTree (ec);
@@ -1906,18 +1865,18 @@ namespace Mono.CSharp {
                        this.loc = expr.Location;
                }
 
-               public override Expression CreateExpressionTree (ResolveContext ec)
+               public override Expression CreateExpressionTree (ResolveContext rc)
                {
-                       return expr.CreateExpressionTree (ec);
+                       return expr.CreateExpressionTree (rc);
                }
 
                public Expression Child {
                        get { return expr; }
                }
 
-               protected override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext rc)
                {
-                       expr = expr.Resolve (ec);
+                       expr = expr.Resolve (rc);
                        if (expr != null) {
                                type = expr.Type;
                                eclass = expr.eclass;
@@ -1948,6 +1907,12 @@ namespace Mono.CSharp {
                        this.expr = expr;
                }
 
+               public Expression Expr {
+                       get {
+                               return expr;
+                       }
+               }
+
                protected override void CloneTo (CloneContext clonectx, Expression t)
                {
                        if (expr == null)
@@ -1967,9 +1932,6 @@ namespace Mono.CSharp {
                        throw new InternalErrorException ("Missing Resolve call");
                }
 
-               public Expression Expr {
-                       get { return expr; }
-               }
        }
 
        //
@@ -2098,77 +2060,57 @@ namespace Mono.CSharp {
                        return new SimpleName (Name, targs, loc);
                }
 
-               protected virtual void Error_TypeOrNamespaceNotFound (IMemberContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
+               {
+                       return SimpleNameResolve (ec, null, false);
+               }
+
+               public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
+               {
+                       return SimpleNameResolve (ec, right_side, false);
+               }
+
+               protected virtual void Error_TypeOrNamespaceNotFound (IMemberContext ctx)
                {
-                       if (ec.CurrentType != null) {
-                               if (ec.CurrentMemberDefinition != null) {
-                                       MemberCore mc = ec.CurrentMemberDefinition.Parent.GetDefinition (Name);
+                       if (ctx.CurrentType != null) {
+                               if (ctx.CurrentMemberDefinition != null) {
+                                       MemberCore mc = ctx.CurrentMemberDefinition.Parent.GetDefinition (Name);
                                        if (mc != null) {
-                                               Error_UnexpectedKind (ec.Module.Compiler.Report, mc, "type", GetMemberType (mc), loc);
+                                               Error_UnexpectedKind (ctx.Module.Compiler.Report, mc, "type", GetMemberType (mc), loc);
                                                return;
                                        }
                                }
-
-                               /*
-                                                               // TODO MemberCache: Implement
-                                                               string ns = ec.CurrentType.Namespace;
-                                                               string fullname = (ns.Length > 0) ? ns + "." + Name : Name;
-                                                               foreach (Assembly a in GlobalRootNamespace.Instance.Assemblies) {
-                                                                       var type = a.GetType (fullname);
-                                                                       if (type != null) {
-                                                                               ec.Compiler.Report.SymbolRelatedToPreviousError (type);
-                                                                               Expression.ErrorIsInaccesible (loc, TypeManager.CSharpName (type), ec.Compiler.Report);
-                                                                               return;
-                                                                       }
-                                                               }
-
-                                                               if (ec.CurrentTypeDefinition != null) {
-                                                                       TypeSpec t = ec.CurrentTypeDefinition.LookupAnyGeneric (Name);
-                                                                       if (t != null) {
-                                                                               Namespace.Error_InvalidNumberOfTypeArguments (ec.Compiler.Report, t, loc);
-                                                                               return;
-                                                                       }
-                                                               }
-                               */
                        }
 
-                       FullNamedExpression retval = ec.LookupNamespaceOrType (Name, -System.Math.Max (1, Arity), loc, true);
+                       // MSAF
+                       var retval = ctx.LookupNamespaceOrType (Name, Arity, LookupMode.IgnoreAccessibility, loc);
                        if (retval != null) {
-                               Error_TypeArgumentsCannotBeUsed (ec.Module.Compiler.Report, loc, retval.Type, Arity);
-/*
-                               var te = retval as TypeExpr;
-                               if (HasTypeArguments && te != null && !te.Type.IsGeneric)
-                                       retval.Error_TypeArgumentsCannotBeUsed (ec.Compiler.Report, loc);
-                               else
-                                       Namespace.Error_InvalidNumberOfTypeArguments (ec.Compiler.Report, retval.Type, loc);
-*/
+                               ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (retval.Type);
+                               ErrorIsInaccesible (ctx, retval.GetSignatureForError (), loc);
                                return;
                        }
 
-                       NamespaceEntry.Error_NamespaceNotFound (loc, Name, ec.Module.Compiler.Report);
-               }
-
-               protected override Expression DoResolve (ResolveContext ec)
-               {
-                       return SimpleNameResolve (ec, null, false);
-               }
+                       retval = ctx.LookupNamespaceOrType (Name, -System.Math.Max (1, Arity), LookupMode.Probing, loc);
+                       if (retval != null) {
+                               Error_TypeArgumentsCannotBeUsed (ctx, retval.Type, Arity, loc);
+                               return;
+                       }
 
-               public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
-               {
-                       return SimpleNameResolve (ec, right_side, false);
+                       NamespaceContainer.Error_NamespaceNotFound (loc, Name, ctx.Module.Compiler.Report);
                }
 
-               public override FullNamedExpression ResolveAsTypeStep (IMemberContext ec, bool silent)
+               public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext ec)
                {
-                       int errors = ec.Module.Compiler.Report.Errors;
-                       FullNamedExpression fne = ec.LookupNamespaceOrType (Name, Arity, loc, /*ignore_cs0104=*/ false);
+                       FullNamedExpression fne = ec.LookupNamespaceOrType (Name, Arity, LookupMode.Normal, loc);
 
                        if (fne != null) {
                                if (fne.Type != null && Arity > 0) {
                                        if (HasTypeArguments) {
                                                GenericTypeExpr ct = new GenericTypeExpr (fne.Type, targs, loc);
-                                               return ct.ResolveAsTypeStep (ec, false);
+                                               if (ct.ResolveAsType (ec) == null)
+                                                       return null;
+
+                                               return ct;
                                        }
 
                                        return new GenericOpenTypeExpr (fne.Type, loc);
@@ -2188,19 +2130,22 @@ namespace Mono.CSharp {
                                                ec.Module.PredefinedAttributes.Dynamic.GetSignatureForError ());
                                }
 
-                               return new DynamicTypeExpr (loc).ResolveAsTypeStep (ec, silent);
+                               fne = new DynamicTypeExpr (loc);
+                               fne.ResolveAsType (ec);
                        }
 
                        if (fne != null)
                                return fne;
 
-                       if (silent || errors != ec.Module.Compiler.Report.Errors)
-                               return null;
-
                        Error_TypeOrNamespaceNotFound (ec);
                        return null;
                }
 
+               public bool IsPossibleTypeOrNamespace (IMemberContext mc)
+               {
+                       return mc.LookupNamespaceOrType (Name, Arity, LookupMode.Probing, loc) != null;
+               }
+
                public override Expression LookupNameExpression (ResolveContext rc, MemberLookupRestrictions restrictions)
                {
                        int lookup_arity = Arity;
@@ -2227,7 +2172,7 @@ namespace Mono.CSharp {
                                                        e = variable.CreateReferenceExpression (rc, loc);
                                                        if (e != null) {
                                                                if (Arity > 0)
-                                                                       Error_TypeArgumentsCannotBeUsed (rc.Report, "variable", Name, loc);
+                                                                       Error_TypeArgumentsCannotBeUsed (rc, "variable", Name, loc);
 
                                                                return e;
                                                        }
@@ -2312,14 +2257,13 @@ namespace Mono.CSharp {
                                // Stage 3: Lookup nested types, namespaces and type parameters in the context
                                //
                                if ((restrictions & MemberLookupRestrictions.InvocableOnly) == 0 && !variable_found) {
-                                       e = ResolveAsTypeStep (rc, lookup_arity == 0 || !errorMode);
-                                       if (e != null) {
+                                       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 e;
+                                               return ResolveAsTypeOrNamespace (rc);
                                        }
                                }
 
@@ -2327,10 +2271,53 @@ namespace Mono.CSharp {
                                        if (variable_found) {
                                                rc.Report.Error (841, loc, "A local variable `{0}' cannot be used before it is declared", Name);
                                        } else {
+                                               if (Arity > 0) {
+                                                       TypeParameter[] tparams = rc.CurrentTypeParameters;
+                                                       if (tparams != null) {
+                                                               foreach (var ctp in tparams) {
+                                                                       if (ctp.Name == Name) {
+                                                                               Error_TypeArgumentsCannotBeUsed (rc, "type parameter", Name, loc);
+                                                                               return null;
+                                                                       }
+                                                               }
+                                                       }
+
+                                                       var ct = rc.CurrentType;
+                                                       do {
+                                                               if (ct.MemberDefinition.TypeParametersCount > 0) {
+                                                                       foreach (var ctp in ct.MemberDefinition.TypeParameters) {
+                                                                               if (ctp.Name == Name) {
+                                                                                       Error_TypeArgumentsCannotBeUsed (rc, "type parameter", Name, loc);
+                                                                                       return null;
+                                                                               }
+                                                                       }
+                                                               }
+
+                                                               ct = ct.DeclaringType;
+                                                       } while (ct != null);
+                                               }
+
+                                               if ((restrictions & MemberLookupRestrictions.InvocableOnly) == 0) {
+                                                       e = rc.LookupNamespaceOrType (Name, Arity, LookupMode.IgnoreAccessibility, loc);
+                                                       if (e != null) {
+                                                               rc.Report.SymbolRelatedToPreviousError (e.Type);
+                                                               ErrorIsInaccesible (rc, e.GetSignatureForError (), loc);
+                                                               return e;
+                                                       }
+                                               }
+
+                                               e = rc.LookupNamespaceOrType (Name, -System.Math.Max (1, Arity), LookupMode.Probing, loc);
+                                               if (e != null) {
+                                                       if (!(e is TypeExpr) || (restrictions & MemberLookupRestrictions.InvocableOnly) == 0 || !e.Type.IsDelegate) {
+                                                               Error_TypeArgumentsCannotBeUsed (rc, e.Type, Arity, loc);
+                                                               return e;
+                                                       }
+                                               }
+
                                                rc.Report.Error (103, loc, "The name `{0}' does not exist in the current context", Name);
                                        }
 
-                                       return null;
+                                       return ErrorExpression.Instance;
                                }
 
                                if (rc.Module.Evaluator != null) {
@@ -2340,7 +2327,6 @@ namespace Mono.CSharp {
                                }
 
                                lookup_arity = 0;
-                               restrictions &= ~MemberLookupRestrictions.InvocableOnly;
                                errorMode = true;
                        }
                }
@@ -2385,11 +2371,50 @@ namespace Mono.CSharp {
                        throw new NotSupportedException ("ET");
                }
 
-               public override FullNamedExpression ResolveAsTypeStep (IMemberContext ec, bool silent)
+               public abstract FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext mc);
+
+               //
+               // This is used to resolve the expression as a type, a null
+               // value will be returned if the expression is not a type
+               // reference
+               //
+               public override TypeSpec ResolveAsType (IMemberContext mc)
                {
-                       return this;
+                       FullNamedExpression fne = ResolveAsTypeOrNamespace (mc);
+
+                       if (fne == null)
+                               return null;
+
+                       TypeExpr te = fne as TypeExpr;
+                       if (te == null) {
+                               fne.Error_UnexpectedKind (mc.Module.Compiler.Report, null, "type", loc);
+                               return null;
+                       }
+
+                       te.loc = loc;
+
+                       type = te.Type;
+
+                       var dep = type.GetMissingDependencies ();
+                       if (dep != null) {
+                               ImportedTypeDefinition.Error_MissingDependency (mc, dep, loc);
+                       }
+
+                       //
+                       // 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 TypeContainer.BaseContext)) {
+                               ObsoleteAttribute obsolete_attr = type.GetAttributeObsolete ();
+                               if (obsolete_attr != null && !mc.IsObsolete) {
+                                       AttributeTester.Report_ObsoleteMessage (obsolete_attr, te.GetSignatureForError (), Location, mc.Module.Compiler.Report);
+                               }
+                       }
+
+                       return type;
                }
 
+
                public override void Emit (EmitContext ec)
                {
                        throw new InternalErrorException ("FullNamedExpression `{0}' found in resolved tree",
@@ -2400,24 +2425,20 @@ namespace Mono.CSharp {
        /// <summary>
        ///   Expression that evaluates to a type
        /// </summary>
-       public abstract class TypeExpr : FullNamedExpression {
-               public override FullNamedExpression ResolveAsTypeStep (IMemberContext ec, bool silent)
+       public abstract class TypeExpr : FullNamedExpression
+       {
+               public sealed override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext mc)
                {
-                       TypeExpr t = DoResolveAsTypeStep (ec);
-                       if (t == null)
-                               return null;
-
-                       eclass = ExprClass.Type;
-                       return t;
+                       ResolveAsType (mc);
+                       return this;
                }
 
-               protected override Expression DoResolve (ResolveContext ec)
+               protected sealed override Expression DoResolve (ResolveContext ec)
                {
-                       return ResolveAsTypeTerminal (ec, false);
+                       ResolveAsType (ec);
+                       return this;
                }
 
-               protected abstract TypeExpr DoResolveAsTypeStep (IMemberContext ec);
-
                public override bool Equals (object obj)
                {
                        TypeExpr tobj = obj as TypeExpr;
@@ -2436,7 +2457,8 @@ namespace Mono.CSharp {
        /// <summary>
        ///   Fully resolved Expression that already evaluated to a type
        /// </summary>
-       public class TypeExpression : TypeExpr {
+       public class TypeExpression : TypeExpr
+       {
                public TypeExpression (TypeSpec t, Location l)
                {
                        Type = t;
@@ -2444,14 +2466,9 @@ namespace Mono.CSharp {
                        loc = l;
                }
 
-               protected override TypeExpr DoResolveAsTypeStep (IMemberContext ec)
+               public sealed override TypeSpec ResolveAsType (IMemberContext ec)
                {
-                       return this;
-               }
-
-               public override TypeExpr ResolveAsTypeTerminal (IMemberContext ec, bool silent)
-               {
-                       return this;
+                       return type;
                }
        }
 
@@ -2495,7 +2512,6 @@ namespace Mono.CSharp {
                        get;
                }
 
-               // TODO: Not needed
                protected abstract TypeSpec DeclaringType {
                        get;
                }
@@ -2515,7 +2531,7 @@ namespace Mono.CSharp {
                        // Overload resulution works on virtual or non-virtual members only (no overrides). That
                        // means for base.member access we have to find the closest match after we found best candidate
                        //
-                       if ((method.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.STATIC)) != Modifiers.STATIC) {
+                       if ((method.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) != 0) {
                                //
                                // The method could already be what we are looking for
                                //
@@ -2570,21 +2586,25 @@ namespace Mono.CSharp {
                                return;
 
                        if ((member.Modifiers & Modifiers.PROTECTED) != 0 && !(InstanceExpression is This)) {
-                               var ct = rc.CurrentType;
-                               var expr_type = InstanceExpression.Type;
-                               if (ct == expr_type)
-                                       return;
+                               CheckProtectedMemberAccess (rc, member, InstanceExpression.Type, loc);
+                       }
+               }
 
-                               if ((member.Modifiers & Modifiers.INTERNAL) != 0 && member.DeclaringType.MemberDefinition.IsInternalAsPublic (ct.MemberDefinition.DeclaringAssembly))
-                                       return;
+               public static void CheckProtectedMemberAccess<T> (ResolveContext rc, T member, TypeSpec qualifier, Location loc) where T : MemberSpec
+               {
+                       var ct = rc.CurrentType;
+                       if (ct == qualifier)
+                               return;
 
-                               expr_type = expr_type.GetDefinition ();
-                               if (ct != expr_type && !IsSameOrBaseQualifier (ct, expr_type)) {
-                                       rc.Report.SymbolRelatedToPreviousError (member);
-                                       rc.Report.Error (1540, loc,
-                                               "Cannot access protected member `{0}' via a qualifier of type `{1}'. The qualifier must be of type `{2}' or derived from it",
-                                               member.GetSignatureForError (), expr_type.GetSignatureForError (), ct.GetSignatureForError ());
-                               }
+                       if ((member.Modifiers & Modifiers.INTERNAL) != 0 && member.DeclaringType.MemberDefinition.IsInternalAsPublic (ct.MemberDefinition.DeclaringAssembly))
+                               return;
+
+                       qualifier = qualifier.GetDefinition ();
+                       if (ct != qualifier && !IsSameOrBaseQualifier (ct, qualifier)) {
+                               rc.Report.SymbolRelatedToPreviousError (member);
+                               rc.Report.Error (1540, loc,
+                                       "Cannot access protected member `{0}' via a qualifier of type `{1}'. The qualifier must be of type `{2}' or derived from it",
+                                       member.GetSignatureForError (), qualifier.GetSignatureForError (), ct.GetSignatureForError ());
                        }
                }
 
@@ -2646,9 +2666,7 @@ namespace Mono.CSharp {
                        // 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) {
-                               rc.Report.DisableReporting ();
-                               Expression identical_type = rc.LookupNamespaceOrType (name.Name, 0, loc, true) as TypeExpr;
-                               rc.Report.EnableReporting ();
+                               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;
                        }
@@ -2758,7 +2776,7 @@ namespace Mono.CSharp {
 
                public virtual MemberExpr ResolveMemberAccess (ResolveContext ec, Expression left, SimpleName original)
                {
-                       if (left != null && left.IsNull && TypeManager.IsReferenceType (left.Type)) {
+                       if (left != null && left.IsNull && TypeSpec.IsReferenceType (left.Type)) {
                                ec.Report.Warning (1720, 1, left.Location,
                                        "Expression will always cause a `{0}'", "System.NullReferenceException");
                        }
@@ -2770,9 +2788,9 @@ namespace Mono.CSharp {
                protected void EmitInstance (EmitContext ec, bool prepare_for_load)
                {
                        TypeSpec instance_type = InstanceExpression.Type;
-                       if (TypeManager.IsValueType (instance_type)) {
+                       if (TypeSpec.IsValueType (instance_type)) {
                                if (InstanceExpression is IMemoryLocation) {
-                                       ((IMemoryLocation) InstanceExpression).AddressOf (ec, AddressOp.LoadStore);
+                                       ((IMemoryLocation) InstanceExpression).AddressOf (ec, AddressOp.Load);
                                } else {
                                        LocalTemporary t = new LocalTemporary (instance_type);
                                        InstanceExpression.Emit (ec);
@@ -2783,7 +2801,7 @@ namespace Mono.CSharp {
                                InstanceExpression.Emit (ec);
 
                                // Only to make verifier happy
-                               if (instance_type.IsGenericParameter && !(InstanceExpression is This) && TypeManager.IsReferenceType (instance_type))
+                               if (instance_type.IsGenericParameter && !(InstanceExpression is This) && TypeSpec.IsReferenceType (instance_type))
                                        ec.Emit (OpCodes.Box, instance_type);
                        }
 
@@ -2799,10 +2817,10 @@ namespace Mono.CSharp {
        // 
        class ExtensionMethodGroupExpr : MethodGroupExpr, OverloadResolver.IErrorHandler
        {
-               NamespaceEntry namespace_entry;
+               NamespaceContainer namespace_entry;
                public readonly Expression ExtensionExpression;
 
-               public ExtensionMethodGroupExpr (IList<MethodSpec> list, NamespaceEntry n, Expression extensionExpr, Location l)
+               public ExtensionMethodGroupExpr (IList<MethodSpec> list, NamespaceContainer n, Expression extensionExpr, Location l)
                        : base (list.Cast<MemberSpec>().ToList (), extensionExpr.Type, l)
                {
                        this.namespace_entry = n;
@@ -3161,7 +3179,7 @@ namespace Mono.CSharp {
                                return null;
 
                        int arity = type_arguments == null ? 0 : type_arguments.Count;
-                       NamespaceEntry methods_scope = null;
+                       NamespaceContainer methods_scope = null;
                        var methods = rc.LookupExtensionMethod (InstanceExpression.Type, Methods[0].Name, arity, ref methods_scope);
                        if (methods == null)
                                return null;
@@ -3367,7 +3385,7 @@ namespace Mono.CSharp {
                                //
                                // With identical parameter lists
                                //
-                               if (!TypeSpecComparer.Equals (p_m.Parameters.Types,q_m.Parameters.Types))
+                               if (!TypeSpecComparer.Equals (p_m.Parameters.Types, q_m.Parameters.Types))
                                        return 0;
 
                                p = p_m.ReturnType;
@@ -3386,6 +3404,28 @@ namespace Mono.CSharp {
                                if (q.Kind == MemberKind.Void) {
                                        return p.Kind != MemberKind.Void ? 1: 0;
                                }
+
+                               //
+                               // 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) {
+                                       if (p.IsGenericTask != q.IsGenericTask) {
+                                               return 0;
+                                       }
+
+                                       var async_am = a.Expr as AnonymousMethodExpression;
+                                       if (async_am == null || !async_am.IsAsync)
+                                               return 0;
+
+                                       q = q.TypeArguments[0];
+                                       p = p.TypeArguments[0];
+                               }
+
+                               //
+                               // The parameters are identicial and return type is not void, use better type conversion
+                               // on return type to determine better one
+                               //
                        } else {
                                if (argument_type == p)
                                        return 1;
@@ -4013,7 +4053,7 @@ namespace Mono.CSharp {
                                //
                                // 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 found, this set is used to report more details about what was wrong
+                               // candidate was found, this set is used to report more details about what was wrong
                                // with lambda body
                                //
                                if (argument.Expr.Type == InternalType.AnonymousMethod) {
@@ -4023,6 +4063,10 @@ namespace Mono.CSharp {
                                        }
                                }
 
+                               //
+                               // 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 ();
@@ -4281,6 +4325,13 @@ namespace Mono.CSharp {
                                return null;
                        }
 
+                       //
+                       // These flags indicates we are running delegate probing conversion. No need to
+                       // do more expensive checks
+                       // 
+                       if ((restrictions & (Restrictions.ProbingOnly | Restrictions.CovariantDelegate)) == (Restrictions.CovariantDelegate | Restrictions.ProbingOnly))
+                               return (T) best_candidate;
+
                        if (ambiguous_candidates != null) {
                                //
                                // Now check that there are no ambiguities i.e the selected method
@@ -4380,7 +4431,7 @@ namespace Mono.CSharp {
                                else
                                        ec.Report.Error (1620, loc, "Argument `#{0}' is missing `{1}' modifier",
                                                index, Parameter.GetModifierSignature (mod));
-                       } else {
+                       } else if (a.Expr != ErrorExpression.Instance) {
                                string p1 = a.GetSignatureForError ();
                                string p2 = TypeManager.CSharpName (paramType);
 
@@ -4404,7 +4455,7 @@ namespace Mono.CSharp {
 
                        if (ta_count != best_candidate.Arity && (ta_count > 0 || ((IParametersMember) best_candidate).Parameters.IsEmpty)) {
                                var mg = new MethodGroupExpr (new [] { best_candidate }, best_candidate.DeclaringType, loc);
-                               mg.Error_TypeArgumentsCannotBeUsed (rc.Report, loc, best_candidate, ta_count);
+                               mg.Error_TypeArgumentsCannotBeUsed (rc, best_candidate, ta_count, loc);
                                return;
                        }
 
@@ -4683,7 +4734,7 @@ namespace Mono.CSharp {
 
                public override void SetTypeArguments (ResolveContext ec, TypeArguments ta)
                {
-                       Error_TypeArgumentsCannotBeUsed (ec.Report, "constant", GetSignatureForError (), loc);
+                       Error_TypeArgumentsCannotBeUsed (ec, "constant", GetSignatureForError (), loc);
                }
        }
 
@@ -4770,7 +4821,7 @@ namespace Mono.CSharp {
                public bool IsMarshalByRefAccess (ResolveContext rc)
                {
                        // Checks possible ldflda of field access expression
-                       return !spec.IsStatic && TypeManager.IsValueType (spec.MemberType) && !(InstanceExpression is This) &&
+                       return !spec.IsStatic && TypeSpec.IsValueType (spec.MemberType) && !(InstanceExpression is This) &&
                                rc.Module.PredefinedTypes.MarshalByRefObject.Define () &&
                                TypeSpec.IsBaseClass (spec.DeclaringType, rc.Module.PredefinedTypes.MarshalByRefObject.TypeSpec, false);
                }
@@ -4812,32 +4863,34 @@ namespace Mono.CSharp {
                {
                        bool lvalue_instance = rhs != null && IsInstance && spec.DeclaringType.IsStruct;
 
-                       if (ResolveInstanceExpression (ec, rhs)) {
-                               // Resolve the field's instance expression while flow analysis is turned
-                               // off: when accessing a field "a.b", we must check whether the field
-                               // "a.b" is initialized, not whether the whole struct "a" is initialized.
+                       if (rhs != this) {
+                               if (ResolveInstanceExpression (ec, rhs)) {
+                                       // Resolve the field's instance expression while flow analysis is turned
+                                       // off: when accessing a field "a.b", we must check whether the field
+                                       // "a.b" is initialized, not whether the whole struct "a" is initialized.
 
-                               if (lvalue_instance) {
-                                       using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) {
-                                               bool out_access = rhs == EmptyExpression.OutAccess || rhs == EmptyExpression.LValueMemberOutAccess;
+                                       if (lvalue_instance) {
+                                               using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) {
+                                                       bool out_access = rhs == EmptyExpression.OutAccess || rhs == EmptyExpression.LValueMemberOutAccess;
 
-                                               Expression right_side =
-                                                       out_access ? EmptyExpression.LValueMemberOutAccess : EmptyExpression.LValueMemberAccess;
+                                                       Expression right_side =
+                                                               out_access ? EmptyExpression.LValueMemberOutAccess : EmptyExpression.LValueMemberAccess;
 
-                                               InstanceExpression = InstanceExpression.ResolveLValue (ec, right_side);
-                                       }
-                               } else {
-                                       using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) {
-                                               InstanceExpression = InstanceExpression.Resolve (ec, ResolveFlags.VariableOrValue);
+                                                       InstanceExpression = InstanceExpression.ResolveLValue (ec, right_side);
+                                               }
+                                       } else {
+                                               using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) {
+                                                       InstanceExpression = InstanceExpression.Resolve (ec, ResolveFlags.VariableOrValue);
+                                               }
                                        }
+
+                                       if (InstanceExpression == null)
+                                               return null;
                                }
 
-                               if (InstanceExpression == null)
-                                       return null;
+                               DoBestMemberChecks (ec, spec);
                        }
 
-                       DoBestMemberChecks (ec, spec);
-
                        var fb = spec as FixedFieldSpec;
                        IVariableReference var = InstanceExpression as IVariableReference;
 
@@ -5039,11 +5092,21 @@ namespace Mono.CSharp {
 
                public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load)
                {
-                       prepared = prepare_for_load && !(source is DynamicExpressionStatement);
-                       if (IsInstance)
-                               EmitInstance (ec, prepared);
+                       var await_expr = source as Await;
+                       if (await_expr != null) {
+                               //
+                               // Await is not ordinary expression (it contains jump), hence the usual flow cannot be used
+                               // to emit instance load before expression
+                               //
+                               await_expr.EmitAssign (ec, this);
+                       } else {
+                               prepared = prepare_for_load && !(source is DynamicExpressionStatement);
+                               if (IsInstance)
+                                       EmitInstance (ec, prepared);
+
+                               source.Emit (ec);
+                       }
 
-                       source.Emit (ec);
                        if (leave_copy) {
                                ec.Emit (OpCodes.Dup);
                                if (!IsStatic) {
@@ -5143,7 +5206,7 @@ namespace Mono.CSharp {
 
                public override void SetTypeArguments (ResolveContext ec, TypeArguments ta)
                {
-                       Error_TypeArgumentsCannotBeUsed (ec.Report, "field", GetSignatureForError (), loc);
+                       Error_TypeArgumentsCannotBeUsed (ec, "field", GetSignatureForError (), loc);
                }
        }
 
@@ -5325,7 +5388,7 @@ namespace Mono.CSharp {
                {
                        eclass = ExprClass.PropertyAccess;
 
-                       if (best_candidate.IsNotRealProperty) {
+                       if (best_candidate.IsNotCSharpCompatible) {
                                Error_PropertyNotValid (rc);
                        }
 
@@ -5345,7 +5408,7 @@ namespace Mono.CSharp {
 
                public override void SetTypeArguments (ResolveContext ec, TypeArguments ta)
                {
-                       Error_TypeArgumentsCannotBeUsed (ec.Report, "property", GetSignatureForError (), loc);
+                       Error_TypeArgumentsCannotBeUsed (ec, "property", GetSignatureForError (), loc);
                }
        }
 
@@ -5673,7 +5736,7 @@ namespace Mono.CSharp {
 
                public override void SetTypeArguments (ResolveContext ec, TypeArguments ta)
                {
-                       Error_TypeArgumentsCannotBeUsed (ec.Report, "event", GetSignatureForError (), loc);
+                       Error_TypeArgumentsCannotBeUsed (ec, "event", GetSignatureForError (), loc);
                }
        }