Skip to content

Commit 8091744

Browse files
authored
Merge pull request #67428 from hborla/dependent-type-pack-syntax
[Type Resolution] Only allow `each` applied directly to a type parameter pack.
2 parents 7741409 + 43c3004 commit 8091744

23 files changed

+67
-62
lines changed

include/swift/AST/Types.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,10 @@ class alignas(1 << TypeAlignInBits) TypeBase
769769
/// include type parameters in nested positions e.g. \c X<T...>.
770770
bool isParameterPack();
771771

772+
/// Determine whether this type is directly a type parameter pack, which
773+
/// can only be a GenericTypeParamType.
774+
bool isRootParameterPack();
775+
772776
/// Determine whether this type can dynamically be an optional type.
773777
///
774778
/// \param includeExistential Whether an existential type should be considered

lib/AST/ASTMangler.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -653,8 +653,7 @@ std::string ASTMangler::mangleAutoDiffGeneratedDeclaration(
653653
static Type getTypeForDWARFMangling(Type t) {
654654
return t.subst(
655655
[](SubstitutableType *t) -> Type {
656-
if (isa<GenericTypeParamType>(t) &&
657-
cast<GenericTypeParamType>(t)->isParameterPack()) {
656+
if (t->isRootParameterPack()) {
658657
return PackType::getSingletonPackExpansion(t->getCanonicalType());
659658
}
660659
return t->getCanonicalType();

lib/AST/ASTVerifier.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -614,8 +614,7 @@ class Verifier : public ASTWalker {
614614
auto countType = expansion->getCountType();
615615
if (!(countType->is<PackType>() ||
616616
countType->is<PackArchetypeType>() ||
617-
(countType->is<GenericTypeParamType>() &&
618-
countType->castTo<GenericTypeParamType>()->isParameterPack()))) {
617+
countType->isRootParameterPack())) {
619618
Out << "non-pack shape type" << countType->getString() << "\n";
620619
abort();
621620
}

lib/AST/GenericSignature.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -875,7 +875,7 @@ void GenericSignature::verify(ArrayRef<Requirement> reqts) const {
875875
abort();
876876
}
877877

878-
if (!reqt.getFirstType()->castTo<GenericTypeParamType>()->isParameterPack()) {
878+
if (!reqt.getFirstType()->isRootParameterPack()) {
879879
llvm::errs() << "Left hand side is not a parameter pack: ";
880880
reqt.dump(llvm::errs());
881881
llvm::errs() << "\n";
@@ -889,7 +889,7 @@ void GenericSignature::verify(ArrayRef<Requirement> reqts) const {
889889
abort();
890890
}
891891

892-
if (!reqt.getSecondType()->castTo<GenericTypeParamType>()->isParameterPack()) {
892+
if (!reqt.getSecondType()->isRootParameterPack()) {
893893
llvm::errs() << "Right hand side is not a parameter pack: ";
894894
reqt.dump(llvm::errs());
895895
llvm::errs() << "\n";

lib/AST/ParameterPack.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,7 @@ static Type transformTypeParameterPacksRec(
6666
if (auto *paramType = dyn_cast<SubstitutableType>(t)) {
6767
if (expansionLevel == 0 &&
6868
(isa<PackArchetypeType>(paramType) ||
69-
(isa<GenericTypeParamType>(paramType) &&
70-
cast<GenericTypeParamType>(paramType)->isParameterPack()))) {
69+
paramType->isRootParameterPack())) {
7170
return fn(paramType);
7271
}
7372

@@ -186,6 +185,12 @@ bool TypeBase::isParameterPack() {
186185
while (auto *memberTy = t->getAs<DependentMemberType>())
187186
t = memberTy->getBase();
188187

188+
return t->isRootParameterPack();
189+
}
190+
191+
bool TypeBase::isRootParameterPack() {
192+
Type t(this);
193+
189194
return t->is<GenericTypeParamType>() &&
190195
t->castTo<GenericTypeParamType>()->isParameterPack();
191196
}

lib/AST/TypeSubstitution.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,7 @@ QueryTypeSubstitutionMapOrIdentity::operator()(SubstitutableType *type) const {
5656
if (known != substitutions.end() && known->second)
5757
return known->second;
5858

59-
if (isa<PackArchetypeType>(type) ||
60-
(isa<GenericTypeParamType>(type) &&
61-
cast<GenericTypeParamType>(type)->isParameterPack())) {
59+
if (isa<PackArchetypeType>(type) || type->isRootParameterPack()) {
6260
return PackType::getSingletonPackExpansion(type);
6361
}
6462

lib/Sema/TypeCheckType.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4673,7 +4673,7 @@ NeverNullType TypeResolver::resolvePackElement(PackElementTypeRepr *repr,
46734673
if (packReference->hasError())
46744674
return ErrorType::get(ctx);
46754675

4676-
if (!packReference->isParameterPack()) {
4676+
if (!packReference->isRootParameterPack()) {
46774677
auto diag =
46784678
ctx.Diags.diagnose(repr->getLoc(), diag::each_non_pack, packReference);
46794679
bool addEachFixitApplied = false;

test/Constraints/pack-expansion-expressions.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ extension P {
5959

6060

6161
func outerArchetype<each T, U>(t: repeat each T, u: U) where repeat each T: P {
62-
let _: (repeat (each T.A, U)) = (repeat ((each t).value, u))
62+
let _: (repeat ((each T).A, U)) = (repeat ((each t).value, u))
6363
}
6464

6565
func sameElement<each T, U>(t: repeat each T, u: U) where repeat each T: P, repeat each T == U {
@@ -478,11 +478,11 @@ do {
478478

479479
// rdar://107675464 - misplaced `each` results in `type of expression is ambiguous without a type annotation`
480480
do {
481-
func test_correct_each<each T: P>(_ value: repeat each T) -> (repeat each T.A) {
481+
func test_correct_each<each T: P>(_ value: repeat each T) -> (repeat (each T).A) {
482482
return (repeat (each value).makeA()) // Ok
483483
}
484484

485-
func test_misplaced_each<each T: P>(_ value: repeat each T) -> (repeat each T.A) {
485+
func test_misplaced_each<each T: P>(_ value: repeat each T) -> (repeat (each T).A) {
486486
return (repeat each value.makeA())
487487
// expected-error@-1 {{value pack 'each T' must be referenced with 'each'}} {{25-25=(each }} {{30-30=)}}
488488
}

test/Generics/pack-shape-requirements.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ func inferSameShape<each T, each U>(ts t: repeat each T, us u: repeat each U) wh
1212
// CHECK-LABEL: desugarSameShape(ts:us:)
1313
// CHECK-NEXT: Generic signature: <each T, each U where repeat each T : P, (repeat (each T, each U)) : Any, repeat each U : P>
1414
func desugarSameShape<each T, each U>(ts t: repeat each T, us u: repeat each U)
15-
where repeat each T: P, repeat each U: P, (repeat (each T.A, each U.A)): Any {}
15+
where repeat each T: P, repeat each U: P, (repeat ((each T).A, (each U).A)): Any {}
1616

1717
// CHECK-LABEL: multipleSameShape1(ts:us:vs:)
1818
// CHECK-NEXT: Generic signature: <each T, each U, each V where (repeat (each T, each U)) : Any, (repeat (each U, each V)) : Any>
@@ -75,11 +75,11 @@ func expandedParameters<each T, each Result>(_ t: repeat each T, transform: repe
7575

7676
// CHECK-LABEL: sameType1
7777
// CHECK-NEXT: Generic signature: <each T, each U where repeat each T : P, repeat each U : P, repeat (each T).[P]A == (each U).[P]A>
78-
func sameType1<each T, each U>(_: repeat (each T, each U)) where repeat each T: P, repeat each U: P, repeat each T.A == each U.A {}
78+
func sameType1<each T, each U>(_: repeat (each T, each U)) where repeat each T: P, repeat each U: P, repeat (each T).A == (each U).A {}
7979

8080
// Make sure inherited associated types are handled
8181
protocol Q: P where A: Q {}
8282

8383
// CHECK-LABEL: sameType2
8484
// CHECK-NEXT: Generic signature: <each T, each U where repeat each T : Q, repeat each U : Q, repeat (each T).[P]A.[P]A == (each U).[P]A.[P]A>
85-
func sameType2<each T, each U>(_: repeat (each T, each U)) where repeat each T: Q, repeat each U: Q, repeat each T.A.A == each U.A.A {}
85+
func sameType2<each T, each U>(_: repeat (each T, each U)) where repeat each T: Q, repeat each U: Q, repeat (each T).A.A == (each U).A.A {}

test/Generics/tuple-conformances.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ protocol P {
1212
}
1313

1414
extension Builtin.TheTupleType: P where repeat each Elements: P {
15-
typealias A = (repeat each Elements.A)
15+
typealias A = (repeat (each Elements).A)
1616
typealias B = Float
1717
func f() {}
1818
}

0 commit comments

Comments
 (0)