@@ -3524,13 +3524,19 @@ class ExprAvailabilityWalker : public ASTWalker {
35243524 return call;
35253525 }
35263526
3527- // / Walks up to the first enclosing LoadExpr and returns it.
3527+ // / Walks up from a potential member reference to the first LoadExpr that would
3528+ // / make the member reference an r-value instead of an l-value.
35283529 const LoadExpr *getEnclosingLoadExpr () const {
35293530 assert (!ExprStack.empty () && " must be called while visiting an expression" );
35303531 ArrayRef<const Expr *> stack = ExprStack;
35313532 stack = stack.drop_back ();
35323533
35333534 for (auto expr : llvm::reverse (stack)) {
3535+ // Do not search past the first enclosing ApplyExpr. Any enclosing
3536+ // LoadExpr from this point only applies to the result of the call.
3537+ if (auto applyExpr = dyn_cast<ApplyExpr>(expr))
3538+ return nullptr ;
3539+
35343540 if (auto loadExpr = dyn_cast<LoadExpr>(expr))
35353541 return loadExpr;
35363542 }
@@ -3631,12 +3637,7 @@ class ExprAvailabilityWalker : public ASTWalker {
36313637
36323638 // / Walk an inout expression, checking for availability.
36333639 void walkInOutExpr (InOutExpr *E) {
3634- // If there is a LoadExpr in the stack, then this InOutExpr is not actually
3635- // indicative of any mutation so the access context should just be Getter.
3636- auto accessContext = getEnclosingLoadExpr () ? MemberAccessContext::Getter
3637- : MemberAccessContext::InOut;
3638-
3639- walkInContext (E, E->getSubExpr (), accessContext);
3640+ walkInContext (E, E->getSubExpr (), MemberAccessContext::InOut);
36403641 }
36413642
36423643 bool shouldWalkIntoClosure (AbstractClosureExpr *closure) const {
@@ -3657,7 +3658,6 @@ class ExprAvailabilityWalker : public ASTWalker {
36573658 return ;
36583659 }
36593660
3660-
36613661 // / Walk the given expression in the member access context.
36623662 void walkInContext (Expr *baseExpr, Expr *E,
36633663 MemberAccessContext AccessContext) {
@@ -3693,18 +3693,22 @@ class ExprAvailabilityWalker : public ASTWalker {
36933693 break ;
36943694
36953695 case MemberAccessContext::Setter:
3696- diagAccessorAvailability (D->getOpaqueAccessor (AccessorKind::Set),
3697- ReferenceRange, ReferenceDC, std::nullopt );
3696+ if (!getEnclosingLoadExpr ()) {
3697+ diagAccessorAvailability (D->getOpaqueAccessor (AccessorKind::Set),
3698+ ReferenceRange, ReferenceDC, std::nullopt );
3699+ }
36983700 break ;
36993701
37003702 case MemberAccessContext::InOut:
37013703 diagAccessorAvailability (D->getOpaqueAccessor (AccessorKind::Get),
37023704 ReferenceRange, ReferenceDC,
37033705 DeclAvailabilityFlag::ForInout);
37043706
3705- diagAccessorAvailability (D->getOpaqueAccessor (AccessorKind::Set),
3706- ReferenceRange, ReferenceDC,
3707- DeclAvailabilityFlag::ForInout);
3707+ if (!getEnclosingLoadExpr ()) {
3708+ diagAccessorAvailability (D->getOpaqueAccessor (AccessorKind::Set),
3709+ ReferenceRange, ReferenceDC,
3710+ DeclAvailabilityFlag::ForInout);
3711+ }
37083712 break ;
37093713 }
37103714 }
0 commit comments