Skip to content

Commit 16c3992

Browse files
committed
[Variadic Generics] distinctly diagnose more types of pack expansion errors + add fixits
1 parent 1f3623d commit 16c3992

File tree

6 files changed

+62
-26
lines changed

6 files changed

+62
-26
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5310,8 +5310,8 @@ ERROR(vararg_not_allowed,none,
53105310
"variadic parameter cannot appear outside of a function parameter list",
53115311
())
53125312
ERROR(expansion_not_allowed,none,
5313-
"pack expansion %0 cannot appear outside of a function parameter list, "
5314-
"function result, tuple element or generic argument list", (Type))
5313+
"pack expansion repeat each %0 can only appear in a function parameter list, "
5314+
"tuple element, or generic argument list", (Type))
53155315
ERROR(expansion_not_variadic,none,
53165316
"pack expansion %0 must contain at least one pack reference", (Type))
53175317
ERROR(pack_reference_outside_expansion,none,
@@ -5320,7 +5320,10 @@ ERROR(pack_reference_outside_expansion,none,
53205320
ERROR(each_non_pack,none,
53215321
"'each' cannot be applied to non-pack type %0",
53225322
(Type))
5323-
ERROR(pack_expansion_missing_pack_reference,none,
5323+
ERROR(pack_reference_must_be_in_expansion,none,
5324+
"pack reference %0 requires expansion using keyword 'repeat'",
5325+
(TypeRepr*))
5326+
ERROR(pack_type_requires_keyword_each,none,
53245327
"pack type %0 must be referenced with 'each'",
53255328
(TypeRepr*))
53265329
ERROR(tuple_duplicate_label,none,

include/swift/Basic/SourceLoc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ class SourceRange {
157157
/// A half-open character-based source range.
158158
class CharSourceRange {
159159
SourceLoc Start;
160-
unsigned ByteLength;
160+
unsigned ByteLength{};
161161

162162
public:
163163
/// Constructs an invalid range.

lib/Sema/TypeCheckType.cpp

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4077,11 +4077,24 @@ TypeResolver::resolveDeclRefTypeRepr(DeclRefTypeRepr *repr,
40774077
silContext, identBase);
40784078

40794079
if (result && result->isParameterPack() &&
4080-
options.contains(TypeResolutionFlags::AllowPackReferences) &&
4081-
!options.contains(TypeResolutionFlags::FromPackReference)) {
4082-
diagnose(repr->getLoc(), diag::pack_expansion_missing_pack_reference,
4083-
repr);
4084-
return ErrorType::get(result);
4080+
// Workaround to allow 'shape' type checking of SIL.
4081+
// TODO: Explicitly pass along whether in a 'shape' context.
4082+
!options.contains(TypeResolutionFlags::SILMode)) {
4083+
bool invalid = false;
4084+
if (!options.contains(TypeResolutionFlags::AllowPackReferences)) {
4085+
diagnose(repr->getLoc(), diag::pack_reference_must_be_in_expansion,
4086+
repr);
4087+
invalid = true;
4088+
}
4089+
if (!options.contains(TypeResolutionFlags::FromPackReference)) {
4090+
diagnose(repr->getLoc(), diag::pack_type_requires_keyword_each,
4091+
repr)
4092+
.fixItInsert(repr->getLoc(), "each ");
4093+
invalid = true;
4094+
}
4095+
if (invalid) {
4096+
return ErrorType::get(result);
4097+
}
40854098
}
40864099
} else {
40874100
result = resolveType(baseComp, options);
@@ -4592,6 +4605,7 @@ NeverNullType TypeResolver::resolvePackElement(PackElementTypeRepr *repr,
45924605
}
45934606
}
45944607
}
4608+
// TODO: else 'each' probably should be removed preceding repr
45954609
return packReference;
45964610
}
45974611

test/Constraints/pack-expansion-expressions.swift

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ func typeReprPacks<each T>(_ t: repeat each T) where each T: ExpressibleByIntege
7676
_ = repeat Array<each T>()
7777
_ = repeat 1 as each T
7878

79-
_ = Array<each T>() // expected-error {{pack reference 'T' can only appear in pack expansion or generic requirement}}
80-
_ = 1 as each T // expected-error {{pack reference 'T' can only appear in pack expansion or generic requirement}}
79+
_ = Array<each T>() // expected-error {{pack reference 'T' requires expansion using keyword 'repeat'}}
80+
_ = 1 as each T // expected-error {{pack reference 'T' requires expansion using keyword 'repeat'}}
8181
repeat Invalid<String, each T>("") // expected-error {{cannot find 'Invalid' in scope}}
8282
}
8383

@@ -87,22 +87,38 @@ func sameShapeDiagnostics<each T, each U>(t: repeat each T, u: repeat each U) {
8787
_ = repeat (Array<each T>(), each u) // expected-error {{pack expansion requires that 'U' and 'T' have the same shape}}
8888
}
8989

90-
func returnPackExpansionType<each T>(_ t: repeat each T) -> repeat each T { // expected-error {{pack expansion 'T' cannot appear outside of a function parameter list, function result, tuple element or generic argument list}}
90+
func returnPackExpansionType<each T>(_ t: repeat each T) -> repeat each T { // expected-error {{pack expansion repeat each 'T' can only appear in a function parameter list, tuple element, or generic argument list}}
9191
fatalError()
9292
}
9393

94-
func returnEachPackReference<each T>(_ t: repeat each T) -> each T { // expected-error {{pack reference 'T' can only appear in pack expansion or generic requirement}}
94+
func returnEachPackReference<each T>(_ t: repeat each T) -> each T { // expected-error {{pack reference 'T' requires expansion using keyword 'repeat'}}
9595
fatalError()
9696
}
9797

98-
func returnRepeatTuple<each T>(_ t: repeat each T) -> (repeat T) { // expected-error {{pack type 'T' must be referenced with 'each'}}
98+
// expected-error@+1 {{pack type 'T' must be referenced with 'each'}}{{63-63=each }}
99+
func returnRepeatTuple<each T>(_ t: repeat each T) -> (repeat T) {
99100
fatalError()
100101
}
101102

102-
func parameterAsPackTypeWithoutExpansion<each T>(_ t: T) -> repeat each T { // expected-error {{pack expansion 'T' cannot appear outside of a function parameter list, function result, tuple element or generic argument list}}
103+
// expected-error@+2 {{pack reference 'T' requires expansion using keyword 'repeat'}}
104+
// expected-error@+1 {{pack type 'T' must be referenced with 'each'}}{{55-55=each }}
105+
func parameterAsPackTypeWithoutExpansion<each T>(_ t: T) {
106+
}
107+
108+
// expected-error@+2 {{pack reference 'T' requires expansion using keyword 'repeat'}}
109+
// expected-error@+1 {{pack type 'T' must be referenced with 'each'}}{{57-57=each }}
110+
func returnPackReference<each T>(_ t: repeat each T) -> T {
103111
fatalError()
104112
}
105113

114+
func packTypeParameterOutsidePackExpansionType<each T>(_ t: T,
115+
// expected-error@-1 {{pack reference 'T' requires expansion using keyword 'repeat'}}
116+
// expected-error@-2 {{pack type 'T' must be referenced with 'each'}}{{61-61=each }}
117+
_ a: Array<T>) {
118+
// expected-error@-1 {{pack reference 'T' requires expansion using keyword 'repeat'}}
119+
// expected-error@-2 {{pack type 'T' must be referenced with 'each'}}{{67-67=each }}
120+
}
121+
106122
func expansionOfNonPackType<T>(_ t: repeat each T) {}
107123
// expected-error@-1 {{'each' cannot be applied to non-pack type 'T'}}{{29-29=each }}
108124
// expected-error@-2 {{pack expansion 'T' must contain at least one pack reference}}
@@ -125,7 +141,7 @@ protocol Generatable {
125141

126142
func generateTuple<each T : Generatable>() -> (repeat each T) {
127143
(each T).generate()
128-
// expected-error@-1 {{pack reference 'T' can only appear in pack expansion or generic requirement}}
144+
// expected-error@-1 {{pack reference 'T' requires expansion using keyword 'repeat'}}
129145

130146
return (repeat (each T).generate())
131147
}

test/Constraints/variadic_generic_functions.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ func debugPrint<each T>(_ items: repeat each T)
1010
}*/
1111
}
1212

13-
func max<each T>(_ values: repeat each T) -> T?
13+
func max<each T>(_ values: repeat each T) -> (repeat each T)?
1414
where each T: Comparable
1515
{
1616
return nil
1717
}
1818

19-
func min<each T: Comparable>(_ values: repeat each T) -> T? {
19+
func min<each T: Comparable>(_ values: repeat each T) -> (repeat each T)? {
2020
return nil
2121
}
2222

test/type/pack_expansion.swift

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// REQUIRES: asserts
44

55
func f1<each T>() -> repeat each T {}
6-
// expected-error@-1 {{pack expansion 'T' cannot appear outside of a function parameter list, function result, tuple element or generic argument list}}
6+
// expected-error@-1 {{pack expansion repeat each 'T' can only appear in a function parameter list, tuple element, or generic argument list}}
77

88
func f2<each T>() -> (repeat each T) {}
99
// okay
@@ -19,12 +19,12 @@ protocol P<T> {
1919
func f4<each T>() -> any P<repeat each T> {}
2020

2121
typealias T1<each T> = repeat each T
22-
// expected-error@-1 {{pack expansion 'T' cannot appear outside of a function parameter list, function result, tuple element or generic argument list}}
22+
// expected-error@-1 {{pack expansion repeat each 'T' can only appear in a function parameter list, tuple element, or generic argument list}}
2323

2424
typealias T2<each T> = (repeat each T)
2525

2626
func f4<each T>() -> repeat () -> each T {}
27-
// expected-error@-1 {{pack expansion '() -> T' cannot appear outside of a function parameter list, function result, tuple element or generic argument list}}
27+
// expected-error@-1 {{pack expansion repeat each '() -> T' can only appear in a function parameter list, tuple element, or generic argument list}}
2828

2929
func f5<each T>() -> () -> (repeat each T) {}
3030

@@ -36,20 +36,20 @@ enum E<each T> {
3636
case f2(_: G<repeat each T>)
3737

3838
var x: repeat each T { fatalError() }
39-
// expected-error@-1 {{pack expansion 'T' cannot appear outside of a function parameter list, function result, tuple element or generic argument list}}
39+
// expected-error@-1 {{pack expansion repeat each 'T' can only appear in a function parameter list, tuple element, or generic argument list}}
4040

4141
var x: (repeat each T) { fatalError() }
4242

4343
subscript(_: repeat each T) -> Int { fatalError() }
4444

4545
subscript() -> repeat each T { fatalError() }
46-
// expected-error@-1 {{pack expansion 'T' cannot appear outside of a function parameter list, function result, tuple element or generic argument list}}
46+
// expected-error@-1 {{pack expansion repeat each 'T' can only appear in a function parameter list, tuple element, or generic argument list}}
4747

4848
subscript() -> (repeat each T) { fatalError() }
4949
}
5050

5151
func withWhereClause<each T>(_ x: repeat each T) where repeat each T: P {}
52-
// expected-error@-1 {{pack expansion 'T' cannot appear outside of a function parameter list, function result, tuple element or generic argument list}}
52+
// expected-error@-1 {{pack expansion repeat each 'T' can only appear in a function parameter list, tuple element, or generic argument list}}
5353

5454
struct Outer<each T> {
5555
struct Bad<each U> {
@@ -70,9 +70,12 @@ func packRef<each T>(_: repeat each T) where each T: P {}
7070
func packMemberRef<each T>(_: repeat each T.T) where each T: P {}
7171

7272
// expected-error@+1 {{'each' cannot be applied to non-pack type 'Int'}}
73-
func invalidPackRef(_: each Int) {}
73+
func invalidPackRefEachInt(_: each Int) {}
7474

75-
// expected-error@+1 {{pack reference 'T' can only appear in pack expansion or generic requirement}}
75+
// expected-error@+1 {{pack expansion 'Int' must contain at least one pack reference}}
76+
func invalidPackRefRepeatInt(_: repeat Int) {}
77+
78+
// expected-error@+1 {{pack reference 'T' requires expansion using keyword 'repeat'}}
7679
func packRefOutsideExpansion<each T>(_: each T) {}
7780

7881
// coverage to ensure a 'repeat each' type is considered Copyable

0 commit comments

Comments
 (0)