Skip to content

Commit 7d6dac6

Browse files
committed
[Sema] Correct label fix-its for multiple trailing closures
Update the logic to account for multiple trailing closures. rdar://81278194
1 parent 51535fc commit 7d6dac6

File tree

2 files changed

+17
-11
lines changed

2 files changed

+17
-11
lines changed

lib/Sema/MiscDiagnostics.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1906,9 +1906,7 @@ bool swift::diagnoseArgumentLabelError(ASTContext &ctx,
19061906
assert(oldName || newName && "We can't have oldName and newName out of "
19071907
"bounds, otherwise n would be smaller");
19081908

1909-
if (oldName == newName ||
1910-
(argList.hasTrailingClosure && i == argList.args.size() - 1 &&
1911-
(numMissing > 0 || numExtra > 0 || numWrong > 0)))
1909+
if (oldName == newName || argList.isUnlabeledTrailingClosureIdx(i))
19121910
continue;
19131911

19141912
if (!oldName.hasValue() && newName.hasValue()) {
@@ -1988,11 +1986,17 @@ bool swift::diagnoseArgumentLabelError(ASTContext &ctx,
19881986
if (i < newNames.size())
19891987
newName = newNames[i];
19901988

1991-
if (oldName == newName || (i == n-1 && argList.hasTrailingClosure))
1989+
if (oldName == newName || argList.isUnlabeledTrailingClosureIdx(i))
19921990
continue;
19931991

19941992
if (newName.empty()) {
1995-
// Delete the old name.
1993+
// If this is a labeled trailing closure, we need to replace with '_'.
1994+
if (argList.isLabeledTrailingClosureIdx(i)) {
1995+
diag.fixItReplace(argList.labelLocs[i], "_");
1996+
continue;
1997+
}
1998+
1999+
// Otherwise, delete the old name.
19962000
diag.fixItRemoveChars(argList.labelLocs[i],
19972001
argList.args[i]->getStartLoc());
19982002
continue;
@@ -2006,7 +2010,10 @@ bool swift::diagnoseArgumentLabelError(ASTContext &ctx,
20062010
if (newNameIsReserved)
20072011
newStr += "`";
20082012

2009-
if (oldName.empty()) {
2013+
// If the argument was previously unlabeled, insert the new label. Note that
2014+
// we don't do this for labeled trailing closures as they write unlabeled
2015+
// args as '_:', and therefore need replacement.
2016+
if (oldName.empty() && !argList.isLabeledTrailingClosureIdx(i)) {
20102017
// Insert the name.
20112018
newStr += ": ";
20122019
diag.fixItInsert(argList.args[i]->getStartLoc(), newStr);

test/Parse/trailing_closures.swift

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ func test_multiple_trailing_syntax_without_labels() {
8282

8383
fn {} g: {} // Ok
8484

85-
fn {} _: {} // expected-error {{missing argument labels 'f:g:' in call}}
85+
fn {} _: {} // expected-error {{missing argument label 'g:' in call}} {{9-10=g}} {{none}}
8686

8787
fn {} g: <#T##() -> Void#> // expected-error {{editor placeholder in source file}}
8888

@@ -95,14 +95,13 @@ func test_multiple_trailing_syntax_without_labels() {
9595

9696
mixed_args_1 {} _: {}
9797

98-
mixed_args_1 {} a: {} // expected-error@:16 {{incorrect argument labels in call (have '_:a:', expected 'a:_:')}}
98+
mixed_args_1 {} a: {} // expected-error@:16 {{extraneous argument label 'a:' in call}} {{19-20=_}} {{none}}
9999

100100
mixed_args_2 {} a: {} _: {}
101101

102-
mixed_args_2 {} _: {} // expected-error@:18 {{missing argument for parameter 'a' in call}}
102+
mixed_args_2 {} _: {} // expected-error@:18 {{missing argument for parameter 'a' in call}} {{18-18= a: <#() -> Void#>}} {{none}}
103103

104-
// FIXME: not a good diagnostic
105-
mixed_args_2 {} _: {} _: {} // expected-error@:16 {{missing argument label 'a:' in call}}
104+
mixed_args_2 {} _: {} _: {} // expected-error@:16 {{missing argument label 'a:' in call}} {{19-20=a}} {{none}}
106105
}
107106

108107
func produce(fn: () -> Int?, default d: () -> Int) -> Int { // expected-note {{declared here}}

0 commit comments

Comments
 (0)