Skip to content

Commit 3e436d3

Browse files
committed
Sema: Fix two problems in checkReferencedGenericParams() analysis
- Don't walk into the count type of a PackExpansionType, because when matching two PackExpansionTypes, the solver only introduces a shape constraint between the count types, which does not fix it to a concrete type. - Similarly, don't walk into type alias substitutions, because only the desugared type is considered by the constraint solver. This is mildly source breaking, in that before we let you declare generic functions that could not be called.
1 parent 999b790 commit 3e436d3

File tree

2 files changed

+28
-0
lines changed

2 files changed

+28
-0
lines changed

lib/Sema/TypeCheckGeneric.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,25 @@ void TypeChecker::checkReferencedGenericParams(GenericContext *dc) {
341341
ReferencedGenericParams.insert(ty->getCanonicalType());
342342
return Action::SkipChildren;
343343
}
344+
345+
// Skip the count type, which is always a generic parameter;
346+
// we don't consider it a reference because it only binds the
347+
// shape and not the metadata.
348+
if (auto *expansionTy = ty->getAs<PackExpansionType>()) {
349+
expansionTy->getPatternType().walk(*this);
350+
return Action::SkipChildren;
351+
}
352+
353+
// Don't walk into generic type alias substitutions. This does
354+
// not constrain `T`:
355+
//
356+
// typealias Foo<T> = Int
357+
// func foo<T>(_: Foo<T>) {}
358+
if (auto *aliasTy = dyn_cast<TypeAliasType>(ty.getPointer())) {
359+
Type(aliasTy->getSinglyDesugaredType()).walk(*this);
360+
return Action::SkipChildren;
361+
}
362+
344363
return Action::Continue;
345364
}
346365

test/type/pack_expansion.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ struct Outer<each T> {
6565
func packRef<each T>(_: repeat each T) where repeat each T: P {}
6666

6767
func packMemberRef<each T>(_: repeat (each T).T) where repeat each T: P {}
68+
// expected-error@-1 {{generic parameter 'T' is not used in function signature}}
6869

6970
// expected-error@+1 {{'each' cannot be applied to non-pack type 'Int'}}{{31-35=}}
7071
func invalidPackRefEachInt(_: each Int) {}
@@ -98,3 +99,11 @@ func golden<Z>(_ z: Z) {}
9899
func hour<each T>(_ t: repeat each T) {
99100
_ = (repeat golden(each t))
100101
}
102+
103+
func unusedParameterPack1<each T: Sequence>(_: repeat (each T).Element) {}
104+
// expected-error@-1 {{generic parameter 'T' is not used in function signature}}
105+
106+
typealias First<T, U> = T
107+
108+
func unusedParameterPack2<each T>(_: repeat First<Int, each T>) {}
109+
// expected-error@-1 {{generic parameter 'T' is not used in function signature}}

0 commit comments

Comments
 (0)