Skip to content

Commit 45722bf

Browse files
committed
[RequirementMachine] Use pack expansion types as a source for requirement inference.
Previously, only the pattern type was added as a requirement inference source, but the pack expansion type is necessary for inferring same-shape requirements for packs that are expanded in parallel.
1 parent cf38d55 commit 45722bf

File tree

5 files changed

+19
-6
lines changed

5 files changed

+19
-6
lines changed

lib/AST/RequirementMachine/ConcreteContraction.cpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -371,8 +371,12 @@ ConcreteContraction::substRequirement(const Requirement &req) const {
371371
auto firstType = req.getFirstType();
372372

373373
switch (req.getKind()) {
374-
case RequirementKind::SameShape:
375-
llvm_unreachable("Same-shape requirement not supported here");
374+
case RequirementKind::SameShape: {
375+
auto substFirstType = substType(firstType);
376+
auto substSecondType = substType(req.getSecondType());
377+
378+
return Requirement(req.getKind(), substFirstType, substSecondType);
379+
}
376380

377381
case RequirementKind::Superclass:
378382
case RequirementKind::SameType: {

lib/Sema/TypeCheckGeneric.cpp

-2
Original file line numberDiff line numberDiff line change
@@ -648,8 +648,6 @@ GenericSignatureRequest::evaluate(Evaluator &evaluator,
648648
typeRepr = specifier->getBase();
649649

650650
if (auto *packExpansion = dyn_cast<PackExpansionTypeRepr>(typeRepr)) {
651-
typeRepr = packExpansion->getPatternType();
652-
653651
paramOptions.setContext(TypeResolverContext::VariadicFunctionInput);
654652
} else {
655653
paramOptions.setContext(TypeResolverContext::FunctionInput);

lib/Sema/TypeCheckType.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -4228,8 +4228,13 @@ NeverNullType TypeResolver::resolvePackExpansionType(PackExpansionTypeRepr *repr
42284228
return ErrorType::get(ctx);
42294229
}
42304230

4231-
// The pattern type must contain at least one variadic generic parameter.
42324231
if (!pair.second) {
4232+
// Non-pack variadic parameters parse as PackExpansionTypeReprs. These
4233+
// can only appear in variadic function parameter types.
4234+
if (options.getContext() == TypeResolverContext::VariadicFunctionInput)
4235+
return pair.first;
4236+
4237+
// Otherwise, the pattern type must contain at least one pack reference.
42334238
diagnose(repr->getLoc(), diag::expansion_not_variadic, pair.first)
42344239
.highlight(repr->getSourceRange());
42354240
return ErrorType::get(ctx);

lib/Sema/TypeCheckType.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ class TypeResolutionOptions {
314314
bool isPackExpansionSupported() const {
315315
switch (context) {
316316
case Context::FunctionInput:
317+
case Context::VariadicFunctionInput:
317318
case Context::TupleElement:
318319
case Context::GenericArgument:
319320
return true;
@@ -335,7 +336,6 @@ class TypeResolutionOptions {
335336
case Context::PatternBindingDecl:
336337
case Context::EditorPlaceholderExpr:
337338
case Context::ClosureExpr:
338-
case Context::VariadicFunctionInput:
339339
case Context::InoutFunctionInput:
340340
case Context::FunctionResult:
341341
case Context::SubscriptDecl:

test/Generics/pack-shape-requirements.swift

+6
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,9 @@ struct Ts<T...> {
5959
}
6060
}
6161
}
62+
63+
// CHECK-LABEL: expandedParameters(_:transform:)
64+
// CHECK-NEXT: Generic signature: <T..., Result... where T.shape == Result.shape>
65+
func expandedParameters<T..., Result...>(_ t: T..., transform: ((T) -> Result)...) -> (Result...) {
66+
fatalError()
67+
}

0 commit comments

Comments
 (0)