Skip to content

Commit 51476cd

Browse files
committed
[Diagnostics] Clarify tuple splat message when single parameter is generic parameter
Since it's hard to say whether tuple use is really intended, let's add `did you mean to pass a tuple?` note to the error message.
1 parent c62c289 commit 51476cd

File tree

5 files changed

+49
-29
lines changed

5 files changed

+49
-29
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3493,6 +3493,8 @@ ERROR(single_tuple_parameter_mismatch_special,none,
34933493
ERROR(single_tuple_parameter_mismatch_normal,none,
34943494
"%0 %1 expects a single parameter of type %2%3",
34953495
(DescriptiveDeclKind, DeclBaseName, Type, StringRef))
3496+
NOTE(note_maybe_forgot_to_form_tuple,none,
3497+
"did you mean to pass a tuple?", ())
34963498
ERROR(unknown_single_tuple_parameter_mismatch,none,
34973499
"single parameter of type %0 is expected in call", (Type))
34983500
ERROR(cannot_convert_single_tuple_into_multiple_arguments,none,

lib/Sema/CSDiagnostics.cpp

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4880,16 +4880,17 @@ bool InvalidTupleSplatWithSingleParameterFailure::diagnoseAsError() {
48804880
? emitDiagnostic(argExpr->getLoc(),
48814881
diag::single_tuple_parameter_mismatch_special,
48824882
choice->getDescriptiveKind(), paramTy, subsStr)
4883-
: emitDiagnostic(
4884-
argExpr->getLoc(), diag::single_tuple_parameter_mismatch_normal,
4885-
choice->getDescriptiveKind(), name, paramTy, subsStr);
4883+
: emitDiagnostic(argExpr->getLoc(),
4884+
diag::single_tuple_parameter_mismatch_normal,
4885+
choice->getDescriptiveKind(), name, paramTy, subsStr);
4886+
48864887

48874888
auto newLeftParenLoc = argExpr->getStartLoc();
48884889
if (auto *TE = dyn_cast<TupleExpr>(argExpr)) {
48894890
auto firstArgLabel = TE->getElementName(0);
48904891
// Cover situations like:
48914892
//
4892-
// func foo<T>(x: T) {}
4893+
// func foo(x: (Int, Int)) {}
48934894
// foo(x: 0, 1)
48944895
//
48954896
// Where left paren should be suggested after the label,
@@ -4904,9 +4905,24 @@ bool InvalidTupleSplatWithSingleParameterFailure::diagnoseAsError() {
49044905
}
49054906
}
49064907

4907-
diagnostic.highlight(argExpr->getSourceRange())
4908-
.fixItInsertAfter(newLeftParenLoc, "(")
4909-
.fixItInsert(argExpr->getEndLoc(), ")");
4908+
// If the parameter is a generic parameter, it's hard to say
4909+
// whether use of a tuple is really intended here, so let's
4910+
// attach a fix-it to a note instead of the diagnostic message
4911+
// to indicate that it's not the only right solution possible.
4912+
if (auto *typeVar = ParamType->getAs<TypeVariableType>()) {
4913+
if (typeVar->getImpl().getGenericParameter()) {
4914+
diagnostic.flush();
4915+
4916+
emitDiagnostic(argExpr->getLoc(), diag::note_maybe_forgot_to_form_tuple)
4917+
.fixItInsertAfter(newLeftParenLoc, "(")
4918+
.fixItInsert(argExpr->getEndLoc(), ")");
4919+
}
4920+
} else {
4921+
diagnostic.highlight(argExpr->getSourceRange())
4922+
.fixItInsertAfter(newLeftParenLoc, "(")
4923+
.fixItInsert(argExpr->getEndLoc(), ")");
4924+
}
4925+
49104926
return true;
49114927
}
49124928

test/Constraints/enum_cases.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ enum E_32551313<L, R> {
104104

105105
struct Foo_32551313 {
106106
static func bar() -> E_32551313<(String, Foo_32551313?), (String, String)>? {
107-
return E_32551313.Left("", Foo_32551313()) // expected-error {{enum case 'Left' expects a single parameter of type 'L' [with L = (String, Foo_32551313?)]}} {{28-28=(}} {{46-46=)}}
107+
return E_32551313.Left("", Foo_32551313()) // expected-error {{enum case 'Left' expects a single parameter of type 'L' [with L = (String, Foo_32551313?)]}}
108+
// expected-note@-1 {{did you mean to pass a tuple?}} {{28-28=(}} {{46-46=)}}
108109
}
109110
}
110111

test/Constraints/tuple_arguments.swift

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,12 @@ func genericTuple<T, U>(_ x: (T, U)) {}
6969

7070
do {
7171
generic(3)
72-
generic(3, 4) // expected-error {{global function 'generic' expects a single parameter of type 'T' [with T = (Int, Int)]}} {{11-11=(}} {{15-15=)}}
72+
generic(3, 4) // expected-error {{global function 'generic' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{11-11=(}} {{15-15=)}}
7373
generic((3))
7474
generic((3, 4))
7575

7676
genericLabeled(x: 3)
77-
genericLabeled(x: 3, 4) // expected-error {{global function 'genericLabeled' expects a single parameter of type 'T' [with T = (Int, Int)]}} {{20-20=(}} {{25-25=)}}
77+
genericLabeled(x: 3, 4) // expected-error {{global function 'genericLabeled' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{20-20=(}} {{25-25=)}}
7878
genericLabeled(x: (3))
7979
genericLabeled(x: (3, 4))
8080

@@ -92,7 +92,7 @@ do {
9292
let d = (a, b)
9393

9494
generic(a)
95-
generic(a, b) // expected-error {{global function 'generic' expects a single parameter of type 'T' [with T = (Int, Int)]}} {{11-11=(}} {{15-15=)}}
95+
generic(a, b) // expected-error {{global function 'generic' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{11-11=(}} {{15-15=)}}
9696
generic((a))
9797
generic(c)
9898
generic((a, b))
@@ -114,7 +114,7 @@ do {
114114
var d = (a, b)
115115

116116
generic(a)
117-
generic(a, b) // expected-error {{global function 'generic' expects a single parameter of type 'T' [with T = (Int, Int)]}} {{11-11=(}} {{15-15=)}}
117+
generic(a, b) // expected-error {{global function 'generic' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{11-11=(}} {{15-15=)}}
118118
generic((a))
119119
generic(c)
120120
generic((a, b))
@@ -256,12 +256,12 @@ do {
256256
let s = Concrete()
257257

258258
s.generic(3)
259-
s.generic(3, 4) // expected-error {{instance method 'generic' expects a single parameter of type 'T' [with T = (Int, Int)]}} {{13-13=(}} {{17-17=)}}
259+
s.generic(3, 4) // expected-error {{instance method 'generic' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{13-13=(}} {{17-17=)}}
260260
s.generic((3))
261261
s.generic((3, 4))
262262

263263
s.genericLabeled(x: 3)
264-
s.genericLabeled(x: 3, 4) // expected-error {{instance method 'genericLabeled' expects a single parameter of type 'T' [with T = (Int, Int)]}} {{22-22=(}} {{27-27=)}}
264+
s.genericLabeled(x: 3, 4) // expected-error {{instance method 'genericLabeled' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{22-22=(}} {{27-27=)}}
265265
s.genericLabeled(x: (3))
266266
s.genericLabeled(x: (3, 4))
267267

@@ -281,7 +281,7 @@ do {
281281
let d = (a, b)
282282

283283
s.generic(a)
284-
s.generic(a, b) // expected-error {{instance method 'generic' expects a single parameter of type 'T' [with T = (Int, Int)]}} {{13-13=(}} {{17-17=)}}
284+
s.generic(a, b) // expected-error {{instance method 'generic' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{13-13=(}} {{17-17=)}}
285285
s.generic((a))
286286
s.generic((a, b))
287287
s.generic(d)
@@ -304,7 +304,7 @@ do {
304304
var d = (a, b)
305305

306306
s.generic(a)
307-
s.generic(a, b) // expected-error {{instance method 'generic' expects a single parameter of type 'T' [with T = (Int, Int)]}} {{13-13=(}} {{17-17=)}}
307+
s.generic(a, b) // expected-error {{instance method 'generic' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{13-13=(}} {{17-17=)}}
308308
s.generic((a))
309309
s.generic((a, b))
310310
s.generic(d)
@@ -390,12 +390,12 @@ do {
390390
var s = Concrete()
391391

392392
s.mutatingGeneric(3)
393-
s.mutatingGeneric(3, 4) // expected-error {{instance method 'mutatingGeneric' expects a single parameter of type 'T' [with T = (Int, Int)]}} {{21-21=(}} {{25-25=)}}
393+
s.mutatingGeneric(3, 4) // expected-error {{instance method 'mutatingGeneric' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{21-21=(}} {{25-25=)}}
394394
s.mutatingGeneric((3))
395395
s.mutatingGeneric((3, 4))
396396

397397
s.mutatingGenericLabeled(x: 3)
398-
s.mutatingGenericLabeled(x: 3, 4) // expected-error {{instance method 'mutatingGenericLabeled' expects a single parameter of type 'T' [with T = (Int, Int)]}} {{30-30=(}} {{35-35=)}}
398+
s.mutatingGenericLabeled(x: 3, 4) // expected-error {{instance method 'mutatingGenericLabeled' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{30-30=(}} {{35-35=)}}
399399
s.mutatingGenericLabeled(x: (3))
400400
s.mutatingGenericLabeled(x: (3, 4))
401401

@@ -415,7 +415,7 @@ do {
415415
let d = (a, b)
416416

417417
s.mutatingGeneric(a)
418-
s.mutatingGeneric(a, b) // expected-error {{instance method 'mutatingGeneric' expects a single parameter of type 'T' [with T = (Int, Int)]}} {{21-21=(}} {{25-25=)}}
418+
s.mutatingGeneric(a, b) // expected-error {{instance method 'mutatingGeneric' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{21-21=(}} {{25-25=)}}
419419
s.mutatingGeneric((a))
420420
s.mutatingGeneric((a, b))
421421
s.mutatingGeneric(d)
@@ -438,7 +438,7 @@ do {
438438
var d = (a, b)
439439

440440
s.mutatingGeneric(a)
441-
s.mutatingGeneric(a, b) // expected-error {{instance method 'mutatingGeneric' expects a single parameter of type 'T' [with T = (Int, Int)]}} {{21-21=(}} {{25-25=)}}
441+
s.mutatingGeneric(a, b) // expected-error {{instance method 'mutatingGeneric' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{21-21=(}} {{25-25=)}}
442442
s.mutatingGeneric((a))
443443
s.mutatingGeneric((a, b))
444444
s.mutatingGeneric(d)
@@ -929,10 +929,10 @@ struct GenericInitLabeledTuple<T> {
929929
}
930930

931931
do {
932-
_ = GenericInit(3, 4) // expected-error {{initializer expects a single parameter of type 'T' [with T = (Int, Int)]}} {{19-19=(}} {{23-23=)}}
932+
_ = GenericInit(3, 4) // expected-error {{initializer expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{19-19=(}} {{23-23=)}}
933933
_ = GenericInit((3, 4))
934934

935-
_ = GenericInitLabeled(x: 3, 4) // expected-error {{initializer expects a single parameter of type 'T' [with T = (Int, Int)]}} {{28-28=(}} {{33-33=)}}
935+
_ = GenericInitLabeled(x: 3, 4) // expected-error {{initializer expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{28-28=(}} {{33-33=)}}
936936
_ = GenericInitLabeled(x: (3, 4))
937937

938938
_ = GenericInitTwo(3, 4)
@@ -967,7 +967,7 @@ do {
967967
let b = 4
968968
let c = (a, b)
969969

970-
_ = GenericInit(a, b) // expected-error {{initializer expects a single parameter of type 'T' [with T = (Int, Int)]}} {{19-19=(}} {{23-23=)}}
970+
_ = GenericInit(a, b) // expected-error {{initializer expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{19-19=(}} {{23-23=)}}
971971
_ = GenericInit((a, b))
972972
_ = GenericInit(c)
973973

@@ -1003,7 +1003,7 @@ do {
10031003
var b = 4
10041004
var c = (a, b)
10051005

1006-
_ = GenericInit(a, b) // expected-error {{initializer expects a single parameter of type 'T' [with T = (Int, Int)]}} {{19-19=(}} {{23-23=)}}
1006+
_ = GenericInit(a, b) // expected-error {{initializer expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{19-19=(}} {{23-23=)}}
10071007
_ = GenericInit((a, b))
10081008
_ = GenericInit(c)
10091009

@@ -1127,12 +1127,12 @@ enum GenericEnum<T> {
11271127
}
11281128

11291129
do {
1130-
_ = GenericEnum.one(3, 4) // expected-error {{enum case 'one' expects a single parameter of type 'T' [with T = (Int, Int)]}} {{23-23=(}} {{27-27=)}}
1130+
_ = GenericEnum.one(3, 4) // expected-error {{enum case 'one' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{23-23=(}} {{27-27=)}}
11311131
_ = GenericEnum.one((3, 4))
11321132

1133-
_ = GenericEnum.labeled(x: 3, 4) // expected-error {{enum case 'labeled' expects a single parameter of type 'T' [with T = (Int, Int)]}} {{29-29=(}} {{34-34=)}}
1133+
_ = GenericEnum.labeled(x: 3, 4) // expected-error {{enum case 'labeled' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{29-29=(}} {{34-34=)}}
11341134
_ = GenericEnum.labeled(x: (3, 4))
1135-
_ = GenericEnum.labeled(3, 4) // expected-error {{enum case 'labeled' expects a single parameter of type 'T' [with T = (Int, Int)]}} {{27-27=(}} {{31-31=)}}
1135+
_ = GenericEnum.labeled(3, 4) // expected-error {{enum case 'labeled' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{27-27=(}} {{31-31=)}}
11361136
_ = GenericEnum.labeled((3, 4)) // expected-error {{missing argument label 'x:' in call}}
11371137

11381138
_ = GenericEnum.two(3, 4)
@@ -1163,7 +1163,7 @@ do {
11631163
let b = 4
11641164
let c = (a, b)
11651165

1166-
_ = GenericEnum.one(a, b) // expected-error {{enum case 'one' expects a single parameter of type 'T' [with T = (Int, Int)]}} {{23-23=(}} {{27-27=)}}
1166+
_ = GenericEnum.one(a, b) // expected-error {{enum case 'one' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{23-23=(}} {{27-27=)}}
11671167
_ = GenericEnum.one((a, b))
11681168
_ = GenericEnum.one(c)
11691169

@@ -1199,7 +1199,7 @@ do {
11991199
var b = 4
12001200
var c = (a, b)
12011201

1202-
_ = GenericEnum.one(a, b) // expected-error {{enum case 'one' expects a single parameter of type 'T' [with T = (Int, Int)]}} {{23-23=(}} {{27-27=)}}
1202+
_ = GenericEnum.one(a, b) // expected-error {{enum case 'one' expects a single parameter of type 'T' [with T = (Int, Int)]}} expected-note {{did you mean to pass a tuple?}} {{23-23=(}} {{27-27=)}}
12031203
_ = GenericEnum.one((a, b))
12041204
_ = GenericEnum.one(c)
12051205

test/decl/var/property_wrappers.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ struct Initialization {
236236
var x2: Double
237237

238238
@Wrapper(stored: 17) // expected-error {{initializer expects a single parameter of type 'T' [with T = (wrappedValue: Int, stored: Int)]}}
239+
// expected-note@-1 {{did you mean to pass a tuple?}}
239240
var x3 = 42
240241

241242
@Wrapper(stored: 17)

0 commit comments

Comments
 (0)