@@ -3524,13 +3524,19 @@ class ExprAvailabilityWalker : public ASTWalker {
3524
3524
return call;
3525
3525
}
3526
3526
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.
3528
3529
const LoadExpr *getEnclosingLoadExpr () const {
3529
3530
assert (!ExprStack.empty () && " must be called while visiting an expression" );
3530
3531
ArrayRef<const Expr *> stack = ExprStack;
3531
3532
stack = stack.drop_back ();
3532
3533
3533
3534
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
+
3534
3540
if (auto loadExpr = dyn_cast<LoadExpr>(expr))
3535
3541
return loadExpr;
3536
3542
}
@@ -3631,12 +3637,7 @@ class ExprAvailabilityWalker : public ASTWalker {
3631
3637
3632
3638
// / Walk an inout expression, checking for availability.
3633
3639
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);
3640
3641
}
3641
3642
3642
3643
bool shouldWalkIntoClosure (AbstractClosureExpr *closure) const {
@@ -3657,7 +3658,6 @@ class ExprAvailabilityWalker : public ASTWalker {
3657
3658
return ;
3658
3659
}
3659
3660
3660
-
3661
3661
// / Walk the given expression in the member access context.
3662
3662
void walkInContext (Expr *baseExpr, Expr *E,
3663
3663
MemberAccessContext AccessContext) {
@@ -3693,18 +3693,22 @@ class ExprAvailabilityWalker : public ASTWalker {
3693
3693
break ;
3694
3694
3695
3695
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
+ }
3698
3700
break ;
3699
3701
3700
3702
case MemberAccessContext::InOut:
3701
3703
diagAccessorAvailability (D->getOpaqueAccessor (AccessorKind::Get),
3702
3704
ReferenceRange, ReferenceDC,
3703
3705
DeclAvailabilityFlag::ForInout);
3704
3706
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
+ }
3708
3712
break ;
3709
3713
}
3710
3714
}
0 commit comments