Skip to content

Commit de90dec

Browse files
committed
Support @abi on subscripts
And make sure we reject it on `deinit`s and accessors.
1 parent 1822c33 commit de90dec

File tree

4 files changed

+85
-9
lines changed

4 files changed

+85
-9
lines changed

include/swift/AST/DeclAttr.def

+2-1
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,8 @@ SIMPLE_DECL_ATTR(safe, Safe,
538538
164)
539539

540540
DECL_ATTR(abi, ABI,
541-
OnAbstractFunction | OnVar /* will eventually add types */ | LongAttribute | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
541+
OnConstructor | OnFunc | OnSubscript | OnVar | LongAttribute |
542+
ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
542543
165)
543544
DECL_ATTR_FEATURE_REQUIREMENT(ABI, ABIAttribute)
544545

lib/AST/NameLookup.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1531,7 +1531,7 @@ void MemberLookupTable::addMember(Decl *member) {
15311531
A->getMemberName().addToLookupTable(Lookup, vd);
15321532

15331533
auto abiRole = ABIRoleInfo(vd);
1534-
if (!abiRole.providesABI())
1534+
if (!abiRole.providesABI() && abiRole.getCounterpart())
15351535
addMember(abiRole.getCounterpart());
15361536
}
15371537

lib/Parse/ParseDecl.cpp

+13-7
Original file line numberDiff line numberDiff line change
@@ -9727,10 +9727,23 @@ Parser::parseDeclSubscript(SourceLoc StaticLoc,
97279727

97289728
Decls.push_back(Subscript);
97299729

9730+
bool Invalid = false;
9731+
// Reject 'subscript' functions outside of type decls
9732+
if (!(Flags & PD_HasContainerType)) {
9733+
diagnose(SubscriptLoc, diag::subscript_decl_wrong_scope);
9734+
Invalid = true;
9735+
}
9736+
97309737
// '{'
97319738
// Parse getter and setter.
97329739
ParsedAccessors accessors;
97339740
if (Tok.isNot(tok::l_brace)) {
9741+
// Subscript stubs should never have accessors, and this one doesn't, so
9742+
// we're done.
9743+
if (Flags.contains(PD_StubOnly)) {
9744+
return makeParserResult(Status, Subscript);
9745+
}
9746+
97349747
// Subscript declarations must always have at least a getter, so they need
97359748
// to be followed by a {.
97369749
if (!Status.isErrorOrHasCompletion()) {
@@ -9747,13 +9760,6 @@ Parser::parseDeclSubscript(SourceLoc StaticLoc,
97479760
Subscript);
97489761
}
97499762

9750-
bool Invalid = false;
9751-
// Reject 'subscript' functions outside of type decls
9752-
if (!(Flags & PD_HasContainerType)) {
9753-
diagnose(SubscriptLoc, diag::subscript_decl_wrong_scope);
9754-
Invalid = true;
9755-
}
9756-
97579763
accessors.record(*this, Subscript, (Invalid || !Status.isSuccess() ||
97589764
Status.hasCodeCompletion()));
97599765

test/attr/attr_abi.swift

+69
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,23 @@ var funcForVar: Int = 0
3030
@abi(var varForFunc_abi: Int) // expected-error {{cannot give global function 'varForFunc()' the ABI of a pattern binding}}
3131
func varForFunc() {}
3232

33+
struct SameKind {
34+
@abi(subscript(sub1 _: Int) -> Int)
35+
subscript(sub1 _: Int) -> Int { 0 }
36+
37+
@abi(func sub2(_: Int) -> Int) // expected-error {{cannot give subscript 'subscript(sub2:)' the ABI of a instance method}}
38+
subscript(sub2 _: Int) -> Int { 0 }
39+
40+
@abi(subscript(sub3 _: Int) -> Int) // expected-error {{cannot give instance method 'sub3' the ABI of a subscript}}
41+
func sub3(_: Int) -> Int { 0 }
42+
43+
@abi(var sub4: Int) // expected-error {{cannot give subscript 'subscript(sub4:)' the ABI of a pattern binding}}
44+
subscript(sub4 _: Int) -> Int { 0 }
45+
46+
@abi(subscript(sub4 _: Int) -> Int) // expected-error {{cannot give property 'sub4' the ABI of a subscript}}
47+
var sub4: Int { 0 }
48+
}
49+
3350
//
3451
// Function arity checking
3552
//
@@ -88,6 +105,58 @@ func param01_generic11<T>(_: Int) -> T { fatalError() }
88105
@abi(func param11_generic11<T>(_: Int) -> T)
89106
func param11_generic11<T>(_: Int) -> T { fatalError() }
90107

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

0 commit comments

Comments
 (0)