Skip to content

Commit c5908c1

Browse files
committed
Support @abi on subscripts
And make sure we reject it on `deinit`s and accessors.
1 parent 5655d14 commit c5908c1

File tree

4 files changed

+84
-9
lines changed

4 files changed

+84
-9
lines changed

include/swift/AST/DeclAttr.def

+1-1
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

+1-1
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

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

97579757
Decls.push_back(Subscript);
97589758

9759+
bool Invalid = false;
9760+
// Reject 'subscript' functions outside of type decls
9761+
if (!(Flags & PD_HasContainerType)) {
9762+
diagnose(SubscriptLoc, diag::subscript_decl_wrong_scope);
9763+
Invalid = true;
9764+
}
9765+
97599766
// '{'
97609767
// Parse getter and setter.
97619768
ParsedAccessors accessors;
97629769
if (Tok.isNot(tok::l_brace)) {
9770+
// Subscript stubs should never have accessors, and this one doesn't, so
9771+
// we're done.
9772+
if (Flags.contains(PD_StubOnly)) {
9773+
return makeParserResult(Status, Subscript);
9774+
}
9775+
97639776
// Subscript declarations must always have at least a getter, so they need
97649777
// to be followed by a {.
97659778
if (!Status.isErrorOrHasCompletion()) {
@@ -9776,13 +9789,6 @@ Parser::parseDeclSubscript(SourceLoc StaticLoc,
97769789
Subscript);
97779790
}
97789791

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-
97869792
accessors.record(*this, Subscript, (Invalid || !Status.isSuccess() ||
97879793
Status.hasCodeCompletion()));
97889794

test/attr/attr_abi.swift

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

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

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

0 commit comments

Comments
 (0)