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