Skip to content

Commit bbe8c20

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 2211b2c commit bbe8c20

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
@@ -343,6 +343,25 @@ void TypeChecker::checkReferencedGenericParams(GenericContext *dc) {
343343
ReferencedGenericParams.insert(ty->getCanonicalType());
344344
return Action::SkipChildren;
345345
}
346+
347+
// Skip the count type, which is always a generic parameter;
348+
// we don't consider it a reference because it only binds the
349+
// shape and not the metadata.
350+
if (auto *expansionTy = ty->getAs<PackExpansionType>()) {
351+
expansionTy->getPatternType().walk(*this);
352+
return Action::SkipChildren;
353+
}
354+
355+
// Don't walk into generic type alias substitutions. This does
356+
// not constrain `T`:
357+
//
358+
// typealias Foo<T> = Int
359+
// func foo<T>(_: Foo<T>) {}
360+
if (auto *aliasTy = dyn_cast<TypeAliasType>(ty.getPointer())) {
361+
Type(aliasTy->getSinglyDesugaredType()).walk(*this);
362+
return Action::SkipChildren;
363+
}
364+
346365
return Action::Continue;
347366
}
348367

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'}}
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)