Skip to content

Commit 2f0750a

Browse files
committed
Let protocols define getter requirements for @_staticExclusiveOnly types
1 parent 3ccbcfe commit 2f0750a

File tree

3 files changed

+43
-4
lines changed

3 files changed

+43
-4
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1995,6 +1995,8 @@ ERROR(attr_static_exclusive_only_let_only_param,none,
19951995
"parameter of type %0 must be declared as either 'borrowing' or 'consuming'", (Type))
19961996
ERROR(attr_static_exclusive_only_mutating,none,
19971997
"type %0 cannot have mutating function %1", (Type, ValueDecl *))
1998+
ERROR(attr_static_exclusive_no_setters,none,
1999+
"varaible of type %0 must not have a setter", (Type))
19982000

19992001
// @extractConstantsFromMembers
20002002
ERROR(attr_extractConstantsFromMembers_experimental,none,

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2589,13 +2589,14 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
25892589

25902590
TypeChecker::checkDeclAttributes(VD);
25912591

2592+
auto DC = VD->getDeclContext();
2593+
25922594
if (!checkOverrides(VD)) {
25932595
// If a property has an override attribute but does not override
25942596
// anything, complain.
25952597
auto overridden = VD->getOverriddenDecl();
25962598
if (auto *OA = VD->getAttrs().getAttribute<OverrideAttr>()) {
25972599
if (!overridden) {
2598-
auto DC = VD->getDeclContext();
25992600
auto isClassContext = DC->getSelfClassDecl() != nullptr;
26002601
auto isStructOrEnumContext = DC->getSelfEnumDecl() != nullptr ||
26012602
DC->getSelfStructDecl() != nullptr;
@@ -2650,10 +2651,22 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
26502651

26512652
// @_staticExclusiveOnly types cannot be put into 'var's, only 'let'.
26522653
if (auto SD = VD->getInterfaceType()->getStructOrBoundGenericStruct()) {
2653-
if (SD->getAttrs().hasAttribute<StaticExclusiveOnlyAttr>() &&
2654-
!VD->isLet()) {
2654+
if (SD->getAttrs().hasAttribute<StaticExclusiveOnlyAttr>()) {
2655+
auto isProtocolContext = DC->getSelfProtocolDecl() != nullptr;
2656+
2657+
if (isProtocolContext && !VD->supportsMutation()) {
2658+
return;
2659+
}
2660+
2661+
if (VD->isLet()) {
2662+
return;
2663+
}
2664+
2665+
auto diagMsg = isProtocolContext ? diag::attr_static_exclusive_no_setters
2666+
: diag::attr_static_exclusive_only_let_only;
2667+
26552668
Ctx.Diags.diagnoseWithNotes(
2656-
VD->diagnose(diag::attr_static_exclusive_only_let_only,
2669+
VD->diagnose(diagMsg,
26572670
VD->getInterfaceType()),
26582671
[&]() {
26592672
SD->diagnose(diag::attr_static_exclusive_only_type_nonmutating,

test/attr/attr_static_exclusive_only.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ struct B: ~Copyable { // expected-note {{'B' is a non-mutable type}}
99
// expected-note@-2 {{'B' is a non-mutable type}}
1010
// expected-note@-3 {{'B' is a non-mutable type}}
1111
// expected-note@-4 {{'B' is a non-mutable type}}
12+
// expected-note@-5 {{'B' is a non-mutable type}}
13+
// expected-note@-6 {{'B' is a non-mutable type}}
1214
mutating func change() { // expected-error {{type 'B' cannot have mutating function 'change()'}}
1315
print("123")
1416
}
@@ -68,3 +70,25 @@ func p(_: (consuming B) -> ()) {} // OK
6870
struct Q<T>: ~Copyable {} // expected-note {{'Q<T>' is a non-mutable type}}
6971

7072
var r0 = Q<Int>() // expected-error {{variable of type 'Q<Int>' must be declared with a 'let'}}
73+
74+
protocol S {
75+
var t0: B { get } // OK
76+
77+
var t1: B { get set } // expected-error {{varaible of type 'B' must not have a setter}}
78+
}
79+
80+
protocol U: ~Copyable {
81+
var v: B { get } // OK
82+
}
83+
84+
struct W: ~Copyable {}
85+
86+
extension W: U {
87+
var v: B { // expected-error {{variable of type 'B' must be declared with a 'let'}}
88+
B()
89+
}
90+
}
91+
92+
struct X: ~Copyable, U {
93+
let v: B // OK
94+
}

0 commit comments

Comments
 (0)