Skip to content

Commit ad940ab

Browse files
committed
Sema: Diagnose availability of storage accessors for key paths.
Fixes the missing diagnostic about the availability of the setter of `x` in the following example: ``` struct S { var x: Int { get { 0 } @available(*, unavailable) set {} } } var s = S() s[keyPath: \.x] = 1 ``` Resolves rdar://124977727
1 parent 9b41669 commit ad940ab

File tree

2 files changed

+25
-21
lines changed

2 files changed

+25
-21
lines changed

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3557,6 +3557,7 @@ class ExprAvailabilityWalker : public ASTWalker {
35573557
/// availability.
35583558
void maybeDiagKeyPath(KeyPathExpr *KP) {
35593559
auto flags = DeclAvailabilityFlags();
3560+
auto declContext = Where.getDeclContext();
35603561
if (KP->isObjC())
35613562
flags = DeclAvailabilityFlag::ForObjCKeyPath;
35623563

@@ -3566,7 +3567,10 @@ class ExprAvailabilityWalker : public ASTWalker {
35663567
case KeyPathExpr::Component::Kind::Subscript: {
35673568
auto decl = component.getDeclRef();
35683569
auto loc = component.getLoc();
3569-
diagnoseDeclRefAvailability(decl, loc, nullptr, flags);
3570+
auto range = component.getSourceRange();
3571+
if (diagnoseDeclRefAvailability(decl, loc, nullptr, flags))
3572+
break;
3573+
maybeDiagStorageAccess(decl.getDecl(), range, declContext);
35703574
break;
35713575
}
35723576

test/Sema/availability_accessors.swift

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -34,21 +34,21 @@ struct BaseStruct {
3434

3535
var unavailableGetter: Value {
3636
@available(*, unavailable)
37-
get { fatalError() } // expected-note 24 {{getter for 'unavailableGetter' has been explicitly marked unavailable here}}
37+
get { fatalError() } // expected-note 28 {{getter for 'unavailableGetter' has been explicitly marked unavailable here}}
3838
set {}
3939
}
4040

4141
var unavailableSetter: Value {
4242
get { .defaultValue }
4343
@available(*, unavailable)
44-
set { fatalError() } // expected-note 12 {{setter for 'unavailableSetter' has been explicitly marked unavailable here}}
44+
set { fatalError() } // expected-note 16 {{setter for 'unavailableSetter' has been explicitly marked unavailable here}}
4545
}
4646

4747
var unavailableGetterAndSetter: Value {
4848
@available(*, unavailable)
49-
get { fatalError() } // expected-note 24 {{getter for 'unavailableGetterAndSetter' has been explicitly marked unavailable here}}
49+
get { fatalError() } // expected-note 28 {{getter for 'unavailableGetterAndSetter' has been explicitly marked unavailable here}}
5050
@available(*, unavailable)
51-
set { fatalError() } // expected-note 12 {{setter for 'unavailableGetterAndSetter' has been explicitly marked unavailable here}}
51+
set { fatalError() } // expected-note 16 {{setter for 'unavailableGetterAndSetter' has been explicitly marked unavailable here}}
5252
}
5353
}
5454

@@ -117,10 +117,10 @@ func testKeyPathLoads() {
117117
_ = a[keyPath: \.[takesIntInOut(&x.available.a.b)]]
118118
_ = a[keyPath: \.[takesIntInOut(&x.available[0].b)]]
119119

120-
_ = x[keyPath: \.unavailableGetter] // FIXME: missing diagnostic for getter
121-
_ = x[keyPath: \.unavailableGetter.a] // FIXME: missing diagnostic for getter
122-
_ = x[keyPath: \.unavailableGetter[0]] // FIXME: missing diagnostic for getter
123-
_ = x[keyPath: \.unavailableGetter[0].b] // FIXME: missing diagnostic for getter
120+
_ = x[keyPath: \.unavailableGetter] // expected-error {{getter for 'unavailableGetter' is unavailable}}
121+
_ = x[keyPath: \.unavailableGetter.a] // expected-error {{getter for 'unavailableGetter' is unavailable}}
122+
_ = x[keyPath: \.unavailableGetter[0]] // expected-error {{getter for 'unavailableGetter' is unavailable}}
123+
_ = x[keyPath: \.unavailableGetter[0].b] // expected-error {{getter for 'unavailableGetter' is unavailable}}
124124
_ = a[keyPath: \.[takesIntInOut(&x.unavailableGetter.a.b)]] // expected-error {{getter for 'unavailableGetter' is unavailable}}
125125
_ = a[keyPath: \.[takesIntInOut(&x.unavailableGetter[0].b)]] // expected-error {{getter for 'unavailableGetter' is unavailable}}
126126

@@ -131,10 +131,10 @@ func testKeyPathLoads() {
131131
_ = a[keyPath: \.[takesIntInOut(&x.unavailableSetter.a.b)]] // FIXME: missing diagnostic for setter
132132
_ = a[keyPath: \.[takesIntInOut(&x.unavailableSetter[0].b)]] // expected-error {{setter for 'unavailableSetter' is unavailable}}
133133

134-
_ = x[keyPath: \.unavailableGetterAndSetter] // FIXME: missing diagnostic for getter
135-
_ = x[keyPath: \.unavailableGetterAndSetter.a] // FIXME: missing diagnostic for getter
136-
_ = x[keyPath: \.unavailableGetterAndSetter[0]] // FIXME: missing diagnostic for getter
137-
_ = x[keyPath: \.unavailableGetterAndSetter[0].b] // FIXME: missing diagnostic for getter
134+
_ = x[keyPath: \.unavailableGetterAndSetter] // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}}
135+
_ = x[keyPath: \.unavailableGetterAndSetter.a] // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}}
136+
_ = x[keyPath: \.unavailableGetterAndSetter[0]] // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}}
137+
_ = x[keyPath: \.unavailableGetterAndSetter[0].b] // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}}
138138
_ = a[keyPath: \.[takesIntInOut(&x.unavailableGetterAndSetter.a.b)]] // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} FIXME: missing diagnostic for setter
139139
_ = a[keyPath: \.[takesIntInOut(&x.unavailableGetterAndSetter[0].b)]] // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
140140
}
@@ -158,17 +158,17 @@ func testKeyPathAssignments() {
158158
a[keyPath: \.[takesIntInOut(&x.unavailableGetter.a.b)]] = 0 // expected-error {{getter for 'unavailableGetter' is unavailable}}
159159
a[keyPath: \.[takesIntInOut(&x.unavailableGetter[0].b)]] = 0 // expected-error {{getter for 'unavailableGetter' is unavailable}}
160160

161-
x[keyPath: \.unavailableSetter] = someValue
162-
x[keyPath: \.unavailableSetter.a] = someValue.a // FIXME: missing diagnostic for setter
163-
x[keyPath: \.unavailableSetter[0]] = someValue.a // FIXME: missing diagnostic for setter
164-
x[keyPath: \.unavailableSetter[0].b] = 1 // FIXME: missing diagnostic for setter
161+
x[keyPath: \.unavailableSetter] = someValue // expected-error {{setter for 'unavailableSetter' is unavailable}}
162+
x[keyPath: \.unavailableSetter.a] = someValue.a // expected-error {{setter for 'unavailableSetter' is unavailable}}
163+
x[keyPath: \.unavailableSetter[0]] = someValue.a // expected-error {{setter for 'unavailableSetter' is unavailable}}
164+
x[keyPath: \.unavailableSetter[0].b] = 1 // expected-error {{setter for 'unavailableSetter' is unavailable}}
165165
a[keyPath: \.[takesIntInOut(&x.unavailableSetter.a.b)]] = 0 // FIXME: missing diagnostic for setter
166166
a[keyPath: \.[takesIntInOut(&x.unavailableSetter[0].b)]] = 0 // expected-error {{setter for 'unavailableSetter' is unavailable}}
167167

168-
x[keyPath: \.unavailableGetterAndSetter] = someValue
169-
x[keyPath: \.unavailableGetterAndSetter.a] = someValue.a // FIXME: missing diagnostics for getter and setter
170-
x[keyPath: \.unavailableGetterAndSetter[0]] = someValue.a // FIXME: missing diagnostics for getter and setter
171-
x[keyPath: \.unavailableGetterAndSetter[0].b] = 1 // FIXME: missing diagnostics for getter and setter
168+
x[keyPath: \.unavailableGetterAndSetter] = someValue // expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
169+
x[keyPath: \.unavailableGetterAndSetter.a] = someValue.a // expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
170+
x[keyPath: \.unavailableGetterAndSetter[0]] = someValue.a // expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
171+
x[keyPath: \.unavailableGetterAndSetter[0].b] = 1 // expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
172172
a[keyPath: \.[takesIntInOut(&x.unavailableGetterAndSetter.a.b)]] = 0 // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} FIXME: missing diagnostic for setter
173173
a[keyPath: \.[takesIntInOut(&x.unavailableGetterAndSetter[0].b)]] = 0 // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
174174
}

0 commit comments

Comments
 (0)