Skip to content

Commit 8dbcd11

Browse files
authored
Merge pull request #74690 from tshortli/accessor-availability-reference-types
Sema: Suppress set accessor availability diagnostics in `LoadExpr`s
2 parents 461481e + 31df22f commit 8dbcd11

File tree

2 files changed

+324
-68
lines changed

2 files changed

+324
-68
lines changed

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)