Skip to content

Commit c6508a4

Browse files
authored
Merge pull request #64415 from slavapestov/reduced-type-of-pack-expansion
RequirementMachine: The reduced type of a PackExpansionType has a reduced *shape* for the count type
2 parents 8db7d71 + 2fa344b commit c6508a4

File tree

9 files changed

+49
-26
lines changed

9 files changed

+49
-26
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5310,26 +5310,26 @@ ERROR(vararg_not_allowed,none,
53105310
"variadic parameter cannot appear outside of a function parameter list",
53115311
())
53125312
ERROR(expansion_not_allowed,none,
5313-
"variadic expansion %0 cannot appear outside of a function parameter list, "
5313+
"pack expansion %0 cannot appear outside of a function parameter list, "
53145314
"function result, tuple element or generic argument list", (Type))
53155315
ERROR(expansion_not_variadic,none,
5316-
"variadic expansion %0 must contain at least one variadic generic parameter", (Type))
5316+
"pack expansion %0 must contain at least one pack reference", (Type))
53175317
ERROR(pack_reference_outside_expansion,none,
53185318
"pack reference %0 can only appear in pack expansion or generic requirement",
53195319
(Type))
53205320
ERROR(each_non_pack,none,
53215321
"'each' cannot be applied to non-pack type %0",
53225322
(Type))
53235323
ERROR(pack_expansion_missing_pack_reference,none,
5324-
"pack expansion %0 must specify a pack reference",
5324+
"pack type %0 must be referenced with 'each'",
53255325
(TypeRepr*))
53265326
ERROR(tuple_duplicate_label,none,
53275327
"cannot create a tuple with a duplicate element label", ())
53285328
ERROR(multiple_ellipsis_in_tuple,none,
53295329
"only a single element can be variadic", ())
53305330

53315331
ERROR(expansion_not_same_shape,none,
5332-
"variadic expansion %0 requires that %1 and %2 have the same shape",
5332+
"pack expansion %0 requires that %1 and %2 have the same shape",
53335333
(Type, Type, Type))
53345334
ERROR(expansion_expr_not_same_shape,none,
53355335
"pack expansion requires that %0 and %1 have the same shape",

lib/AST/GenericSignature.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ GenericSignatureImpl::lookupNestedType(Type type, Identifier name) const {
536536

537537
Type
538538
GenericSignatureImpl::getReducedShape(Type type) const {
539-
return getRequirementMachine()->getReducedShape(type);
539+
return getRequirementMachine()->getReducedShape(type, getGenericParams());
540540
}
541541

542542
bool

lib/AST/RequirementMachine/GenericSignatureQueries.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ RequirementMachine::getLocalRequirements(
5757

5858
GenericSignature::LocalRequirements result;
5959
result.anchor = Map.getTypeForTerm(term, genericParams);
60-
result.packShape = getReducedShape(depType);
60+
result.packShape = getReducedShape(depType, genericParams);
6161

6262
auto *props = Map.lookUpProperties(term);
6363
if (!props)
@@ -365,6 +365,17 @@ Type RequirementMachine::getReducedType(
365365
if (!t->hasTypeParameter())
366366
return t;
367367

368+
// The reduced type of a PackExpansionType has a reduced *shape* for
369+
// the count type.
370+
if (auto *packExpansionType = t->getAs<PackExpansionType>()) {
371+
auto reducedPattern = getReducedType(packExpansionType->getPatternType(),
372+
genericParams);
373+
auto reducedShape = packExpansionType->getCountType();
374+
if (reducedShape->isParameterPack())
375+
reducedShape = getReducedShape(reducedShape, genericParams);
376+
return Type(PackExpansionType::get(reducedPattern, reducedShape));
377+
}
378+
368379
if (!t->isTypeParameter())
369380
return None;
370381

@@ -727,12 +738,12 @@ RequirementMachine::getReducedShapeTerm(Type type) const {
727738
return reducedTerm;
728739
}
729740

730-
Type RequirementMachine::getReducedShape(Type type) const {
741+
Type RequirementMachine::getReducedShape(Type type,
742+
TypeArrayView<GenericTypeParamType> genericParams) const {
731743
if (!type->isParameterPack())
732744
return Type();
733745

734-
return Map.getTypeForTerm(getReducedShapeTerm(type),
735-
getGenericParams());
746+
return Map.getTypeForTerm(getReducedShapeTerm(type), genericParams);
736747
}
737748

738749
bool RequirementMachine::haveSameShape(Type type1, Type type2) const {

lib/AST/RequirementMachine/RequirementMachine.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,8 @@ class RequirementMachine final {
164164
MutableTerm getReducedShapeTerm(Type type) const;
165165

166166
public:
167-
Type getReducedShape(Type type) const;
167+
Type getReducedShape(Type type,
168+
TypeArrayView<GenericTypeParamType> genericParams) const;
168169

169170
bool haveSameShape(Type type1, Type type2) const;
170171

lib/AST/Type.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4684,7 +4684,18 @@ static Type substType(Type derivedType,
46844684
boxTy->getLayout(),
46854685
newSubMap);
46864686
}
4687-
4687+
4688+
if (auto packExpansionTy = dyn_cast<PackExpansionType>(type)) {
4689+
auto patternTy = substType(packExpansionTy->getPatternType(),
4690+
substitutions, lookupConformances, options);
4691+
auto countTy = substType(packExpansionTy->getCountType(),
4692+
substitutions, lookupConformances, options);
4693+
if (auto *archetypeTy = countTy->getAs<PackArchetypeType>())
4694+
countTy = archetypeTy->getReducedShape();
4695+
4696+
return Type(PackExpansionType::get(patternTy, countTy)->expand());
4697+
}
4698+
46884699
if (auto silFnTy = dyn_cast<SILFunctionType>(type)) {
46894700
if (silFnTy->isPolymorphic())
46904701
return None;

test/Constraints/pack-expansion-expressions.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,25 +87,25 @@ 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 {{variadic 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 'T' cannot appear outside of a function parameter list, function result, tuple element or generic argument list}}
9191
fatalError()
9292
}
9393

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

98-
func returnRepeatTuple<each T>(_ t: repeat each T) -> (repeat T) { // expected-error {{pack expansion 'T' must specify a pack reference}}
98+
func returnRepeatTuple<each T>(_ t: repeat each T) -> (repeat T) { // expected-error {{pack type 'T' must be referenced with 'each'}}
9999
fatalError()
100100
}
101101

102-
func parameterAsPackTypeWithoutExpansion<each T>(_ t: T) -> repeat each T { // expected-error {{variadic expansion 'T' cannot appear outside of a function parameter list, function result, tuple element or generic argument list}}
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}}
103103
fatalError()
104104
}
105105

106106
func expansionOfNonPackType<T>(_ t: repeat each T) {}
107107
// expected-error@-1 {{'each' cannot be applied to non-pack type 'T'}}{{29-29=each }}
108-
// expected-error@-2 {{variadic expansion 'T' must contain at least one variadic generic parameter}}
108+
// expected-error@-2 {{pack expansion 'T' must contain at least one pack reference}}
109109

110110
func tupleExpansion<each T, each U>(
111111
_ tuple1: (repeat each T),
@@ -143,7 +143,7 @@ func copyIntoTuple<each T>(_ arg: repeat each T) -> (repeat each T) {
143143
}
144144
func callCopyAndBind<T>(_ arg: repeat each T) {
145145
// expected-error@-1 {{'each' cannot be applied to non-pack type 'T'}}
146-
// expected-error@-2 {{variadic expansion 'T' must contain at least one variadic generic parameter}}
146+
// expected-error@-2 {{pack expansion 'T' must contain at least one pack reference}}
147147

148148
// Don't propagate errors for invalid declaration reference
149149
let result = copyIntoTuple(repeat each arg)

test/Constraints/variadic_generic_functions.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ func min<each T: Comparable>(_ values: repeat each T) -> T? {
2222

2323
func invalidPacks() {
2424
func monovariadic1() -> (each String) {} // expected-error {{'each' cannot be applied to non-pack type 'String'}}
25-
func monovariadic2<T>() -> (repeat T) {} // expected-error {{variadic expansion 'T' must contain at least one variadic generic parameter}}
26-
func monovariadic3<T, U>() -> (T, repeat U) {} // expected-error {{variadic expansion 'U' must contain at least one variadic generic parameter}}
25+
func monovariadic2<T>() -> (repeat T) {} // expected-error {{pack expansion 'T' must contain at least one pack reference}}
26+
func monovariadic3<T, U>() -> (T, repeat U) {} // expected-error {{pack expansion 'U' must contain at least one pack reference}}
2727
}
2828

2929
func call() {

test/Constraints/variadic_generic_types.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@ func g<each T>(_: repeat each T) {
2121
_ = ((Int, repeat Array<each T>) -> ()).self
2222

2323
_ = (repeat each Int).self
24-
// expected-error@-1 {{variadic expansion 'Int' must contain at least one variadic generic parameter}}
24+
// expected-error@-1 {{pack expansion 'Int' must contain at least one pack reference}}
2525
// expected-error@-2 {{'each' cannot be applied to non-pack type 'Int'}}
2626
}

test/type/pack_expansion.swift

Lines changed: 7 additions & 7 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 {{variadic expansion 'T' cannot appear outside of a function parameter list, function result, tuple element or generic argument list}}
6+
// expected-error@-1 {{pack expansion 'T' cannot appear outside of a function parameter list, function result, 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 {{variadic expansion 'T' cannot appear outside of a function parameter list, function result, tuple element or generic argument list}}
22+
// expected-error@-1 {{pack expansion 'T' cannot appear outside of a function parameter list, function result, 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 {{variadic expansion '() -> T' cannot appear outside of a function parameter list, function result, tuple element or generic argument list}}
27+
// expected-error@-1 {{pack expansion '() -> T' cannot appear outside of a function parameter list, function result, tuple element or generic argument list}}
2828

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

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

3838
var x: repeat each T { fatalError() }
39-
// expected-error@-1 {{variadic expansion 'T' cannot appear outside of a function parameter list, function result, tuple element or generic argument list}}
39+
// expected-error@-1 {{pack expansion 'T' cannot appear outside of a function parameter list, function result, 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 {{variadic expansion 'T' cannot appear outside of a function parameter list, function result, tuple element or generic argument list}}
46+
// expected-error@-1 {{pack expansion 'T' cannot appear outside of a function parameter list, function result, 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 {{variadic expansion 'T' cannot appear outside of a function parameter list, function result, tuple element or generic argument list}}
52+
// expected-error@-1 {{pack expansion 'T' cannot appear outside of a function parameter list, function result, tuple element or generic argument list}}
5353

5454
struct Outer<each T> {
5555
struct Bad<each U> {
56-
typealias Value = (repeat (each T, each U)) // expected-error {{variadic expansion 'repeat (each T, each U)' requires that 'T' and 'U' have the same shape}}
56+
typealias Value = (repeat (each T, each U)) // expected-error {{pack expansion 'repeat (each T, each U)' requires that 'T' and 'U' have the same shape}}
5757
}
5858

5959
struct Good<each U> where (repeat (each T, each U)): Any {

0 commit comments

Comments
 (0)