@@ -6596,14 +6596,29 @@ static Type getFunctionBuilderTypeFor(ConstraintSystem &cs, unsigned paramIdx,
6596
6596
bool ConstraintSystem::resolveClosure (TypeVariableType *typeVar,
6597
6597
Type contextualType,
6598
6598
ConstraintLocatorBuilder locator) {
6599
+ auto getContextualParamAt =
6600
+ [&contextualType](unsigned index) -> Optional<AnyFunctionType::Param> {
6601
+ auto *fnType = contextualType->getAs <FunctionType>();
6602
+ return fnType && fnType->getNumParams () > index
6603
+ ? fnType->getParams ()[index]
6604
+ : Optional<AnyFunctionType::Param>();
6605
+ };
6606
+
6599
6607
auto *closureLocator = typeVar->getImpl ().getLocator ();
6600
6608
auto *closure = cast<ClosureExpr>(closureLocator->getAnchor ());
6601
-
6602
- auto *closureType = getClosureType (closure);
6609
+ auto *inferredClosureType = getClosureType (closure);
6603
6610
6604
6611
auto *paramList = closure->getParameters ();
6612
+ SmallVector<AnyFunctionType::Param, 4 > parameters;
6605
6613
for (unsigned i = 0 , n = paramList->size (); i != n; ++i) {
6606
- const auto ¶m = closureType->getParams ()[i];
6614
+ auto param = inferredClosureType->getParams ()[i];
6615
+
6616
+ // In case of anonymous parameters let's infer flags from context
6617
+ // that helps to infer variadic and inout earlier.
6618
+ if (closure->hasAnonymousClosureVars ()) {
6619
+ if (auto contextualParam = getContextualParamAt (i))
6620
+ param = param.withFlags (contextualParam->getParameterFlags ());
6621
+ }
6607
6622
6608
6623
Type internalType;
6609
6624
@@ -6617,17 +6632,25 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar,
6617
6632
auto *paramLoc =
6618
6633
getConstraintLocator (closure, LocatorPathElt::TupleElement (i));
6619
6634
6620
- internalType = createTypeVariable (paramLoc, TVO_CanBindToLValue |
6621
- TVO_CanBindToNoEscape);
6635
+ auto *typeVar = createTypeVariable (paramLoc, TVO_CanBindToLValue |
6636
+ TVO_CanBindToNoEscape);
6637
+
6638
+ // If external parameter is variadic it translates into an array in
6639
+ // the body of the closure.
6640
+ internalType =
6641
+ param.isVariadic () ? ArraySliceType::get (typeVar) : Type (typeVar);
6622
6642
6623
6643
auto externalType = param.getOldType ();
6624
- addConstraint (ConstraintKind::BindParam, externalType, internalType,
6625
- paramLoc);
6644
+ addConstraint (ConstraintKind::BindParam, externalType, typeVar, paramLoc);
6626
6645
}
6627
6646
6628
6647
setType (paramList->get (i), internalType);
6648
+ parameters.push_back (param);
6629
6649
}
6630
6650
6651
+ auto closureType =
6652
+ FunctionType::get (parameters, inferredClosureType->getResult (),
6653
+ inferredClosureType->getExtInfo ());
6631
6654
assignFixedType (typeVar, closureType, closureLocator);
6632
6655
6633
6656
if (auto last = locator.last ()) {
0 commit comments