@@ -6827,26 +6827,22 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
68276827 llvm_unreachable (" Unhandled coercion" );
68286828}
68296829
6830- // / Detect if the expression is an assignment to a `self` wrapped property that
6831- // / has a nonmutating setter, inside a constructor.
6832- // /
6833- // / We use this to decide when to produce an inout_expr instead of a load_expr
6834- // / for the sake of emitting a reference required by the assign_by_wrapper
6835- // / instruction.
6836- static bool isNonMutatingSetterPWAssignInsideInit (Expr *baseExpr,
6837- ValueDecl *member,
6838- DeclContext *UseDC) {
6839- // Setter is mutating
6840- if (cast<AbstractStorageDecl>(member)->isSetterMutating ())
6841- return false ;
6830+ // / Detect whether an assignment to \c baseExpr.member in the given
6831+ // / decl context can potentially be initialization of a property wrapper.
6832+ static bool isPotentialPropertyWrapperInit (Expr *baseExpr,
6833+ ValueDecl *member,
6834+ DeclContext *UseDC) {
68426835 // Member is not a wrapped property
68436836 auto *VD = dyn_cast<VarDecl>(member);
68446837 if (!(VD && VD->hasAttachedPropertyWrapper ()))
68456838 return false ;
6846- // This is not an expression inside a constructor
6839+
6840+ // Assignment to a wrapped property can only be re-written to
6841+ // initialization in an init.
68476842 auto *CD = dyn_cast<ConstructorDecl>(UseDC);
68486843 if (!CD)
68496844 return false ;
6845+
68506846 // This is not an assignment on self
68516847 if (!baseExpr->isSelfExprOf (CD))
68526848 return false ;
@@ -6886,15 +6882,14 @@ static Type adjustSelfTypeForMember(Expr *baseExpr,
68866882 bool isSettableFromHere =
68876883 SD->isSettable (UseDC) && SD->isSetterAccessibleFrom (UseDC);
68886884
6889- // If neither the property's getter nor its setter are mutating, and
6890- // this is not a nonmutating property wrapper setter,
6891- // the base can be an rvalue.
6892- // With the exception of assignments to a wrapped property inside a
6893- // constructor, where we need to produce a reference to be used on
6894- // the assign_by_wrapper instruction.
6895- if (!SD->isGetterMutating () &&
6885+ // If neither the property's getter nor its setter are mutating,
6886+ // the base can be an rvalue unless the assignment is potentially
6887+ // initializing a property wrapper. If the assignment can be re-
6888+ // written to property wrapper initialization, the base type should
6889+ // be an lvalue.
6890+ if (!SD->isGetterMutating () &&
68966891 (!isSettableFromHere || !SD->isSetterMutating ()) &&
6897- !isNonMutatingSetterPWAssignInsideInit (baseExpr, member, UseDC))
6892+ !isPotentialPropertyWrapperInit (baseExpr, member, UseDC))
68986893 return baseObjectTy;
68996894
69006895 if (isa<SubscriptDecl>(member))
0 commit comments