eclass = ExprClass.Value;
TypeSpec etype = expr.Type;
+ if (type == null) {
+ type = InternalType.ErrorType;
+ return this;
+ }
+
if (!TypeSpec.IsReferenceType (type) && !type.IsNullableType) {
if (TypeManager.IsGenericParameter (type)) {
ec.Report.Error (413, loc,
}
}
+ bool statement_resolve;
+ public override ExpressionStatement ResolveStatement (BlockContext bc)
+ {
+ statement_resolve = true;
+ var es = base.ResolveStatement (bc);
+ statement_resolve = false;
+
+ return es;
+ }
+
protected override Expression DoResolve (ResolveContext rc)
{
ResolveConditionalAccessReceiver (rc);
var method = mg.BestCandidate;
type = mg.BestCandidateReturnType;
- if (conditional_access_receiver)
+ if (conditional_access_receiver && !statement_resolve)
type = LiftMemberType (ec, type);
if (arguments == null && method.DeclaringType.BuiltinType == BuiltinTypeSpec.Type.Object && method.Name == Destructor.MetadataName) {
args.Insert (0, new Argument (inst.Resolve (ec), mod));
}
} else { // is SimpleName
- if (ec.IsStatic) {
+ if (ec.IsStatic || ec.HasAny (ResolveContext.Options.FieldInitializerScope | ResolveContext.Options.BaseInitializer)) {
args.Insert (0, new Argument (new TypeOf (ec.CurrentType, loc).Resolve (ec), Argument.AType.DynamicTypeName));
} else {
args.Insert (0, new Argument (new This (loc).Resolve (ec)));
{
}
+ public bool NoEmptyInterpolation { get; set; }
+
public ComposedTypeSpecifier Rank {
get {
return this.rank;
if (element == null)
return null;
- if (element is CompoundAssign.TargetExpression) {
- if (first_emit != null)
- throw new InternalErrorException ("Can only handle one mutator at a time");
- first_emit = element;
- element = first_emit_temp = new LocalTemporary (element.Type);
+ var te = element as CompoundAssign.TargetExpression;
+ if (te != null) {
+ for (int i = 1; i < initializers.Count; ++i) {
+ if (initializers [i].ContainsEmitWithAwait ()) {
+ te.RequiresEmitWithAwait = true;
+ break;
+ }
+ }
+
+ if (!te.RequiresEmitWithAwait) {
+ if (first_emit != null)
+ throw new InternalErrorException ("Can only handle one mutator at a time");
+ first_emit = element;
+ element = first_emit_temp = new LocalTemporary (element.Type);
+ }
}
return Convert.ImplicitConversionRequired (
public override void Emit (EmitContext ec)
{
+ if (!NoEmptyInterpolation && EmitOptimizedEmpty (ec))
+ return;
+
var await_field = EmitToFieldSource (ec);
if (await_field != null)
await_field.Emit (ec);
}
+ bool EmitOptimizedEmpty (EmitContext ec)
+ {
+ if (arguments.Count != 1 || dimensions != 1)
+ return false;
+
+ var c = arguments [0] as Constant;
+ if (c == null || !c.IsZeroInteger)
+ return false;
+
+ var m = ec.Module.PredefinedMembers.ArrayEmpty.Get ();
+ if (m == null || ec.CurrentType.MemberDefinition.DeclaringAssembly == m.DeclaringType.MemberDefinition.DeclaringAssembly)
+ return false;
+
+ m = m.MakeGenericMethod (ec.MemberContext, array_element_type);
+ ec.Emit (OpCodes.Call, m);
+ return true;
+ }
+
protected sealed override FieldExpr EmitToFieldSource (EmitContext ec)
{
if (first_emit != null) {
TypeSpec nested = null;
while (expr_type != null) {
- nested = MemberCache.FindNestedType (expr_type, Name, Arity);
+ nested = MemberCache.FindNestedType (expr_type, Name, Arity, false);
if (nested == null) {
if (expr_type == tnew_expr) {
Error_IdentifierNotFound (rc, expr_type);
}
expr_type = tnew_expr;
- nested = MemberCache.FindNestedType (expr_type, Name, Arity);
+ nested = MemberCache.FindNestedType (expr_type, Name, Arity, false);
ErrorIsInaccesible (rc, nested.GetSignatureForError (), loc);
break;
}
public void Error_IdentifierNotFound (IMemberContext rc, TypeSpec expr_type)
{
- var nested = MemberCache.FindNestedType (expr_type, Name, -System.Math.Max (1, Arity));
+ var nested = MemberCache.FindNestedType (expr_type, Name, -System.Math.Max (1, Arity), false);
if (nested != null) {
Error_TypeArgumentsCannotBeUsed (rc, nested, expr.Location);
throw new NotImplementedException ();
sf = ec.GetTemporaryField (type);
+ sf.AutomaticallyReuse = false;
sf.EmitAssign (ec, temp, false, false);
temp_target = sf;
temp.Release (ec);
temp.Release (ec);
if (sf != null)
- sf.IsAvailableForReuse = true;
-
+ sf.PrepareCleanup (ec);
+
return true;
}