@@ -1321,6 +1321,7 @@ class OpenTypeSequenceElements {
1321
1321
// Match the argument of a call to the parameter.
1322
1322
ConstraintSystem::TypeMatchResult constraints::matchCallArguments (
1323
1323
ConstraintSystem &cs, FunctionType *contextualType,
1324
+ ArgumentList *argList,
1324
1325
ArrayRef<AnyFunctionType::Param> args,
1325
1326
ArrayRef<AnyFunctionType::Param> params, ConstraintKind subKind,
1326
1327
ConstraintLocatorBuilder locator,
@@ -1340,8 +1341,7 @@ ConstraintSystem::TypeMatchResult constraints::matchCallArguments(
1340
1341
1341
1342
ParameterListInfo paramInfo (params, callee, appliedSelf);
1342
1343
1343
- // Dig out the argument information.
1344
- auto *argList = cs.getArgumentList (loc);
1344
+ // Make sure that argument list is available.
1345
1345
assert (argList);
1346
1346
1347
1347
// Apply labels to arguments.
@@ -10494,6 +10494,32 @@ bool ConstraintSystem::simplifyAppliedOverloads(
10494
10494
numOptionalUnwraps, locator);
10495
10495
}
10496
10496
10497
+ // / Create an implicit dot-member reference expression to be used
10498
+ // / as a root for injected `.callAsFunction` call.
10499
+ static UnresolvedDotExpr *
10500
+ createImplicitRootForCallAsFunction (ConstraintSystem &cs, Type refType,
10501
+ ArgumentList *arguments,
10502
+ ConstraintLocator *calleeLocator) {
10503
+ auto &ctx = cs.getASTContext ();
10504
+ auto *baseExpr = castToExpr (calleeLocator->getAnchor ());
10505
+
10506
+ SmallVector<Identifier, 2 > closureLabelsScratch;
10507
+ // Create implicit `.callAsFunction` expression to use as an anchor
10508
+ // for new argument list that only has trailing closures in it.
10509
+ auto *implicitRef = UnresolvedDotExpr::createImplicit (
10510
+ ctx, baseExpr, {ctx.Id_callAsFunction },
10511
+ arguments->getArgumentLabels (closureLabelsScratch));
10512
+
10513
+ {
10514
+ // Record a type of the new reference in the constraint system.
10515
+ cs.setType (implicitRef, refType);
10516
+ // Record new `.callAsFunction` in the constraint system.
10517
+ cs.recordCallAsFunction (implicitRef, arguments, calleeLocator);
10518
+ }
10519
+
10520
+ return implicitRef;
10521
+ }
10522
+
10497
10523
ConstraintSystem::SolutionKind
10498
10524
ConstraintSystem::simplifyApplicableFnConstraint (
10499
10525
Type type1, Type type2,
@@ -10548,17 +10574,20 @@ ConstraintSystem::simplifyApplicableFnConstraint(
10548
10574
};
10549
10575
10550
10576
// Local function to form an unsolved result.
10551
- auto formUnsolved = [&] {
10577
+ auto formUnsolved = [&]( bool activate = false ) {
10552
10578
if (flags.contains (TMF_GenerateConstraints)) {
10553
- addUnsolvedConstraint (
10554
- Constraint::createApplicableFunction (
10579
+ auto *application = Constraint::createApplicableFunction (
10555
10580
*this , type1, type2, trailingClosureMatching,
10556
- getConstraintLocator (locator)));
10581
+ getConstraintLocator (locator));
10582
+
10583
+ addUnsolvedConstraint (application);
10584
+ if (activate)
10585
+ activateConstraint (application);
10586
+
10557
10587
return SolutionKind::Solved;
10558
10588
}
10559
10589
10560
10590
return SolutionKind::Unsolved;
10561
-
10562
10591
};
10563
10592
10564
10593
// If right-hand side is a type variable, the constraint is unsolved.
@@ -10633,15 +10662,97 @@ ConstraintSystem::simplifyApplicableFnConstraint(
10633
10662
? ConstraintKind::OperatorArgumentConversion
10634
10663
: ConstraintKind::ArgumentConversion);
10635
10664
10665
+ auto *argumentsLoc = getConstraintLocator (
10666
+ outerLocator.withPathElement (ConstraintLocator::ApplyArgument));
10667
+
10668
+ auto *argumentList = getArgumentList (argumentsLoc);
10636
10669
// The argument type must be convertible to the input type.
10637
10670
auto matchCallResult = ::matchCallArguments (
10638
- *this , func2, func1->getParams (), func2->getParams (), subKind,
10639
- outerLocator.withPathElement (ConstraintLocator::ApplyArgument),
10640
- trailingClosureMatching);
10671
+ *this , func2, argumentList, func1->getParams (), func2->getParams (),
10672
+ subKind, argumentsLoc, trailingClosureMatching);
10641
10673
10642
10674
switch (matchCallResult) {
10643
- case SolutionKind::Error:
10675
+ case SolutionKind::Error: {
10676
+ auto resultTy = func2->getResult ();
10677
+
10678
+ // If this is a call that constructs a callable type with
10679
+ // trailing closure(s), closure(s) might not belong to
10680
+ // the constructor but rather to implicit `callAsFunction`,
10681
+ // there is no way to determine that without trying.
10682
+ if (resultTy->isCallableNominalType (DC) &&
10683
+ argumentList->hasAnyTrailingClosures ()) {
10684
+ auto *calleeLoc = getCalleeLocator (argumentsLoc);
10685
+
10686
+ bool isInit = false ;
10687
+ if (auto overload = findSelectedOverloadFor (calleeLoc)) {
10688
+ isInit = bool (dyn_cast_or_null<ConstructorDecl>(
10689
+ overload->choice .getDeclOrNull ()));
10690
+ }
10691
+
10692
+ if (!isInit)
10693
+ return SolutionKind::Error;
10694
+
10695
+ auto &ctx = getASTContext ();
10696
+ auto numTrailing = argumentList->getNumTrailingClosures ();
10697
+
10698
+ SmallVector<Argument, 4 > newArguments (
10699
+ argumentList->getNonTrailingArgs ());
10700
+ SmallVector<Argument, 4 > trailingClosures (
10701
+ argumentList->getTrailingClosures ());
10702
+
10703
+ // Original argument list with all the trailing closures removed.
10704
+ auto *newArgumentList = ArgumentList::createParsed (
10705
+ ctx, argumentList->getLParenLoc (), newArguments,
10706
+ argumentList->getRParenLoc (),
10707
+ /* firstTrailingClosureIndex=*/ None);
10708
+
10709
+ auto trailingClosureTypes = func1->getParams ().take_back (numTrailing);
10710
+ // The original result type is going to become a result of
10711
+ // implicit `.callAsFunction` instead since `.callAsFunction`
10712
+ // is inserted between `.init` and trailing closures.
10713
+ auto callAsFunctionResultTy = func1->getResult ();
10714
+
10715
+ // The implicit replacement for original result type which
10716
+ // represents a callable type produced by `.init` call.
10717
+ auto callableType =
10718
+ createTypeVariable (getConstraintLocator ({}), /* flags=*/ 0 );
10719
+
10720
+ // The original application type with all the trailing closures
10721
+ // dropped from it and result replaced to the implicit variable.
10722
+ func1 = FunctionType::get (func1->getParams ().drop_back (numTrailing),
10723
+ callableType, func1->getExtInfo ());
10724
+
10725
+ auto matchCallResult = ::matchCallArguments (
10726
+ *this , func2, newArgumentList, func1->getParams (),
10727
+ func2->getParams (), subKind, argumentsLoc, trailingClosureMatching);
10728
+
10729
+ if (matchCallResult != SolutionKind::Solved)
10730
+ return SolutionKind::Error;
10731
+
10732
+ auto *implicitCallArgumentList =
10733
+ ArgumentList::createImplicit (ctx, trailingClosures,
10734
+ /* firstTrailingClosureIndex=*/ 0 );
10735
+
10736
+ auto *implicitRef = createImplicitRootForCallAsFunction (
10737
+ *this , callAsFunctionResultTy, implicitCallArgumentList, calleeLoc);
10738
+
10739
+ auto callAsFunctionArguments =
10740
+ FunctionType::get (trailingClosureTypes, callAsFunctionResultTy,
10741
+ FunctionType::ExtInfo ());
10742
+
10743
+ // Form an unsolved constraint to apply trailing closures to a
10744
+ // callable type produced by `.init`. This constraint would become
10745
+ // active when `callableType` is bound.
10746
+ addUnsolvedConstraint (Constraint::create (
10747
+ *this , ConstraintKind::ApplicableFunction, callAsFunctionArguments,
10748
+ callableType,
10749
+ getConstraintLocator (implicitRef,
10750
+ ConstraintLocator::ApplyFunction)));
10751
+ break ;
10752
+ }
10753
+
10644
10754
return SolutionKind::Error;
10755
+ }
10645
10756
10646
10757
case SolutionKind::Unsolved: {
10647
10758
// Only occurs when there is an ambiguity between forward scanning and
@@ -10691,6 +10802,26 @@ ConstraintSystem::simplifyApplicableFnConstraint(
10691
10802
if (instance2->isTypeVariableOrMember ())
10692
10803
return formUnsolved ();
10693
10804
10805
+ auto *argumentsLoc = getConstraintLocator (
10806
+ outerLocator.withPathElement (ConstraintLocator::ApplyArgument));
10807
+
10808
+ auto *argumentList = getArgumentList (argumentsLoc);
10809
+ assert (argumentList);
10810
+
10811
+ // Cannot simplify construction of callable types during constraint
10812
+ // generation when trailing closures are present because such calls
10813
+ // have special trailing closure matching semantics. It's unclear
10814
+ // whether trailing arguments belong to `.init` or implicit
10815
+ // `.callAsFunction` in this case.
10816
+ //
10817
+ // Note that the constraint has to be activate so that solver attempts
10818
+ // once constraint generation is done.
10819
+ if (getPhase () == ConstraintSystemPhase::ConstraintGeneration &&
10820
+ argumentList->hasAnyTrailingClosures () &&
10821
+ instance2->isCallableNominalType (DC)) {
10822
+ return formUnsolved (/* activate=*/ true );
10823
+ }
10824
+
10694
10825
// Construct the instance from the input arguments.
10695
10826
auto simplified = simplifyConstructionConstraint (instance2, func1, subflags,
10696
10827
/* FIXME?*/ DC,
@@ -11579,6 +11710,7 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
11579
11710
if (!ArgumentLists.count (memberLoc)) {
11580
11711
auto *argList = ArgumentList::createImplicit (
11581
11712
getASTContext (), {Argument (SourceLoc (), Identifier (), nullptr )},
11713
+ /* firstTrailingClosureIndex=*/ None,
11582
11714
AllocationArena::ConstraintSolver);
11583
11715
ArgumentLists.insert ({memberLoc, argList});
11584
11716
}
@@ -11867,6 +11999,15 @@ void ConstraintSystem::recordMatchCallArgumentResult(
11867
11999
argumentMatchingChoices.insert ({locator, result});
11868
12000
}
11869
12001
12002
+ void ConstraintSystem::recordCallAsFunction (UnresolvedDotExpr *root,
12003
+ ArgumentList *arguments,
12004
+ ConstraintLocator *locator) {
12005
+ ImplicitCallAsFunctionRoots.insert ({locator, root});
12006
+
12007
+ associateArgumentList (
12008
+ getConstraintLocator (root, ConstraintLocator::ApplyArgument), arguments);
12009
+ }
12010
+
11870
12011
ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint (
11871
12012
ConstraintFix *fix, Type type1, Type type2, ConstraintKind matchKind,
11872
12013
TypeMatchOptions flags, ConstraintLocatorBuilder locator) {
0 commit comments