@@ -10647,8 +10647,108 @@ ConstraintSystem::simplifyApplicableFnConstraint(
10647
10647
subKind, argumentsLoc, trailingClosureMatching);
10648
10648
10649
10649
switch (matchCallResult) {
10650
- case SolutionKind::Error:
10650
+ case SolutionKind::Error: {
10651
+ if (shouldAttemptFixes ())
10652
+ return SolutionKind::Error;
10653
+
10654
+ auto resultTy = func2->getResult ();
10655
+
10656
+ // If this is a call that constructs a callable type with
10657
+ // a trailing closure(s), closure(s) might not belong to
10658
+ // the constructor but rather to implicit `callAsFunction`,
10659
+ // there is no way to determine that without trying.
10660
+ if (resultTy->isCallableNominalType (DC) &&
10661
+ argumentList->hasAnyTrailingClosures ()) {
10662
+ auto *calleeLoc = getCalleeLocator (argumentsLoc);
10663
+
10664
+ bool isInit = false ;
10665
+ if (auto overload = findSelectedOverloadFor (calleeLoc)) {
10666
+ isInit = bool (dyn_cast_or_null<ConstructorDecl>(
10667
+ overload->choice .getDeclOrNull ()));
10668
+ }
10669
+
10670
+ if (!isInit)
10671
+ return SolutionKind::Error;
10672
+
10673
+ auto &ctx = getASTContext ();
10674
+ auto numTrailing = argumentList->getNumTrailingClosures ();
10675
+
10676
+ SmallVector<Argument, 4 > newArguments;
10677
+ SmallVector<Argument, 4 > trailingClosures;
10678
+
10679
+ for (unsigned i = 0 , n = argumentList->size (); i != n; ++i) {
10680
+ if (argumentList->isTrailingClosureIndex (i)) {
10681
+ trailingClosures.push_back (argumentList->get (i));
10682
+ } else {
10683
+ newArguments.push_back (argumentList->get (i));
10684
+ }
10685
+ }
10686
+
10687
+ // Original argument list with all the trailing closures removed.
10688
+ auto *newArgumentList = ArgumentList::createParsed (
10689
+ ctx, argumentList->getLParenLoc (), newArguments,
10690
+ argumentList->getRParenLoc (),
10691
+ /* firstTrailingClosureIndex=*/ None);
10692
+
10693
+ auto trailingClosureTypes = func1->getParams ().take_back (numTrailing);
10694
+ // The original result type is going to become a result of
10695
+ // implicit `.callAsFunction` instead since `.callAsFunction`
10696
+ // is inserted between `.init` and trailing closures.
10697
+ auto callAsFunctionResultTy = func1->getResult ();
10698
+
10699
+ // The implicit replacement for original result type which
10700
+ // represents a callable type produced by `.init` call.
10701
+ auto callableType =
10702
+ createTypeVariable (getConstraintLocator ({}), /* flags=*/ 0 );
10703
+
10704
+ // The original application type with all the trailing closures
10705
+ // dropped from it and result replaced to the implicit variable.
10706
+ func1 = FunctionType::get (func1->getParams ().drop_back (numTrailing),
10707
+ callableType, func1->getExtInfo ());
10708
+
10709
+ auto matchCallResult = ::matchCallArguments (
10710
+ *this , func2, newArgumentList, func1->getParams (),
10711
+ func2->getParams (), subKind, argumentsLoc, trailingClosureMatching);
10712
+
10713
+ if (matchCallResult != SolutionKind::Solved)
10714
+ return SolutionKind::Error;
10715
+
10716
+ // Note that `createImplicit` cannot be used here because it
10717
+ // doesn't allow us to specify trailing closure index.
10718
+ auto *implicitCallArgumentList = ArgumentList::createParsed (
10719
+ ctx, /* LParen=*/ SourceLoc (), trailingClosures,
10720
+ /* RParen=*/ SourceLoc (),
10721
+ /* firstTrailingClosureIndex=*/ 0 );
10722
+
10723
+ SmallVector<Identifier, 2 > closureLabelsScratch;
10724
+ // Create implicit `.callAsFunction` expression to use as an anchor
10725
+ // for new argument list that only has trailing closures in it.
10726
+ auto *implicitCall = UnresolvedDotExpr::createImplicit (
10727
+ ctx, getAsExpr (argumentsLoc->getAnchor ()), {ctx.Id_callAsFunction },
10728
+ implicitCallArgumentList->getArgumentLabels (closureLabelsScratch));
10729
+
10730
+ associateArgumentList (
10731
+ getConstraintLocator (implicitCall,
10732
+ ConstraintLocator::ApplyArgument),
10733
+ implicitCallArgumentList);
10734
+
10735
+ auto callAsFunctionArguments =
10736
+ FunctionType::get (trailingClosureTypes, callAsFunctionResultTy,
10737
+ FunctionType::ExtInfo ());
10738
+
10739
+ // Form an unsolved constraint to apply trailing closures to a
10740
+ // callable type produced by `.init`. This constraint would become
10741
+ // active when `callableType` is bound.
10742
+ addUnsolvedConstraint (Constraint::create (
10743
+ *this , ConstraintKind::ApplicableFunction, callAsFunctionArguments,
10744
+ callableType,
10745
+ getConstraintLocator (implicitCall,
10746
+ ConstraintLocator::ApplyFunction)));
10747
+ break ;
10748
+ }
10749
+
10651
10750
return SolutionKind::Error;
10751
+ }
10652
10752
10653
10753
case SolutionKind::Unsolved: {
10654
10754
// Only occurs when there is an ambiguity between forward scanning and
0 commit comments