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