Skip to content

Commit 5618121

Browse files
committed
Ban @abi on multi-var PBDs
Per a comment in the review thread that the comma in a multi-variable pattern binding makes it look like the `@abi` attribute has several arguments.
1 parent c78b64f commit 5618121

File tree

3 files changed

+25
-57
lines changed

3 files changed

+25
-57
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8468,14 +8468,10 @@ ERROR(attr_abi_mismatched_async,none,
84688468
"cannot give %0 the ABI of %select{a non-async|an async}1 %kindonly0",
84698469
(Decl *, /*abiIsAsync=*/bool))
84708470

8471-
ERROR(attr_abi_mismatched_pbd_size,none,
8472-
"cannot give pattern binding the ABI of a binding with "
8473-
"%select{more|fewer}0 patterns",
8474-
(/*abiHasExtra=*/bool))
8475-
8476-
ERROR(attr_abi_mismatched_var,none,
8477-
"no match for %select{%kind0 in the ABI|ABI %kind0}1",
8478-
(Decl *, /*isABI=*/bool))
8471+
ERROR(attr_abi_multiple_vars,none,
8472+
"'abi' attribute can only be applied to a single %0; declare each "
8473+
"%0 separately",
8474+
(DescriptiveDeclKind))
84798475

84808476
ERROR(attr_abi_incompatible_with_silgen_name,none,
84818477
"cannot use '@_silgen_name' and '@abi' on the same %kindonly0 because "

lib/Sema/TypeCheckAttrABI.cpp

Lines changed: 12 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,60 +1102,29 @@ class ABIDeclChecker : public ASTComparisonVisitor<ABIDeclChecker> {
11021102
};
11031103

11041104
void checkABIAttrPBD(PatternBindingDecl *APBD, VarDecl *VD) {
1105-
auto &diags = VD->getASTContext().Diags;
11061105
auto PBD = VD->getParentPatternBinding();
11071106

1108-
// To make sure we only diagnose this stuff once, check that VD is the first
1109-
// anchoring variable in the PBD.
1110-
bool isFirstAnchor = false;
1107+
Decl *anchorVD = nullptr;
11111108
for (auto i : range(PBD->getNumPatternEntries())) {
1112-
auto anchorVD = PBD->getAnchoringVarDecl(i);
1113-
if (anchorVD) {
1114-
isFirstAnchor = (anchorVD == VD);
1109+
anchorVD = PBD->getAnchoringVarDecl(i);
1110+
if (anchorVD)
11151111
break;
1116-
}
11171112
}
11181113

1119-
if (!isFirstAnchor)
1114+
// To make sure we only diagnose this stuff once, check that VD is the
1115+
// first anchoring variable in the PBD.
1116+
if (anchorVD != VD)
11201117
return;
11211118

1122-
// Check that the PBDs have the same number of patterns.
1123-
if (PBD->getNumPatternEntries() < APBD->getNumPatternEntries()) {
1124-
diags.diagnose(APBD->getPattern(PBD->getNumPatternEntries())->getLoc(),
1125-
diag::attr_abi_mismatched_pbd_size, /*abiHasExtra=*/false);
1126-
return;
1127-
}
1128-
if (PBD->getNumPatternEntries() > APBD->getNumPatternEntries()) {
1129-
diags.diagnose(PBD->getPattern(APBD->getNumPatternEntries())->getLoc(),
1130-
diag::attr_abi_mismatched_pbd_size, /*abiHasExtra=*/true);
1119+
// In the final approved feature, we only permit single-variable patterns.
1120+
// (However, the rest of the compiler tolerates them.)
1121+
if (!PBD->getSingleVar() || !APBD->getSingleVar()) {
1122+
PBD->diagnose(diag::attr_abi_multiple_vars,
1123+
anchorVD ? anchorVD->getDescriptiveKind()
1124+
: PBD->getDescriptiveKind());
11311125
return;
11321126
}
11331127

1134-
// Check that each pattern has the same number of variables.
1135-
bool didDiagnose = false;
1136-
for (auto i : range(PBD->getNumPatternEntries())) {
1137-
SmallVector<VarDecl *, 8> VDs;
1138-
SmallVector<VarDecl *, 8> AVDs;
1139-
1140-
PBD->getPattern(i)->collectVariables(VDs);
1141-
APBD->getPattern(i)->collectVariables(AVDs);
1142-
1143-
if (VDs.size() < AVDs.size()) {
1144-
for (auto AVD : drop_begin(AVDs, VDs.size())) {
1145-
AVD->diagnose(diag::attr_abi_mismatched_var, AVD, /*isABI=*/true);
1146-
didDiagnose = true;
1147-
}
1148-
}
1149-
else if (VDs.size() > AVDs.size()) {
1150-
for (auto VD : drop_begin(VDs, AVDs.size())) {
1151-
VD->diagnose(diag::attr_abi_mismatched_var, VD, /*isABI=*/false);
1152-
didDiagnose = true;
1153-
}
1154-
}
1155-
}
1156-
if (didDiagnose)
1157-
return;
1158-
11591128
// Check the ABI PBD--this is what checks the underlying vars.
11601129
TypeChecker::typeCheckDecl(APBD);
11611130
}

test/attr/attr_abi.swift

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -279,17 +279,20 @@ var async11Var: Int { get async { fatalError() } }
279279
// PBD shape checking
280280
//
281281
282-
@abi(var x1, y1: Int) // expected-error {{cannot give pattern binding the ABI of a binding with more patterns}}
283-
var x1: Int = 0
282+
@abi(var x1, y1: Int)
283+
var x1: Int = 0 // expected-error {{'abi' attribute can only be applied to a single var; declare each var separately}}
284284
285285
@abi(var x2: Int)
286-
var x2 = 0, y2: Int = 0 // expected-error {{cannot give pattern binding the ABI of a binding with fewer patterns}}
286+
var x2 = 0, y2: Int = 0 // expected-error {{'abi' attribute can only be applied to a single var; declare each var separately}}
287287
288-
@abi(var (x3, y3): (Int, Int), (a3, b3): (Int, Int)) // expected-error {{no match for ABI var 'b3'}}
289-
var (x3, y3): (Int, Int) = (0, 0), a3: Int = 0
288+
@abi(var (x3, y3): (Int, Int), (a3, b3): (Int, Int))
289+
var (x3, y3): (Int, Int) = (0, 0), a3: Int = 0 // expected-error {{'abi' attribute can only be applied to a single var; declare each var separately}}
290290
291291
@abi(var (x4, y4): (Int, Int), a4: Int)
292-
var (x4, y4): (Int, Int) = (0, 0), (a4, b4): (Int, Int) = (0, 0) // expected-error {{no match for var 'b4' in the ABI}}
292+
var (x4, y4): (Int, Int) = (0, 0), (a4, b4): (Int, Int) = (0, 0) // expected-error {{'abi' attribute can only be applied to a single var; declare each var separately}}
293+
294+
@abi(var x5: Int)
295+
var x5: Int = 0
293296
294297
//
295298
// Redeclaration diagnostics

0 commit comments

Comments
 (0)