Rework gc descriptor to include size information in more cases.
[mono.git] / mcs / mcs / ecore.cs
index bcc4701dfb6ac889d67ef05c8af23100d519395a..6263adab8b99b96e64fe7e943f8ea1baf4447c5c 100644 (file)
@@ -7,6 +7,7 @@
 //
 // Copyright 2001, 2002, 2003 Ximian, Inc.
 // Copyright 2003-2008 Novell, Inc.
+// Copyright 2011 Xamarin Inc.
 //
 //
 
@@ -315,9 +316,20 @@ namespace Mono.CSharp {
                                TypeManager.CSharpName (type), name);
                }
 
-               protected static void Error_ValueAssignment (ResolveContext ec, Location loc)
+               public void Error_ValueAssignment (ResolveContext rc, Expression rhs)
                {
-                       ec.Report.Error (131, loc, "The left-hand side of an assignment must be a variable, a property or an indexer");
+                       if (rhs == EmptyExpression.LValueMemberAccess || rhs == EmptyExpression.LValueMemberOutAccess) {
+                               rc.Report.SymbolRelatedToPreviousError (type);
+                               if (rc.CurrentInitializerVariable != null) {
+                                       rc.Report.Error (1918, loc, "Members of value type `{0}' cannot be assigned using a property `{1}' object initializer",
+                                               type.GetSignatureForError (), GetSignatureForError ());
+                               } else {
+                                       rc.Report.Error (1612, loc, "Cannot modify a value type return value of `{0}'. Consider storing the value in a temporary variable",
+                                               GetSignatureForError ());
+                               }
+                       } else {
+                               rc.Report.Error (131, loc, "The left-hand side of an assignment must be a variable, a property or an indexer");
+                       }
                }
 
                protected void Error_VoidPointerOperation (ResolveContext rc)
@@ -390,7 +402,7 @@ namespace Mono.CSharp {
                                        throw;
 
                                ec.Report.Error (584, loc, "Internal compiler error: {0}", ex.Message);
-                               return EmptyExpression.Null;    // TODO: Add location
+                               return ErrorExpression.Instance;        // TODO: Add location
                        }
                }
 
@@ -431,7 +443,7 @@ namespace Mono.CSharp {
                                        if (out_access)
                                                ec.Report.Error (1510, loc, "A ref or out argument must be an assignable variable");
                                        else
-                                               Error_ValueAssignment (ec, loc);
+                                               Error_ValueAssignment (ec, right_side);
                                }
                                return null;
                        }
@@ -528,12 +540,12 @@ namespace Mono.CSharp {
 
                        //
                        // Store the result to temporary field when we
-                       // cannot load this directly
+                       // cannot load `this' directly
                        //
                        var field = ec.GetTemporaryField (type);
                        if (needs_temporary) {
                                //
-                               // Create temporary local (we cannot load this before Emit)
+                               // Create temporary local (we cannot load `this' before Emit)
                                //
                                var temp = ec.GetTemporaryLocal (type);
                                ec.Emit (OpCodes.Stloc, temp);
@@ -628,15 +640,11 @@ namespace Mono.CSharp {
                        }
 
                        var r = new OverloadResolver (ctors, OverloadResolver.Restrictions.NoBaseMembers, loc);
-                       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);
+                       if (!rc.HasSet (ResolveContext.Options.BaseInitializer)) {
+                               r.InstanceQualifier = new ConstructorInstanceQualifier (type);
                        }
 
-                       return ctor;
+                       return r.ResolveMember<MethodSpec> (rc, ref args);
                }
 
                [Flags]
@@ -668,6 +676,9 @@ namespace Mono.CSharp {
                                        if ((member.Modifiers & Modifiers.OVERRIDE) != 0 && member.Kind != MemberKind.Event)
                                                continue;
 
+                                       if ((member.Modifiers & Modifiers.BACKING_FIELD) != 0)
+                                               continue;
+
                                        if ((arity > 0 || (restrictions & MemberLookupRestrictions.ExactArity) != 0) && member.Arity != arity)
                                                continue;
 
@@ -738,6 +749,12 @@ namespace Mono.CSharp {
                        throw new NotImplementedException ();
                }
 
+               public virtual void Error_OperatorCannotBeApplied (ResolveContext rc, Location loc, string oper, TypeSpec t)
+               {
+                       rc.Report.Error (23, loc, "The `{0}' operator cannot be applied to operand of type `{1}'",
+                               oper, t.GetSignatureForError ());
+               }
+
                protected void Error_PointerInsideExpressionTree (ResolveContext ec)
                {
                        ec.Report.Error (1944, loc, "An expression tree cannot contain an unsafe pointer operation");
@@ -831,7 +848,7 @@ namespace Mono.CSharp {
                              name, was, expected);
                }
 
-               public void Error_UnexpectedKind (ResolveContext ec, ResolveFlags flags, Location loc)
+               public virtual void Error_UnexpectedKind (ResolveContext ec, ResolveFlags flags, Location loc)
                {
                        string [] valid = new string [4];
                        int count = 0;
@@ -874,18 +891,6 @@ namespace Mono.CSharp {
                        Report.Error (214, loc, "Pointers and fixed size buffers may only be used in an unsafe context");
                }
 
-               protected void Error_CannotModifyIntermediateExpressionValue (ResolveContext ec)
-               {
-                       ec.Report.SymbolRelatedToPreviousError (type);
-                       if (ec.CurrentInitializerVariable != null) {
-                               ec.Report.Error (1918, loc, "Members of value type `{0}' cannot be assigned using a property `{1}' object initializer",
-                                       TypeManager.CSharpName (type), GetSignatureForError ());
-                       } else {
-                               ec.Report.Error (1612, loc, "Cannot modify a value type return value of `{0}'. Consider storing the value in a temporary variable",
-                                       GetSignatureForError ());
-                       }
-               }
-
                //
                // Converts `source' to an int, uint, long or ulong.
                //
@@ -1001,6 +1006,11 @@ namespace Mono.CSharp {
                {
                        throw new NotImplementedException ("MakeExpression for " + GetType ());
                }
+                       
+               public virtual object Accept (StructuralVisitor visitor)
+               {
+                       return visitor.Visit (this);
+               }
        }
 
        /// <summary>
@@ -1856,6 +1866,17 @@ namespace Mono.CSharp {
                                        c = new ReducedConstantExpression (c, orig_expr);
                                return c;
                        }
+
+                       public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
+                       {
+                               //
+                               // LAMESPEC: Reduced conditional expression is allowed as an attribute argument
+                               //
+                               if (orig_expr is Conditional)
+                                       child.EncodeAttributeValue (rc, enc, targetType);
+                               else
+                                       base.EncodeAttributeValue (rc, enc, targetType);
+                       }
                }
 
                sealed class ReducedExpressionStatement : ExpressionStatement
@@ -2213,9 +2234,16 @@ namespace Mono.CSharp {
                        return new SimpleName (Name, targs, loc);
                }
 
-               protected override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext rc)
                {
-                       return SimpleNameResolve (ec, null, false);
+                       var e = SimpleNameResolve (rc, null, false);
+
+                       var fe = e as FieldExpr;
+                       if (fe != null) {
+                               fe.VerifyAssignedStructField (rc, null);
+                       }
+
+                       return e;
                }
 
                public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
@@ -2504,6 +2532,11 @@ namespace Mono.CSharp {
                        //if (ec.CurrentBlock == null || ec.CurrentBlock.CheckInvariantMeaningInBlock (Name, e, Location))
                        return e;
                }
+               
+               public override object Accept (StructuralVisitor visitor)
+               {
+                       return visitor.Visit (this);
+               }
        }
 
        /// <summary>
@@ -2633,7 +2666,7 @@ namespace Mono.CSharp {
        ///   This class denotes an expression which evaluates to a member
        ///   of a struct or a class.
        /// </summary>
-       public abstract class MemberExpr : Expression
+       public abstract class MemberExpr : Expression, OverloadResolver.IInstanceQualifier
        {
                //
                // An instance expression associated with this member, if it's a
@@ -2673,6 +2706,12 @@ namespace Mono.CSharp {
                        get;
                }
 
+               TypeSpec OverloadResolver.IInstanceQualifier.InstanceType {
+                       get {
+                               return InstanceExpression.Type;
+                       }
+               }
+
                //
                // Converts best base candidate for virtual method starting from QueriedBaseType
                //
@@ -2737,32 +2776,41 @@ namespace Mono.CSharp {
                        return method;
                }
 
-               protected void CheckProtectedMemberAccess<T> (ResolveContext rc, T member) where T : MemberSpec
+               protected void CheckProtectedMemberAccess (ResolveContext rc, MemberSpec member)
                {
                        if (InstanceExpression == null)
                                return;
 
                        if ((member.Modifiers & Modifiers.PROTECTED) != 0 && !(InstanceExpression is This)) {
-                               CheckProtectedMemberAccess (rc, member, InstanceExpression.Type, loc);
+                               if (!CheckProtectedMemberAccess (rc, member, InstanceExpression.Type)) {
+                                       Error_ProtectedMemberAccess (rc, member, InstanceExpression.Type, loc);
+                               }
                        }
                }
 
-               public static void CheckProtectedMemberAccess<T> (ResolveContext rc, T member, TypeSpec qualifier, Location loc) where T : MemberSpec
+               bool OverloadResolver.IInstanceQualifier.CheckProtectedMemberAccess (ResolveContext rc, MemberSpec member)
+               {
+                       if (InstanceExpression == null)
+                               return true;
+
+                       return InstanceExpression is This || CheckProtectedMemberAccess (rc, member, InstanceExpression.Type);
+               }
+
+               public static bool CheckProtectedMemberAccess<T> (ResolveContext rc, T member, TypeSpec qualifier) where T : MemberSpec
                {
                        var ct = rc.CurrentType;
                        if (ct == qualifier)
-                               return;
+                               return true;
 
                        if ((member.Modifiers & Modifiers.INTERNAL) != 0 && member.DeclaringType.MemberDefinition.IsInternalAsPublic (ct.MemberDefinition.DeclaringAssembly))
-                               return;
+                               return true;
 
                        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 ());
+                               return false;
                        }
+
+                       return true;
                }
 
                public override bool ContainsEmitWithAwait ()
@@ -2815,6 +2863,14 @@ namespace Mono.CSharp {
                        rc.Report.Error (205, loc, "Cannot call an abstract base member `{0}'", name);
                }
 
+               public static void Error_ProtectedMemberAccess (ResolveContext rc, MemberSpec member, TypeSpec qualifier, Location loc)
+               {
+                       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 (), rc.CurrentType.GetSignatureForError ());
+               }
+
                //
                // Implements identicial simple name and type-name
                //
@@ -2876,6 +2932,7 @@ namespace Mono.CSharp {
                                                        "An object reference is required to access non-static member `{0}'",
                                                        GetSignatureForError ());
 
+                                       InstanceExpression = new CompilerGeneratedThis (type, loc).Resolve (rc);
                                        return false;
                                }
 
@@ -2886,7 +2943,7 @@ namespace Mono.CSharp {
                                }
 
                                InstanceExpression = new This (loc);
-                               if (this is FieldExpr && rc.CurrentType.IsStruct) {
+                               if (this is FieldExpr && rc.CurrentBlock.ParametersBlock.TopBlock.ThisVariable != null) {
                                        using (rc.Set (ResolveContext.Options.OmitStructFlowAnalysis)) {
                                                InstanceExpression = InstanceExpression.Resolve (rc);
                                        }
@@ -2917,7 +2974,7 @@ namespace Mono.CSharp {
                        // the expression is not field expression which is the only
                        // expression which can use uninitialized this
                        //
-                       if (InstanceExpression is This && !(this is FieldExpr) && rc.CurrentType.IsStruct) {
+                       if (InstanceExpression is This && !(this is FieldExpr) && rc.CurrentBlock.ParametersBlock.TopBlock.ThisVariable != null) {
                                ((This)InstanceExpression).CheckStructThisDefiniteAssignment (rc);
                        }
 
@@ -2925,9 +2982,6 @@ namespace Mono.CSharp {
                        // Additional checks for l-value member access
                        //
                        if (rhs != null) {
-                               //
-                               // TODO: It should be recursive but that would break csc compatibility
-                               //
                                if (InstanceExpression is UnboxCast) {
                                        rc.Report.Error (445, InstanceExpression.Location, "Cannot modify the result of an unboxing conversion");
                                }
@@ -2954,11 +3008,12 @@ namespace Mono.CSharp {
                                if (InstanceExpression is IMemoryLocation) {
                                        ((IMemoryLocation) InstanceExpression).AddressOf (ec, AddressOp.Load);
                                } else {
+                                       // Cannot release the temporary variable when its address
+                                       // is required to be on stack for any parent
                                        LocalTemporary t = new LocalTemporary (instance_type);
                                        InstanceExpression.Emit (ec);
                                        t.Store (ec);
                                        t.AddressOf (ec, AddressOp.Store);
-                                       t.Release (ec);
                                }
                        } else {
                                InstanceExpression.Emit (ec);
@@ -3334,6 +3389,7 @@ namespace Mono.CSharp {
                        var r = new OverloadResolver (Methods, type_arguments, restr, loc);
                        if ((restr & OverloadResolver.Restrictions.NoBaseMembers) == 0) {
                                r.BaseMembersProvider = this;
+                               r.InstanceQualifier = this;
                        }
 
                        if (cerrors != null)
@@ -3362,8 +3418,6 @@ namespace Mono.CSharp {
                                }
 
                                ResolveInstanceExpression (ec, null);
-                               if (InstanceExpression != null)
-                                       CheckProtectedMemberAccess (ec, best_candidate);
                        }
 
                        var base_override = CandidateToBaseOverride (ec, best_candidate);
@@ -3429,6 +3483,22 @@ namespace Mono.CSharp {
                #endregion
        }
 
+       struct ConstructorInstanceQualifier : OverloadResolver.IInstanceQualifier
+       {
+               public ConstructorInstanceQualifier (TypeSpec type)
+                       : this ()
+               {
+                       InstanceType = type;
+               }
+
+               public TypeSpec InstanceType { get; private set; }
+
+               public bool CheckProtectedMemberAccess (ResolveContext rc, MemberSpec member)
+               {
+                       return MemberExpr.CheckProtectedMemberAccess (rc, member, InstanceType);
+               }
+       }
+
        public struct OverloadResolver
        {
                [Flags]
@@ -3457,6 +3527,12 @@ namespace Mono.CSharp {
                        bool TypeInferenceFailed (ResolveContext rc, MemberSpec best);
                }
 
+               public interface IInstanceQualifier
+               {
+                       TypeSpec InstanceType { get; }
+                       bool CheckProtectedMemberAccess (ResolveContext rc, MemberSpec member);
+               }
+
                sealed class NoBaseMembers : IBaseMembersProvider
                {
                        public static readonly IBaseMembersProvider Instance = new NoBaseMembers ();
@@ -3496,6 +3572,7 @@ namespace Mono.CSharp {
                TypeArguments type_arguments;
                IBaseMembersProvider base_provider;
                IErrorHandler custom_errors;
+               IInstanceQualifier instance_qualifier;
                Restrictions restrictions;
                MethodGroupExpr best_candidate_extension_group;
                TypeSpec best_candidate_return_type;
@@ -3573,6 +3650,15 @@ namespace Mono.CSharp {
                        }
                }
 
+               public IInstanceQualifier InstanceQualifier {
+                       get {
+                               return instance_qualifier;
+                       }
+                       set {
+                               instance_qualifier = value;
+                       }
+               }
+
                bool IsProbingOnly {
                        get {
                                return (restrictions & Restrictions.ProbingOnly) != 0;
@@ -3647,16 +3733,16 @@ namespace Mono.CSharp {
                                // 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;
+                                       if (async_am != null && async_am.Block.IsAsync) {
 
-                                       q = q.TypeArguments[0];
-                                       p = p.TypeArguments[0];
+                                               if (p.IsGenericTask != q.IsGenericTask) {
+                                                       return 0;
+                                               }
+
+                                               q = q.TypeArguments[0];
+                                               p = p.TypeArguments[0];
+                                       }
                                }
 
                                //
@@ -4154,7 +4240,7 @@ namespace Mono.CSharp {
                                        // if the type matches
                                        //
                                        Expression e = pd.FixedParameters[i].DefaultValue;
-                                       if (!(e is Constant) || e.Type.IsGenericOrParentIsGeneric) {
+                                       if (!(e is Constant) || e.Type.IsGenericOrParentIsGeneric || e.Type.IsGenericParameter) {
                                                //
                                                // LAMESPEC: No idea what the exact rules are for System.Reflection.Missing.Value instead of null
                                                //
@@ -4327,7 +4413,10 @@ namespace Mono.CSharp {
 
                        var ac_p = p as ArrayContainer;
                        if (ac_p != null) {
-                               var ac_q = ((ArrayContainer) q);
+                               var ac_q = q as ArrayContainer;
+                               if (ac_q == null)
+                                       return null;
+
                                TypeSpec specific = MoreSpecific (ac_p.Element, ac_q.Element);
                                if (specific == ac_p.Element)
                                        return p;
@@ -4402,6 +4491,11 @@ namespace Mono.CSharp {
 
                                                                if (rc.IsRuntimeBinder && !member.DeclaringType.IsAccessible (rc))
                                                                        continue;
+
+                                                               if ((member.Modifiers & (Modifiers.PROTECTED | Modifiers.STATIC)) == Modifiers.PROTECTED &&
+                                                                       instance_qualifier != null && !instance_qualifier.CheckProtectedMemberAccess (rc, member)) {
+                                                                       continue;
+                                                               }
                                                        }
 
                                                        IParametersMember pm = member as IParametersMember;
@@ -4541,6 +4635,9 @@ namespace Mono.CSharp {
                                if (error_mode)
                                        break;
 
+                               if (lambda_conv_msgs != null && !lambda_conv_msgs.IsEmpty)
+                                       break;
+
                                lambda_conv_msgs = null;
                                error_mode = true;
                        }
@@ -4703,6 +4800,12 @@ namespace Mono.CSharp {
                                        return;
                        }
 
+
+                       if ((best_candidate.Modifiers & (Modifiers.PROTECTED | Modifiers.STATIC)) == Modifiers.PROTECTED &&
+                               InstanceQualifier != null && !InstanceQualifier.CheckProtectedMemberAccess (rc, best_candidate)) {
+                               MemberExpr.Error_ProtectedMemberAccess (rc, best_candidate, InstanceQualifier.InstanceType, loc);
+                       }
+
                        //
                        // For candidates which match on parameters count report more details about incorrect arguments
                        //
@@ -5055,7 +5158,7 @@ namespace Mono.CSharp {
 
                public override string GetSignatureForError ()
                {
-                       return TypeManager.GetFullNameSignature (spec);
+                       return spec.GetSignatureForError ();
                }
 
                public bool IsMarshalByRefAccess (ResolveContext rc)
@@ -5069,8 +5172,9 @@ namespace Mono.CSharp {
                public void SetHasAddressTaken ()
                {
                        IVariableReference vr = InstanceExpression as IVariableReference;
-                       if (vr != null)
+                       if (vr != null) {
                                vr.SetHasAddressTaken ();
+                       }
                }
 
                public override Expression CreateExpressionTree (ResolveContext ec)
@@ -5135,7 +5239,7 @@ namespace Mono.CSharp {
                        IVariableReference var = InstanceExpression as IVariableReference;
 
                        if (lvalue_instance && var != null && var.VariableInfo != null) {
-                               var.VariableInfo.SetFieldAssigned (ec, Name);
+                               var.VariableInfo.SetStructFieldAssigned (ec, Name);
                        }
                        
                        if (fb != null) {
@@ -5155,18 +5259,43 @@ namespace Mono.CSharp {
                                return new FixedBufferPtr (this, fb.ElementType, loc).Resolve (ec);
                        }
 
+                       //
+                       // Set flow-analysis variable info for struct member access. It will be check later
+                       // for precise error reporting
+                       //
+                       if (var != null && var.VariableInfo != null && InstanceExpression.Type.IsStruct) {
+                               variable_info = var.VariableInfo.GetStructFieldInfo (Name);
+                               if (rhs != null && variable_info != null)
+                                       variable_info.SetStructFieldAssigned (ec, Name);
+                       }
+
                        eclass = ExprClass.Variable;
+                       return this;
+               }
 
-                       // If the instance expression is a local variable or parameter.
-                       if (var == null || var.VariableInfo == null)
-                               return this;
+               public void VerifyAssignedStructField (ResolveContext rc, Expression rhs)
+               {
+                       var fe = this;
 
-                       VariableInfo vi = var.VariableInfo;
-                       if (!vi.IsFieldAssigned (ec, Name, loc))
-                               return null;
+                       do {
+                               var var = fe.InstanceExpression as IVariableReference;
+                               if (var != null) {
+                                       var vi = var.VariableInfo;
 
-                       variable_info = vi.GetSubStruct (Name);
-                       return this;
+                                       if (vi != null && !vi.IsStructFieldAssigned (rc, fe.Name) && (rhs == null || !fe.type.IsStruct)) {
+                                               if (rhs != null) {
+                                                       rc.Report.Warning (1060, 1, fe.loc, "Use of possibly unassigned field `{0}'", fe.Name);
+                                               } else {
+                                                       rc.Report.Error (170, fe.loc, "Use of possibly unassigned field `{0}'", fe.Name);
+                                               }
+
+                                               return;
+                                       }
+                               }
+
+                               fe = fe.InstanceExpression as FieldExpr;
+
+                       } while (fe != null);
                }
 
                static readonly int [] codes = {
@@ -5288,10 +5417,7 @@ namespace Mono.CSharp {
                
                public void Emit (EmitContext ec, bool leave_copy)
                {
-                       bool is_volatile = false;
-
-                       if ((spec.Modifiers & Modifiers.VOLATILE) != 0)
-                               is_volatile = true;
+                       bool is_volatile = (spec.Modifiers & Modifiers.VOLATILE) != 0;
 
                        spec.MemberDefinition.SetIsUsed ();
                        
@@ -5524,6 +5650,14 @@ namespace Mono.CSharp {
 
                #endregion
 
+               public static PropertyExpr CreatePredefined (PropertySpec spec, Location loc)
+               {
+                       return new PropertyExpr (spec, loc) {
+                               Getter = spec.Get,
+                               Setter = spec.Set
+                       };
+               }
+
                public override Expression CreateExpressionTree (ResolveContext ec)
                {
                        Arguments args;
@@ -5542,8 +5676,9 @@ namespace Mono.CSharp {
                        return CreateExpressionFactoryCall (ec, "Property", args);
                }
 
-               public Expression CreateSetterTypeOfExpression ()
+               public Expression CreateSetterTypeOfExpression (ResolveContext rc)
                {
+                       DoResolveLValue (rc, null);
                        return new TypeOfMethod (Setter, loc);
                }
 
@@ -5763,7 +5898,7 @@ namespace Mono.CSharp {
 
                        // if the property/indexer returns a value type, and we try to set a field in it
                        if (right_side == EmptyExpression.LValueMemberAccess || right_side == EmptyExpression.LValueMemberOutAccess) {
-                               Error_CannotModifyIntermediateExpressionValue (ec);
+                               Error_ValueAssignment (ec, right_side);
                        }
 
                        if (eclass == ExprClass.Unresolved) {
@@ -6106,20 +6241,15 @@ namespace Mono.CSharp {
                        return new TemporaryVariableReference (li, loc);
                }
 
-               public override Expression CreateExpressionTree (ResolveContext ec)
-               {
-                       throw new NotSupportedException ("ET");
-               }
-
                protected override Expression DoResolve (ResolveContext ec)
                {
                        eclass = ExprClass.Variable;
 
                        //
                        // Don't capture temporary variables except when using
-                       // iterator redirection
+                       // state machine redirection
                        //
-                       if (ec.CurrentAnonymousMethod != null && ec.CurrentAnonymousMethod.IsIterator && ec.IsVariableCapturingRequired) {
+                       if (ec.CurrentAnonymousMethod != null && ec.CurrentAnonymousMethod is StateMachineInitializer && ec.IsVariableCapturingRequired) {
                                AnonymousMethodStorey storey = li.Block.Explicit.CreateAnonymousMethodStorey (ec);
                                storey.CaptureLocalVariable (ec, li);
                        }
@@ -6173,7 +6303,11 @@ namespace Mono.CSharp {
                }
 
                public override VariableInfo VariableInfo {
-                       get { throw new NotImplementedException (); }
+                       get { return null; }
+               }
+
+               public override void VerifyAssigned (ResolveContext rc)
+               {
                }
        }