From 913733f508be5b2169ea69cd263fc44c03a52c69 Mon Sep 17 00:00:00 2001 From: James Brown Date: Sun, 30 Mar 2025 21:01:35 -0400 Subject: [PATCH] [CS] Dont wrap packexp in extra layer of expansion Arguments that were already pack expansions were being wrapped in a second layer--preventing some would-be unambiguous overloads from resolving. This adds a check to avoid doing that. --- lib/Sema/CSRanking.cpp | 11 ++++++++--- .../variadic_generic_overload_ranking.swift | 10 ++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/lib/Sema/CSRanking.cpp b/lib/Sema/CSRanking.cpp index acd0dffa4b5..81b6680b9e0 100644 --- a/lib/Sema/CSRanking.cpp +++ b/lib/Sema/CSRanking.cpp @@ -703,11 +703,16 @@ bool CompareDeclSpecializationRequest::evaluate( paramIdx != numParams; ++paramIdx) { const auto ¶m = params2[paramIdx]; auto paramTy = param.getOldType(); + auto argIndices = matching->parameterBindings[paramIdx]; + if (argIndices.empty()) + continue; if (paramListInfo.isVariadicGenericParameter(paramIdx) && - isPackExpansionType(paramTy)) { + isPackExpansionType(paramTy) && + (argIndices.size() > 1 || + !isPackExpansionType(args[argIndices.front()].getOldType()))) { SmallVector argTypes; - for (auto argIdx : matching->parameterBindings[paramIdx]) { + for (auto argIdx : argIndices) { // Don't prefer `T...` over `repeat each T`. if (args[argIdx].isVariadic()) return completeResult(false); @@ -721,7 +726,7 @@ bool CompareDeclSpecializationRequest::evaluate( continue; } - for (auto argIdx : matching->parameterBindings[paramIdx]) { + for (auto argIdx : argIndices) { const auto &arg = args[argIdx]; // Always prefer non-variadic version when possible. if (arg.isVariadic()) diff --git a/test/Constraints/variadic_generic_overload_ranking.swift b/test/Constraints/variadic_generic_overload_ranking.swift index 72018e72b27..dc1ff3f1c0d 100644 --- a/test/Constraints/variadic_generic_overload_ranking.swift +++ b/test/Constraints/variadic_generic_overload_ranking.swift @@ -85,3 +85,13 @@ func test_ranking_with_multiple_expansions() { // CHECK-NEXT: {{.*}} = function_ref @$s33variadic_generic_overload_ranking05test_D25_with_multiple_expansionsyyF7BuilderL_V5buildyAaByyF5TupleL_VyxxQp_tGxxQpRvzAA1PRzlFZ : $@convention(method) (@pack_guaranteed Pack{repeat each τ_0_0}, @thin Builder.Type) -> Tuple<(repeat each τ_0_0)> _ = Builder.build(Empty(), Tuple<(Int, String)>((42, ""))) } +protocol Q: P {} + +func test_ranking_with_protocol_refinement() { + func f(_ a: repeat each T) {} + func f(_ a: repeat each T) {} + struct S: Q {} + // CHECK: // function_ref f #1 (_:) in test_ranking_with_protocol_refinement() + // CHECK-NEXT: {{.*}} = function_ref @$s33variadic_generic_overload_ranking05test_D25_with_protocol_refinementyyF1fL_yyxxQpRvzAA1QRzlF : $@convention(thin) (@pack_guaranteed Pack{repeat each τ_0_0}) -> () + f(S()) +}