Skip to content

Commit d227636

Browse files
committed
Support @abi on subscripts
And make sure we reject it on `deinit`s and accessors.
1 parent 132f491 commit d227636

File tree

4 files changed

+84
-9
lines changed

4 files changed

+84
-9
lines changed

include/swift/AST/DeclAttr.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -857,7 +857,7 @@ SIMPLE_DECL_ATTR(safe, Safe,
857857
164)
858858

859859
DECL_ATTR(abi, ABI,
860-
OnAbstractFunction | OnVar,
860+
OnConstructor | OnFunc | OnSubscript | OnVar,
861861
LongAttribute | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove | ForbiddenInABIAttr,
862862
165)
863863
DECL_ATTR_FEATURE_REQUIREMENT(ABI, ABIAttribute)

lib/AST/NameLookup.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1546,7 +1546,7 @@ void MemberLookupTable::addMember(Decl *member) {
15461546
A->getMemberName().addToLookupTable(Lookup, vd);
15471547

15481548
auto abiRole = ABIRoleInfo(vd);
1549-
if (!abiRole.providesABI())
1549+
if (!abiRole.providesABI() && abiRole.getCounterpart())
15501550
addMember(abiRole.getCounterpart());
15511551
}
15521552

lib/Parse/ParseDecl.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9776,10 +9776,23 @@ Parser::parseDeclSubscript(SourceLoc StaticLoc,
97769776

97779777
Decls.push_back(Subscript);
97789778

9779+
bool Invalid = false;
9780+
// Reject 'subscript' functions outside of type decls
9781+
if (!(Flags & PD_HasContainerType)) {
9782+
diagnose(SubscriptLoc, diag::subscript_decl_wrong_scope);
9783+
Invalid = true;
9784+
}
9785+
97799786
// '{'
97809787
// Parse getter and setter.
97819788
ParsedAccessors accessors;
97829789
if (Tok.isNot(tok::l_brace)) {
9790+
// Subscript stubs should never have accessors, and this one doesn't, so
9791+
// we're done.
9792+
if (Flags.contains(PD_StubOnly)) {
9793+
return makeParserResult(Status, Subscript);
9794+
}
9795+
97839796
// Subscript declarations must always have at least a getter, so they need
97849797
// to be followed by a {.
97859798
if (!Status.isErrorOrHasCompletion()) {
@@ -9796,13 +9809,6 @@ Parser::parseDeclSubscript(SourceLoc StaticLoc,
97969809
Subscript);
97979810
}
97989811

9799-
bool Invalid = false;
9800-
// Reject 'subscript' functions outside of type decls
9801-
if (!(Flags & PD_HasContainerType)) {
9802-
diagnose(SubscriptLoc, diag::subscript_decl_wrong_scope);
9803-
Invalid = true;
9804-
}
9805-
98069812
accessors.record(*this, Subscript, (Invalid || !Status.isSuccess() ||
98079813
Status.hasCodeCompletion()));
98089814

test/attr/attr_abi.swift

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,23 @@ var funcForVar: Int = 0
3333
@abi(var varForFunc_abi: Int) // expected-error {{cannot give global function 'varForFunc()' the ABI of a pattern binding}}
3434
func varForFunc() {}
3535

36+
struct SameKind {
37+
@abi(subscript(sub1 _: Int) -> Int)
38+
subscript(sub1 _: Int) -> Int { 0 }
39+
40+
@abi(func sub2(_: Int) -> Int) // expected-error {{cannot give subscript 'subscript(sub2:)' the ABI of a instance method}}
41+
subscript(sub2 _: Int) -> Int { 0 }
42+
43+
@abi(subscript(sub3 _: Int) -> Int) // expected-error {{cannot give instance method 'sub3' the ABI of a subscript}}
44+
func sub3(_: Int) -> Int { 0 }
45+
46+
@abi(var sub4: Int) // expected-error {{cannot give subscript 'subscript(sub4:)' the ABI of a pattern binding}}
47+
subscript(sub4 _: Int) -> Int { 0 }
48+
49+
@abi(subscript(sub4 _: Int) -> Int) // expected-error {{cannot give property 'sub4' the ABI of a subscript}}
50+
var sub4: Int { 0 }
51+
}
52+
3653
//
3754
// Function arity checking
3855
//
@@ -91,6 +108,58 @@ func param01_generic11<T>(_: Int) -> T { fatalError() }
91108
@abi(func param11_generic11<T>(_: Int) -> T)
92109
func param11_generic11<T>(_: Int) -> T { fatalError() }
93110

111+
112+
113+
struct SubscriptArity {
114+
@abi(subscript(param11_generic00 _: Int) -> Int)
115+
subscript(param11_generic00 _: Int) -> Int { 0 }
116+
117+
@abi(subscript(param21_generic00 _: Int, _: Int) -> Int) // expected-error {{cannot give subscript 'subscript(param21_generic00:)' the ABI of a subscript with a different number of parameters}}
118+
subscript(param21_generic00 _: Int) -> Int { 0 }
119+
120+
@abi(subscript(param12_generic00 _: Int) -> Int) // expected-error {{cannot give subscript 'subscript(param12_generic00:_:)' the ABI of a subscript with a different number of parameters}}
121+
subscript(param12_generic00 _: Int, _: Int) -> Int { 0 }
122+
123+
@abi(subscript(param22_generic00 _: Int, _: Int) -> Int)
124+
subscript(param22_generic00 _: Int, _: Int) -> Int { 0 }
125+
126+
@abi(subscript<T>(param11_generic10 _: T) -> Int) // expected-error {{declaration in '@abi' should not have generic signature because 'subscript(param11_generic10:)' is not generic}}
127+
subscript(param11_generic10 _: Int) -> Int { 0 }
128+
129+
@abi(subscript<T>(param21_generic10 _: T, _: Int) -> Int) // expected-error {{declaration in '@abi' should not have generic signature because 'subscript(param21_generic10:)' is not generic}}
130+
subscript(param21_generic10 _: Int) -> Int { 0 }
131+
132+
@abi(subscript<T>(param12_generic10 _: T) -> Int) // expected-error {{declaration in '@abi' should not have generic signature because 'subscript(param12_generic10:_:)' is not generic}}
133+
subscript(param12_generic10 _: Int, _: Int) -> Int { 0 }
134+
135+
@abi(subscript<T>(param22_generic10 _: T, _: Int) -> Int) // expected-error {{declaration in '@abi' should not have generic signature because 'subscript(param22_generic10:_:)' is not generic}}
136+
subscript(param22_generic10 _: Int, _: Int) -> Int { 0 }
137+
138+
@abi(subscript(param11_generic01 _: Int) -> Int) // expected-error {{declaration in '@abi' should have generic signature compatible with '<T where T : Copyable, T : Escapable>'}}
139+
subscript<T>(param11_generic01 _: T) -> Int { 0 }
140+
141+
@abi(subscript(param21_generic01 _: Int, _: Int) -> Int) // expected-error {{declaration in '@abi' should have generic signature compatible with '<T where T : Copyable, T : Escapable>'}}
142+
subscript<T>(param21_generic01 _: T) -> Int { 0 }
143+
144+
@abi(subscript(param12_generic01 _: Int) -> Int) // expected-error {{declaration in '@abi' should have generic signature compatible with '<T where T : Copyable, T : Escapable>'}}
145+
subscript<T>(param12_generic01 _: T, _: Int) -> Int { 0 }
146+
147+
@abi(subscript(param22_generic01 _: Int, _: Int) -> Int) // expected-error {{declaration in '@abi' should have generic signature compatible with '<T where T : Copyable, T : Escapable>'}}
148+
subscript<T>(param22_generic01 _: T, _: Int) -> Int { 0 }
149+
150+
@abi(subscript<T>(param11_generic11 _: T) -> Int)
151+
subscript<T>(param11_generic11 _: T) -> Int { 0 }
152+
153+
@abi(subscript<T>(param21_generic11 _: T, _: Int) -> Int) // expected-error {{cannot give subscript 'subscript(param21_generic11:)' the ABI of a subscript with a different number of parameters}}
154+
subscript<T>(param21_generic11 _: T) -> Int { 0 }
155+
156+
@abi(subscript<T>(param12_generic11 _: T) -> Int) // expected-error {{cannot give subscript 'subscript(param12_generic11:_:)' the ABI of a subscript with a different number of parameters}}
157+
subscript<T>(param12_generic11 _: T, _: Int) -> Int { 0 }
158+
159+
@abi(subscript<T>(param22_generic11 _: T, _: Int) -> Int)
160+
subscript<T>(param22_generic11 _: T, _: Int) -> Int { 0 }
161+
}
162+
94163
//
95164
// Throws effect checking
96165
//

0 commit comments

Comments
 (0)