Skip to content

Commit 0f511e1

Browse files
committed
Sema: Suppress set accessor availability diagnostics in LoadExprs.
This fixes a regression from #72369. The compiler now incorrectly diagnoses use of an unavailable setter in this example: ``` func increaseBrightness(in window: UIWindow) { // warning: setter for 'screen' was deprecated in iOS 13.0 window.screen.brightness = 1.0 } ``` While the setter is deprecated, it would not going to be called in the generated code since `screen` is a reference type and there is no writeback through the setter for `screen` after setting `brightness`. Resolves rdar://129679658
1 parent e055b38 commit 0f511e1

File tree

2 files changed

+32
-52
lines changed

2 files changed

+32
-52
lines changed

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3631,12 +3631,7 @@ class ExprAvailabilityWalker : public ASTWalker {
36313631

36323632
/// Walk an inout expression, checking for availability.
36333633
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);
3634+
walkInContext(E, E->getSubExpr(), MemberAccessContext::InOut);
36403635
}
36413636

36423637
bool shouldWalkIntoClosure(AbstractClosureExpr *closure) const {
@@ -3657,7 +3652,6 @@ class ExprAvailabilityWalker : public ASTWalker {
36573652
return;
36583653
}
36593654

3660-
36613655
/// Walk the given expression in the member access context.
36623656
void walkInContext(Expr *baseExpr, Expr *E,
36633657
MemberAccessContext AccessContext) {
@@ -3693,18 +3687,22 @@ class ExprAvailabilityWalker : public ASTWalker {
36933687
break;
36943688

36953689
case MemberAccessContext::Setter:
3696-
diagAccessorAvailability(D->getOpaqueAccessor(AccessorKind::Set),
3697-
ReferenceRange, ReferenceDC, std::nullopt);
3690+
if (!getEnclosingLoadExpr()) {
3691+
diagAccessorAvailability(D->getOpaqueAccessor(AccessorKind::Set),
3692+
ReferenceRange, ReferenceDC, std::nullopt);
3693+
}
36983694
break;
36993695

37003696
case MemberAccessContext::InOut:
37013697
diagAccessorAvailability(D->getOpaqueAccessor(AccessorKind::Get),
37023698
ReferenceRange, ReferenceDC,
37033699
DeclAvailabilityFlag::ForInout);
37043700

3705-
diagAccessorAvailability(D->getOpaqueAccessor(AccessorKind::Set),
3706-
ReferenceRange, ReferenceDC,
3707-
DeclAvailabilityFlag::ForInout);
3701+
if (!getEnclosingLoadExpr()) {
3702+
diagAccessorAvailability(D->getOpaqueAccessor(AccessorKind::Set),
3703+
ReferenceRange, ReferenceDC,
3704+
DeclAvailabilityFlag::ForInout);
3705+
}
37083706
break;
37093707
}
37103708
}

test/Sema/availability_accessors.swift

Lines changed: 22 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,14 @@ struct BaseStruct<T: ValueProto> {
7272
var unavailableSetter: T {
7373
get { .defaultValue }
7474
@available(*, unavailable)
75-
set { fatalError() } // expected-note 37 {{setter for 'unavailableSetter' has been explicitly marked unavailable here}}
75+
set { fatalError() } // expected-note 27 {{setter for 'unavailableSetter' has been explicitly marked unavailable here}}
7676
}
7777

7878
var unavailableGetterAndSetter: T {
7979
@available(*, unavailable)
8080
get { fatalError() } // expected-note 46 {{getter for 'unavailableGetterAndSetter' has been explicitly marked unavailable here}}
8181
@available(*, unavailable)
82-
set { fatalError() } // expected-note 37 {{setter for 'unavailableGetterAndSetter' has been explicitly marked unavailable here}}
82+
set { fatalError() } // expected-note 27 {{setter for 'unavailableGetterAndSetter' has been explicitly marked unavailable here}}
8383
}
8484
}
8585

@@ -173,21 +173,15 @@ func testLValueAssignments_Class(_ someValue: ClassValue) {
173173
x.unavailableGetter[0].b = 1 // expected-error {{getter for 'unavailableGetter' is unavailable}}
174174

175175
x.unavailableSetter = someValue // expected-error {{setter for 'unavailableSetter' is unavailable}}
176-
// FIXME: spurious unavailable setter error
177-
x.unavailableSetter.a = someValue.a // expected-error {{setter for 'unavailableSetter' is unavailable}}
178-
// FIXME: spurious unavailable setter error
179-
x.unavailableSetter[0] = someValue.a // expected-error {{setter for 'unavailableSetter' is unavailable}}
180-
// FIXME: spurious unavailable setter error
181-
x.unavailableSetter[0].b = 1 // expected-error {{setter for 'unavailableSetter' is unavailable}}
176+
x.unavailableSetter.a = someValue.a
177+
x.unavailableSetter[0] = someValue.a
178+
x.unavailableSetter[0].b = 1
182179

183180
x.unavailableGetterAndSetter = someValue // expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
184-
// FIXME: spurious unavailable setter error
185-
x.unavailableGetterAndSetter.a = someValue.a // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
181+
x.unavailableGetterAndSetter.a = someValue.a // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}}
186182
// FIXME: missing diagnostic for getter
187-
// FIXME: spurious unavailable setter error
188-
x.unavailableGetterAndSetter[0] = someValue.a // expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
189-
// FIXME: spurious unavailable setter error
190-
x.unavailableGetterAndSetter[0].b = 1 // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
183+
x.unavailableGetterAndSetter[0] = someValue.a
184+
x.unavailableGetterAndSetter[0].b = 1 // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}}
191185
}
192186

193187
func testKeyPathLoads_Struct() {
@@ -245,17 +239,15 @@ func testKeyPathLoads_Class() {
245239
_ = x[keyPath: \.unavailableSetter.a]
246240
_ = x[keyPath: \.unavailableSetter[0]]
247241
_ = x[keyPath: \.unavailableSetter[0].b]
248-
_ = a[keyPath: \.[takesIntInOut(&x.unavailableSetter.a.b)]] // expected-error {{setter for 'unavailableSetter' is unavailable}}
249-
_ = a[keyPath: \.[takesIntInOut(&x.unavailableSetter[0].b)]] // expected-error {{setter for 'unavailableSetter' is unavailable}}
242+
_ = a[keyPath: \.[takesIntInOut(&x.unavailableSetter.a.b)]]
243+
_ = a[keyPath: \.[takesIntInOut(&x.unavailableSetter[0].b)]]
250244

251245
_ = x[keyPath: \.unavailableGetterAndSetter] // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}}
252246
_ = x[keyPath: \.unavailableGetterAndSetter.a] // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}}
253247
_ = x[keyPath: \.unavailableGetterAndSetter[0]] // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}}
254248
_ = x[keyPath: \.unavailableGetterAndSetter[0].b] // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}}
255-
// FIXME: spurious unavailable setter error
256-
_ = a[keyPath: \.[takesIntInOut(&x.unavailableGetterAndSetter.a.b)]] // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} // expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
257-
// FIXME: spurious unavailable setter error
258-
_ = a[keyPath: \.[takesIntInOut(&x.unavailableGetterAndSetter[0].b)]] // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
249+
_ = a[keyPath: \.[takesIntInOut(&x.unavailableGetterAndSetter.a.b)]] // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}}
250+
_ = a[keyPath: \.[takesIntInOut(&x.unavailableGetterAndSetter[0].b)]] // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}}
259251
}
260252

261253
func testKeyPathAssignments_Struct(_ someValue: StructValue) {
@@ -318,20 +310,16 @@ func testKeyPathAssignments_Class(_ someValue: ClassValue) {
318310
x[keyPath: \.unavailableSetter[0]] = someValue.a // expected-error {{setter for 'unavailableSetter' is unavailable}}
319311
// FIXME: spurious unavailable setter error
320312
x[keyPath: \.unavailableSetter[0].b] = 1 // expected-error {{setter for 'unavailableSetter' is unavailable}}
321-
// FIXME: spurious unavailable setter error
322-
a[keyPath: \.[takesIntInOut(&x.unavailableSetter.a.b)]] = 0 // expected-error {{setter for 'unavailableSetter' is unavailable}}
323-
// FIXME: spurious unavailable setter error
324-
a[keyPath: \.[takesIntInOut(&x.unavailableSetter[0].b)]] = 0 // expected-error {{setter for 'unavailableSetter' is unavailable}}
313+
a[keyPath: \.[takesIntInOut(&x.unavailableSetter.a.b)]] = 0
314+
a[keyPath: \.[takesIntInOut(&x.unavailableSetter[0].b)]] = 0
325315

326316
x[keyPath: \.unavailableGetterAndSetter] = someValue // expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
327317
x[keyPath: \.unavailableGetterAndSetter.a] = someValue.a // expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
328318
x[keyPath: \.unavailableGetterAndSetter[0]] = someValue.a // expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
329319
// FIXME: spurious unavailable setter error
330320
x[keyPath: \.unavailableGetterAndSetter[0].b] = 1 // expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
331-
// FIXME: spurious unavailable setter error
332-
a[keyPath: \.[takesIntInOut(&x.unavailableGetterAndSetter.a.b)]] = 0 // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
333-
// FIXME: spurious unavailable setter error
334-
a[keyPath: \.[takesIntInOut(&x.unavailableGetterAndSetter[0].b)]] = 0 // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
321+
a[keyPath: \.[takesIntInOut(&x.unavailableGetterAndSetter.a.b)]] = 0 // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}}
322+
a[keyPath: \.[takesIntInOut(&x.unavailableGetterAndSetter[0].b)]] = 0 // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}}
335323
}
336324

337325
func testMutatingStructMember() {
@@ -405,20 +393,14 @@ func testPassAsInOutParameter_Class() {
405393
takesInOut(&x.unavailableGetter[0].b) // expected-error {{getter for 'unavailableGetter' is unavailable}}
406394

407395
takesInOut(&x.unavailableSetter) // expected-error {{setter for 'unavailableSetter' is unavailable}}
408-
// FIXME: spurious unavailable setter error
409-
takesInOut(&x.unavailableSetter.a) // expected-error {{setter for 'unavailableSetter' is unavailable}}
410-
// FIXME: spurious unavailable setter error
411-
takesInOut(&x.unavailableSetter[0]) // expected-error {{setter for 'unavailableSetter' is unavailable}}
412-
// FIXME: spurious unavailable setter error
413-
takesInOut(&x.unavailableSetter[0].b) // expected-error {{setter for 'unavailableSetter' is unavailable}}
396+
takesInOut(&x.unavailableSetter.a)
397+
takesInOut(&x.unavailableSetter[0])
398+
takesInOut(&x.unavailableSetter[0].b)
414399

415400
takesInOut(&x.unavailableGetterAndSetter) // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
416-
// FIXME: spurious unavailable setter error
417-
takesInOut(&x.unavailableGetterAndSetter.a) // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
418-
// FIXME: spurious unavailable setter error
419-
takesInOut(&x.unavailableGetterAndSetter[0]) // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
420-
// FIXME: spurious unavailable setter error
421-
takesInOut(&x.unavailableGetterAndSetter[0].b) // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
401+
takesInOut(&x.unavailableGetterAndSetter.a) // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}}
402+
takesInOut(&x.unavailableGetterAndSetter[0]) // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}}
403+
takesInOut(&x.unavailableGetterAndSetter[0].b) // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}}
422404
}
423405

424406
var global = BaseStruct<StructValue>()

0 commit comments

Comments
 (0)