Skip to content

Commit 6007e78

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 c39e9eb commit 6007e78

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
@@ -8434,14 +8434,10 @@ ERROR(attr_abi_mismatched_async,none,
84348434
"cannot give %0 the ABI of %select{a non-async|an async}1 %kindonly0",
84358435
(Decl *, /*abiIsAsync=*/bool))
84368436

8437-
ERROR(attr_abi_mismatched_pbd_size,none,
8438-
"cannot give pattern binding the ABI of a binding with "
8439-
"%select{more|fewer}0 patterns",
8440-
(/*abiHasExtra=*/bool))
8441-
8442-
ERROR(attr_abi_mismatched_var,none,
8443-
"no match for %select{%kind0 in the ABI|ABI %kind0}1",
8444-
(Decl *, /*isABI=*/bool))
8437+
ERROR(attr_abi_multiple_vars,none,
8438+
"'abi' attribute can only be applied to a single %0; declare each "
8439+
"%0 separately",
8440+
(DescriptiveDeclKind))
84458441

84468442
ERROR(attr_abi_incompatible_with_silgen_name,none,
84478443
"cannot use '@_silgen_name' and '@abi' on the same %0 because they serve "

lib/Sema/TypeCheckAttrABI.cpp

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

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

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

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

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

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

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)