@@ -567,75 +567,126 @@ bool CompareDeclSpecializationRequest::evaluate(
567
567
auto params1 = funcTy1->getParams ();
568
568
auto params2 = funcTy2->getParams ();
569
569
570
- unsigned numParams1 = params1.size ();
571
- unsigned numParams2 = params2.size ();
572
- if (numParams1 > numParams2)
573
- return completeResult (false );
574
-
575
- // If they both have trailing closures, compare those separately.
576
- bool compareTrailingClosureParamsSeparately = false ;
577
- if (numParams1 > 0 && numParams2 > 0 &&
578
- params1.back ().getParameterType ()->is <AnyFunctionType>() &&
579
- params2.back ().getParameterType ()->is <AnyFunctionType>()) {
580
- compareTrailingClosureParamsSeparately = true ;
581
- }
570
+ // TODO: We should consider merging these two branches together in
571
+ // the future instead of re-implementing `matchCallArguments`.
572
+ if (containsPackExpansionType (params1) ||
573
+ containsPackExpansionType (params2)) {
574
+ ParameterListInfo paramListInfo (params2, decl2, decl2->hasCurriedSelf ());
575
+
576
+ MatchCallArgumentListener listener;
577
+ SmallVector<AnyFunctionType::Param> args (params1);
578
+ auto matching = matchCallArguments (
579
+ args, params2, paramListInfo, llvm::None,
580
+ /* allowFixes=*/ false , listener, TrailingClosureMatching::Forward);
581
+
582
+ if (!matching)
583
+ return completeResult (false );
584
+
585
+ for (unsigned paramIdx = 0 ,
586
+ numParams = matching->parameterBindings .size ();
587
+ paramIdx != numParams; ++paramIdx) {
588
+ const auto ¶m = params2[paramIdx];
589
+ auto paramTy = param.getOldType ();
590
+
591
+ if (paramListInfo.isVariadicGenericParameter (paramIdx) &&
592
+ isPackExpansionType (paramTy)) {
593
+ SmallVector<Type, 2 > argTypes;
594
+ for (auto argIdx : matching->parameterBindings [paramIdx]) {
595
+ // Don't prefer `T...` over `repeat each T`.
596
+ if (args[argIdx].isVariadic ())
597
+ return completeResult (false );
598
+ argTypes.push_back (args[argIdx].getPlainType ());
599
+ }
582
600
583
- auto maybeAddSubtypeConstraint =
584
- [&](const AnyFunctionType::Param ¶m1,
585
- const AnyFunctionType::Param ¶m2) -> bool {
586
- // If one parameter is variadic and the other is not...
587
- if (param1.isVariadic () != param2.isVariadic ()) {
588
- // If the first parameter is the variadic one, it's not
589
- // more specialized.
590
- if (param1.isVariadic ())
591
- return false ;
601
+ auto *argPack = PackType::get (cs.getASTContext (), argTypes);
602
+ cs.addConstraint (ConstraintKind::Subtype,
603
+ PackExpansionType::get (argPack, argPack), paramTy,
604
+ locator);
605
+ continue ;
606
+ }
607
+
608
+ for (auto argIdx : matching->parameterBindings [paramIdx]) {
609
+ const auto &arg = args[argIdx];
610
+ // Always prefer non-variadic version when possible.
611
+ if (arg.isVariadic ())
612
+ return completeResult (false );
592
613
593
- fewerEffectiveParameters = true ;
614
+ cs.addConstraint (ConstraintKind::Subtype, arg.getOldType (),
615
+ paramTy, locator);
616
+ }
617
+ }
618
+ } else {
619
+ unsigned numParams1 = params1.size ();
620
+ unsigned numParams2 = params2.size ();
621
+
622
+ if (numParams1 > numParams2)
623
+ return completeResult (false );
624
+
625
+ // If they both have trailing closures, compare those separately.
626
+ bool compareTrailingClosureParamsSeparately = false ;
627
+ if (numParams1 > 0 && numParams2 > 0 &&
628
+ params1.back ().getParameterType ()->is <AnyFunctionType>() &&
629
+ params2.back ().getParameterType ()->is <AnyFunctionType>()) {
630
+ compareTrailingClosureParamsSeparately = true ;
594
631
}
595
632
596
- Type paramType1 = getAdjustedParamType (param1);
597
- Type paramType2 = getAdjustedParamType (param2);
633
+ auto maybeAddSubtypeConstraint =
634
+ [&](const AnyFunctionType::Param ¶m1,
635
+ const AnyFunctionType::Param ¶m2) -> bool {
636
+ // If one parameter is variadic and the other is not...
637
+ if (param1.isVariadic () != param2.isVariadic ()) {
638
+ // If the first parameter is the variadic one, it's not
639
+ // more specialized.
640
+ if (param1.isVariadic ())
641
+ return false ;
642
+
643
+ fewerEffectiveParameters = true ;
644
+ }
598
645
599
- // Check whether the first parameter is a subtype of the second.
600
- cs.addConstraint (ConstraintKind::Subtype, paramType1, paramType2,
601
- locator);
602
- return true ;
603
- };
604
-
605
- auto pairMatcher = [&](unsigned idx1, unsigned idx2) -> bool {
606
- // Emulate behavior from when IUO was a type, where IUOs
607
- // were considered subtypes of plain optionals, but not
608
- // vice-versa. This wouldn't normally happen, but there are
609
- // cases where we can rename imported APIs so that we have a
610
- // name collision, and where the parameter type(s) are the
611
- // same except for details of the kind of optional declared.
612
- auto param1IsIUO = paramIsIUO (decl1, idx1);
613
- auto param2IsIUO = paramIsIUO (decl2, idx2);
614
- if (param2IsIUO && !param1IsIUO)
615
- return false ;
616
-
617
- if (!maybeAddSubtypeConstraint (params1[idx1], params2[idx2]))
618
- return false ;
646
+ Type paramType1 = getAdjustedParamType (param1);
647
+ Type paramType2 = getAdjustedParamType (param2);
619
648
620
- return true ;
621
- };
649
+ // Check whether the first parameter is a subtype of the second.
650
+ cs.addConstraint (ConstraintKind::Subtype, paramType1, paramType2,
651
+ locator);
652
+ return true ;
653
+ };
622
654
623
- ParameterListInfo paramInfo (params2, decl2, decl2->hasCurriedSelf ());
624
- auto params2ForMatching = params2;
625
- if (compareTrailingClosureParamsSeparately) {
626
- --numParams1;
627
- params2ForMatching = params2.drop_back ();
628
- }
655
+ auto pairMatcher = [&](unsigned idx1, unsigned idx2) -> bool {
656
+ // Emulate behavior from when IUO was a type, where IUOs
657
+ // were considered subtypes of plain optionals, but not
658
+ // vice-versa. This wouldn't normally happen, but there are
659
+ // cases where we can rename imported APIs so that we have a
660
+ // name collision, and where the parameter type(s) are the
661
+ // same except for details of the kind of optional declared.
662
+ auto param1IsIUO = paramIsIUO (decl1, idx1);
663
+ auto param2IsIUO = paramIsIUO (decl2, idx2);
664
+ if (param2IsIUO && !param1IsIUO)
665
+ return false ;
666
+
667
+ if (!maybeAddSubtypeConstraint (params1[idx1], params2[idx2]))
668
+ return false ;
629
669
630
- InputMatcher IM (params2ForMatching, paramInfo);
631
- if (IM.match (numParams1, pairMatcher) != InputMatcher::IM_Succeeded)
632
- return completeResult (false );
670
+ return true ;
671
+ };
672
+
673
+ ParameterListInfo paramInfo (params2, decl2, decl2->hasCurriedSelf ());
674
+ auto params2ForMatching = params2;
675
+ if (compareTrailingClosureParamsSeparately) {
676
+ --numParams1;
677
+ params2ForMatching = params2.drop_back ();
678
+ }
679
+
680
+ InputMatcher IM (params2ForMatching, paramInfo);
681
+ if (IM.match (numParams1, pairMatcher) != InputMatcher::IM_Succeeded)
682
+ return completeResult (false );
633
683
634
- fewerEffectiveParameters |= (IM.getNumSkippedParameters () != 0 );
684
+ fewerEffectiveParameters |= (IM.getNumSkippedParameters () != 0 );
635
685
636
- if (compareTrailingClosureParamsSeparately)
637
- if (!maybeAddSubtypeConstraint (params1.back (), params2.back ()))
638
- knownNonSubtype = true ;
686
+ if (compareTrailingClosureParamsSeparately)
687
+ if (!maybeAddSubtypeConstraint (params1.back (), params2.back ()))
688
+ knownNonSubtype = true ;
689
+ }
639
690
}
640
691
641
692
if (!knownNonSubtype) {
0 commit comments