[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.
This commit is contained in:
James Brown
2025-03-30 21:01:35 -04:00
parent e5d0cd4e51
commit 913733f508
2 changed files with 18 additions and 3 deletions

View File

@@ -703,11 +703,16 @@ bool CompareDeclSpecializationRequest::evaluate(
paramIdx != numParams; ++paramIdx) {
const auto &param = 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<Type, 2> 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())

View File

@@ -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) <each τ_0_0 where repeat each τ_0_0 : P> (@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<each T: Q>(_ a: repeat each T) {}
func f<each T: P>(_ a: repeat each T) {}
struct S: Q {}
// CHECK: // function_ref f #1 <each A>(_:) in test_ranking_with_protocol_refinement()
// CHECK-NEXT: {{.*}} = function_ref @$s33variadic_generic_overload_ranking05test_D25_with_protocol_refinementyyF1fL_yyxxQpRvzAA1QRzlF : $@convention(thin) <each τ_0_0 where repeat each τ_0_0 : Q> (@pack_guaranteed Pack{repeat each τ_0_0}) -> ()
f(S())
}