diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index ea4632232da0b..a2872a2b6ca6b 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -3115,6 +3115,8 @@ ConstraintSystem::TypeMatchResult ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2, ConstraintKind kind, TypeMatchOptions flags, ConstraintLocatorBuilder locator) { + func1 = simplifyType(func1)->castTo(); + func2 = simplifyType(func2)->castTo(); // Match the 'throws' effect. TypeMatchResult throwsResult = matchFunctionThrowing(*this, func1, func2, kind, flags, locator); @@ -12071,11 +12073,6 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar, if (contextualTy->isTypeVariableOrMember()) return false; - // Cannot propagate pack expansion type from context, - // it has to be handled by type matching logic. - if (isPackExpansionType(contextualTy)) - return false; - // If contextual type has an error, let's wait for inference, // otherwise contextual would interfere with diagnostics. if (contextualTy->hasError()) @@ -12241,8 +12238,19 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar, // choices in the body. if (auto contextualParam = getContextualParamAt(i)) { auto paramTy = simplifyType(contextualParam->getOldType()); - if (isSuitableContextualType(paramTy)) + auto isSuitable = isSuitableContextualType(paramTy); + if (isSuitable && !paramTy->is()) addConstraint(ConstraintKind::Bind, externalType, paramTy, paramLoc); + else if (isSuitable) { + // If we have an unbound type variable and the contextual parameter + // type is a pack expansion, we must bind it here. Otherwise, it will + // never get bound. + if (auto externalTypeVar = + getFixedTypeRecursive(externalType, /*wantRValue=*/true) + ->getAs()) { + assignFixedType(externalTypeVar, paramTy); + } + } } addConstraint( diff --git a/lib/Sema/TypeOfReference.cpp b/lib/Sema/TypeOfReference.cpp index 791f493a0841c..1f6167673bbb6 100644 --- a/lib/Sema/TypeOfReference.cpp +++ b/lib/Sema/TypeOfReference.cpp @@ -617,6 +617,7 @@ Type ConstraintSystem::getUnopenedTypeOfReference( requestedType = requestedType->getWithoutSpecifierType()->getReferenceStorageReferent(); + requestedType = simplifyType(requestedType); // Strip pack expansion types off of pack references. if (auto *expansion = requestedType->getAs()) diff --git a/test/Constraints/pack-expansion-expressions.swift b/test/Constraints/pack-expansion-expressions.swift index f05040f17219d..ca42e3ef5ec29 100644 --- a/test/Constraints/pack-expansion-expressions.swift +++ b/test/Constraints/pack-expansion-expressions.swift @@ -798,3 +798,13 @@ do { } } } + +// https://github.com/swiftlang/swift/issues/78426 +func test_pack_param_inference_closure(_: repeat each T) { + func takesGeneric(_: U) {} + let _: (repeat each T) -> Void = { x in } + let _: (repeat each T) -> Void = { repeat takesGeneric(each $0) } + let _: (Any, repeat each T) -> Void = { _,x in repeat takesGeneric(each x) } + let _ = { x in repeat takesGeneric(each x) } + // expected-error@-1{{cannot infer type of closure parameter 'x' without a type annotation}} +}