[ConstraintSystem] Adjust the way pack parameters are opened

Although variadic type is declared without `repeat` each of
its generic arguments is supposed to be a PackType which is
modeled in the interface type as `Pack{repeat ...}`. When
reference to such a type is opened by the constraint solver
we need to drop the Pack{repeat ...} structure because the
type variable would represent a pack type so `S<each T>`
is opened as `S<$T0>` instead of `S<Pack{repeat $T0}>`.

Resolves: https://github.com/apple/swift/issues/66095
This commit is contained in:
Pavel Yaskevich
2023-06-23 17:36:20 -07:00
parent ce4ec06547
commit 2227930d03
2 changed files with 51 additions and 1 deletions

View File

@@ -837,7 +837,21 @@ Type ConstraintSystem::openUnboundGenericType(GenericTypeDecl *decl,
result = DC->mapTypeIntoContext(result);
}
return result.transform([&](Type type) {
return result.transform([&](Type type) -> Type {
// Although generic parameters are declared with just `each`
// their interface types introduce a pack expansion which
// means that the solver has to extact generic argument type
// variable from Pack{repeat ...} and drop that structure to
// make sure that generic argument gets inferred to a pack type.
if (auto *packTy = type->getAs<PackType>()) {
assert(packTy->getNumElements() == 1);
auto *expansion = packTy->getElementType(0)->castTo<PackExpansionType>();
auto *typeVar = expansion->getPatternType()->castTo<TypeVariableType>();
assert(typeVar->getImpl().getGenericParameter() &&
typeVar->getImpl().canBindToPack());
return typeVar;
}
if (auto *expansion = dyn_cast<PackExpansionType>(type.getPointer()))
return openPackExpansionType(expansion, replacements, locator);
return type;
@@ -990,6 +1004,15 @@ Type ConstraintSystem::openType(Type type, OpenedTypeMap &replacements,
}
}
// While opening variadic generic types that appear in other types
// we need to extract generic parameter from Pack{repeat ...} structure
// that gets introduced by the interface type, see
// \c openUnboundGenericType for more details.
if (auto *packTy = type->getAs<PackType>()) {
if (auto expansion = packTy->unwrapSingletonPackExpansion())
type = expansion->getPatternType();
}
if (auto *expansion = type->getAs<PackExpansionType>()) {
return openPackExpansionType(expansion, replacements, locator);
}