@@ -633,75 +633,126 @@ bool CompareDeclSpecializationRequest::evaluate(
633
633
auto params1 = funcTy1->getParams ();
634
634
auto params2 = funcTy2->getParams ();
635
635
636
- unsigned numParams1 = params1.size ();
637
- unsigned numParams2 = params2.size ();
638
- if (numParams1 > numParams2)
639
- return completeResult (false );
640
-
641
- // If they both have trailing closures, compare those separately.
642
- bool compareTrailingClosureParamsSeparately = false ;
643
- if (numParams1 > 0 && numParams2 > 0 &&
644
- params1.back ().getParameterType ()->is <AnyFunctionType>() &&
645
- params2.back ().getParameterType ()->is <AnyFunctionType>()) {
646
- compareTrailingClosureParamsSeparately = true ;
647
- }
636
+ // TODO: We should consider merging these two branches together in
637
+ // the future instead of re-implementing `matchCallArguments`.
638
+ if (containsPackExpansionType (params1) ||
639
+ containsPackExpansionType (params2)) {
640
+ ParameterListInfo paramListInfo (params2, decl2, decl2->hasCurriedSelf ());
641
+
642
+ MatchCallArgumentListener listener;
643
+ SmallVector<AnyFunctionType::Param> args (params1);
644
+ auto matching = matchCallArguments (
645
+ args, params2, paramListInfo, llvm::None,
646
+ /* allowFixes=*/ false , listener, TrailingClosureMatching::Forward);
647
+
648
+ if (!matching)
649
+ return completeResult (false );
650
+
651
+ for (unsigned paramIdx = 0 ,
652
+ numParams = matching->parameterBindings .size ();
653
+ paramIdx != numParams; ++paramIdx) {
654
+ const auto ¶m = params2[paramIdx];
655
+ auto paramTy = param.getOldType ();
656
+
657
+ if (paramListInfo.isVariadicGenericParameter (paramIdx) &&
658
+ isPackExpansionType (paramTy)) {
659
+ SmallVector<Type, 2 > argTypes;
660
+ for (auto argIdx : matching->parameterBindings [paramIdx]) {
661
+ // Don't prefer `T...` over `repeat each T`.
662
+ if (args[argIdx].isVariadic ())
663
+ return completeResult (false );
664
+ argTypes.push_back (args[argIdx].getPlainType ());
665
+ }
648
666
649
- auto maybeAddSubtypeConstraint =
650
- [&](const AnyFunctionType::Param ¶m1,
651
- const AnyFunctionType::Param ¶m2) -> bool {
652
- // If one parameter is variadic and the other is not...
653
- if (param1.isVariadic () != param2.isVariadic ()) {
654
- // If the first parameter is the variadic one, it's not
655
- // more specialized.
656
- if (param1.isVariadic ())
657
- return false ;
667
+ auto *argPack = PackType::get (cs.getASTContext (), argTypes);
668
+ cs.addConstraint (ConstraintKind::Subtype,
669
+ PackExpansionType::get (argPack, argPack), paramTy,
670
+ locator);
671
+ continue ;
672
+ }
673
+
674
+ for (auto argIdx : matching->parameterBindings [paramIdx]) {
675
+ const auto &arg = args[argIdx];
676
+ // Always prefer non-variadic version when possible.
677
+ if (arg.isVariadic ())
678
+ return completeResult (false );
658
679
659
- fewerEffectiveParameters = true ;
680
+ cs.addConstraint (ConstraintKind::Subtype, arg.getOldType (),
681
+ paramTy, locator);
682
+ }
683
+ }
684
+ } else {
685
+ unsigned numParams1 = params1.size ();
686
+ unsigned numParams2 = params2.size ();
687
+
688
+ if (numParams1 > numParams2)
689
+ return completeResult (false );
690
+
691
+ // If they both have trailing closures, compare those separately.
692
+ bool compareTrailingClosureParamsSeparately = false ;
693
+ if (numParams1 > 0 && numParams2 > 0 &&
694
+ params1.back ().getParameterType ()->is <AnyFunctionType>() &&
695
+ params2.back ().getParameterType ()->is <AnyFunctionType>()) {
696
+ compareTrailingClosureParamsSeparately = true ;
660
697
}
661
698
662
- Type paramType1 = getAdjustedParamType (param1);
663
- Type paramType2 = getAdjustedParamType (param2);
699
+ auto maybeAddSubtypeConstraint =
700
+ [&](const AnyFunctionType::Param ¶m1,
701
+ const AnyFunctionType::Param ¶m2) -> bool {
702
+ // If one parameter is variadic and the other is not...
703
+ if (param1.isVariadic () != param2.isVariadic ()) {
704
+ // If the first parameter is the variadic one, it's not
705
+ // more specialized.
706
+ if (param1.isVariadic ())
707
+ return false ;
708
+
709
+ fewerEffectiveParameters = true ;
710
+ }
664
711
665
- // Check whether the first parameter is a subtype of the second.
666
- cs.addConstraint (ConstraintKind::Subtype, paramType1, paramType2,
667
- locator);
668
- return true ;
669
- };
670
-
671
- auto pairMatcher = [&](unsigned idx1, unsigned idx2) -> bool {
672
- // Emulate behavior from when IUO was a type, where IUOs
673
- // were considered subtypes of plain optionals, but not
674
- // vice-versa. This wouldn't normally happen, but there are
675
- // cases where we can rename imported APIs so that we have a
676
- // name collision, and where the parameter type(s) are the
677
- // same except for details of the kind of optional declared.
678
- auto param1IsIUO = paramIsIUO (decl1, idx1);
679
- auto param2IsIUO = paramIsIUO (decl2, idx2);
680
- if (param2IsIUO && !param1IsIUO)
681
- return false ;
682
-
683
- if (!maybeAddSubtypeConstraint (params1[idx1], params2[idx2]))
684
- return false ;
712
+ Type paramType1 = getAdjustedParamType (param1);
713
+ Type paramType2 = getAdjustedParamType (param2);
685
714
686
- return true ;
687
- };
715
+ // Check whether the first parameter is a subtype of the second.
716
+ cs.addConstraint (ConstraintKind::Subtype, paramType1, paramType2,
717
+ locator);
718
+ return true ;
719
+ };
688
720
689
- ParameterListInfo paramInfo (params2, decl2, decl2->hasCurriedSelf ());
690
- auto params2ForMatching = params2;
691
- if (compareTrailingClosureParamsSeparately) {
692
- --numParams1;
693
- params2ForMatching = params2.drop_back ();
694
- }
721
+ auto pairMatcher = [&](unsigned idx1, unsigned idx2) -> bool {
722
+ // Emulate behavior from when IUO was a type, where IUOs
723
+ // were considered subtypes of plain optionals, but not
724
+ // vice-versa. This wouldn't normally happen, but there are
725
+ // cases where we can rename imported APIs so that we have a
726
+ // name collision, and where the parameter type(s) are the
727
+ // same except for details of the kind of optional declared.
728
+ auto param1IsIUO = paramIsIUO (decl1, idx1);
729
+ auto param2IsIUO = paramIsIUO (decl2, idx2);
730
+ if (param2IsIUO && !param1IsIUO)
731
+ return false ;
732
+
733
+ if (!maybeAddSubtypeConstraint (params1[idx1], params2[idx2]))
734
+ return false ;
695
735
696
- InputMatcher IM (params2ForMatching, paramInfo);
697
- if (IM.match (numParams1, pairMatcher) != InputMatcher::IM_Succeeded)
698
- return completeResult (false );
736
+ return true ;
737
+ };
738
+
739
+ ParameterListInfo paramInfo (params2, decl2, decl2->hasCurriedSelf ());
740
+ auto params2ForMatching = params2;
741
+ if (compareTrailingClosureParamsSeparately) {
742
+ --numParams1;
743
+ params2ForMatching = params2.drop_back ();
744
+ }
745
+
746
+ InputMatcher IM (params2ForMatching, paramInfo);
747
+ if (IM.match (numParams1, pairMatcher) != InputMatcher::IM_Succeeded)
748
+ return completeResult (false );
699
749
700
- fewerEffectiveParameters |= (IM.getNumSkippedParameters () != 0 );
750
+ fewerEffectiveParameters |= (IM.getNumSkippedParameters () != 0 );
701
751
702
- if (compareTrailingClosureParamsSeparately)
703
- if (!maybeAddSubtypeConstraint (params1.back (), params2.back ()))
704
- knownNonSubtype = true ;
752
+ if (compareTrailingClosureParamsSeparately)
753
+ if (!maybeAddSubtypeConstraint (params1.back (), params2.back ()))
754
+ knownNonSubtype = true ;
755
+ }
705
756
}
706
757
707
758
if (!knownNonSubtype) {
0 commit comments