@@ -6827,26 +6827,22 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
6827
6827
llvm_unreachable (" Unhandled coercion" );
6828
6828
}
6829
6829
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) {
6842
6835
// Member is not a wrapped property
6843
6836
auto *VD = dyn_cast<VarDecl>(member);
6844
6837
if (!(VD && VD->hasAttachedPropertyWrapper ()))
6845
6838
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.
6847
6842
auto *CD = dyn_cast<ConstructorDecl>(UseDC);
6848
6843
if (!CD)
6849
6844
return false ;
6845
+
6850
6846
// This is not an assignment on self
6851
6847
if (!baseExpr->isSelfExprOf (CD))
6852
6848
return false ;
@@ -6886,15 +6882,14 @@ static Type adjustSelfTypeForMember(Expr *baseExpr,
6886
6882
bool isSettableFromHere =
6887
6883
SD->isSettable (UseDC) && SD->isSetterAccessibleFrom (UseDC);
6888
6884
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 () &&
6896
6891
(!isSettableFromHere || !SD->isSetterMutating ()) &&
6897
- !isNonMutatingSetterPWAssignInsideInit (baseExpr, member, UseDC))
6892
+ !isPotentialPropertyWrapperInit (baseExpr, member, UseDC))
6898
6893
return baseObjectTy;
6899
6894
6900
6895
if (isa<SubscriptDecl>(member))
0 commit comments