Skip to content

Commit b6a614c

Browse files
authored
Merge pull request #36499 from ahoppen/pr/rdar64319340
[Sema] Correctly diagnose passing tuple as only argument to function with multiple parameters
2 parents 4dbfb8a + fa9f3f3 commit b6a614c

File tree

3 files changed

+39
-11
lines changed

3 files changed

+39
-11
lines changed

lib/Sema/MiscDiagnostics.cpp

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1847,28 +1847,45 @@ bool swift::diagnoseArgumentLabelError(ASTContext &ctx,
18471847
llvm::SmallString<16> missingBuffer;
18481848
llvm::SmallString<16> extraBuffer;
18491849
for (unsigned i = 0; i != n; ++i) {
1850-
Identifier oldName;
1850+
// oldName and newName are
1851+
// - None if i is out of bounds for the argument list
1852+
// - nullptr for an argument without a label
1853+
// - have a value if the argument has a label
1854+
Optional<Identifier> oldName;
18511855
if (i < argList.args.size())
18521856
oldName = argList.labels[i];
1853-
Identifier newName;
1857+
Optional<Identifier> newName;
18541858
if (i < newNames.size())
18551859
newName = newNames[i];
18561860

1861+
assert(oldName || newName && "We can't have oldName and newName out of "
1862+
"bounds, otherwise n would be smaller");
1863+
18571864
if (oldName == newName ||
1858-
(argList.hasTrailingClosure && i == argList.args.size()-1 &&
1865+
(argList.hasTrailingClosure && i == argList.args.size() - 1 &&
18591866
(numMissing > 0 || numExtra > 0 || numWrong > 0)))
18601867
continue;
18611868

1862-
if (oldName.empty()) {
1869+
if (!oldName.hasValue() && newName.hasValue()) {
1870+
++numMissing;
1871+
missingBuffer += newName->str();
1872+
missingBuffer += ':';
1873+
} else if (oldName.hasValue() && !newName.hasValue()) {
1874+
++numExtra;
1875+
extraBuffer += oldName->str();
1876+
extraBuffer += ':';
1877+
} else if (oldName->empty()) {
1878+
// In the cases from here onwards oldValue and newValue are not null
18631879
++numMissing;
1864-
missingBuffer += newName.str();
1880+
missingBuffer += newName->str();
18651881
missingBuffer += ":";
1866-
} else if (newName.empty()) {
1882+
} else if (newName->empty()) {
18671883
++numExtra;
1868-
extraBuffer += oldName.str();
1884+
extraBuffer += oldName->str();
18691885
extraBuffer += ':';
1870-
} else
1886+
} else {
18711887
++numWrong;
1888+
}
18721889
}
18731890

18741891
// Emit the diagnostic.

test/Constraints/argument_matching.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,7 +1086,7 @@ func testUnlabeledParameterBindingPosition() {
10861086
func f(aa: Int, bb: Int, _ cc: Int) {}
10871087

10881088
f(0, 2)
1089-
// expected-error@-1:6 {{missing argument labels 'aa:bb:' in call}}
1089+
// expected-error@-1:6 {{missing argument labels 'aa:bb::' in call}}
10901090
// expected-error@-2:8 {{missing argument for parameter 'bb' in call}}
10911091

10921092
f(0, bb: 1, 2)
@@ -1191,7 +1191,7 @@ func testUnlabeledParameterBindingPosition() {
11911191
// expected-error@-1:6 {{missing arguments for parameters 'aa', 'cc' in call}}
11921192

11931193
f(1, 2, 3)
1194-
// expected-error@-1 {{missing argument labels 'aa:cc:' in call}}
1194+
// expected-error@-1 {{missing argument labels 'aa:cc::' in call}}
11951195
// expected-error@-2:11 {{missing argument for parameter 'cc' in call}}
11961196

11971197
f(1, 2, 3, 4)
@@ -1223,7 +1223,7 @@ func testUnlabeledParameterBindingPosition() {
12231223
// expected-error@-1:12 {{missing argument for parameter 'bb' in call}}
12241224

12251225
f(aa: 1, xx: 2, 3)
1226-
// expected-error@-1 {{incorrect argument label in call (have 'aa:xx:_:', expected 'aa:bb:_:_:')}}
1226+
// expected-error@-1 {{incorrect argument labels in call (have 'aa:xx:_:', expected 'aa:bb:_:_:')}}
12271227
// expected-error@-2:12 {{missing argument for parameter 'bb' in call}}
12281228

12291229
f(aa: 1, bb: 2, 3, xx: 4)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
func twoArgs(_ a: Int, _ b: Int) -> Void { //expected-note{{'twoArgs' declared here}}
4+
}
5+
6+
func call() {
7+
// Call a function that takes two unnamed arguments with a tuple that has two
8+
// named arguments
9+
let namedTuple: (x: Int, y: Int) = (1, 1)
10+
twoArgs(namedTuple) // expected-error{{global function 'twoArgs' expects 2 separate arguments}} expected-error{{missing argument label ':' in call}}
11+
}

0 commit comments

Comments
 (0)