From 7a4bc72d8e7b54e7170b469865249f68259fce75 Mon Sep 17 00:00:00 2001 From: Jamie <2119834+jamieQ@users.noreply.github.com> Date: Fri, 3 Oct 2025 06:23:34 -0500 Subject: [PATCH] [SILGen]: fix a bug in isolated default argument handling Changes in https://github.com/swiftlang/swift/pull/81370 addressed a number of issues with isolated default argument handling. However, there seemed to still be a problem when dealing with isolated default arguments of instance/static methods under the following conditions: - The method contained an isolated default parameter - The method contained a defaulted parameter that expanded to 0 or >1 values - Said parameter was followed by another defaulted parameter The attempted fix here was to adjust the isolated default argument iteration bookkeeping. --- lib/SILGen/SILGenApply.cpp | 1 + test/SILGen/isolated_default_arguments.swift | 63 ++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp index fb0f622b8c050..bfd4c135c32ba 100644 --- a/lib/SILGen/SILGenApply.cpp +++ b/lib/SILGen/SILGenApply.cpp @@ -3202,6 +3202,7 @@ static void emitDelayedArguments(SILGenFunction &SGF, // Otherwise, reset the current index adjustment. } else { indexAdjustment = 0; + indexAdjustmentSite = site; } assert(!siteArgs[argIndex] && diff --git a/test/SILGen/isolated_default_arguments.swift b/test/SILGen/isolated_default_arguments.swift index 627904e6330e7..4202623f74826 100644 --- a/test/SILGen/isolated_default_arguments.swift +++ b/test/SILGen/isolated_default_arguments.swift @@ -161,3 +161,66 @@ func useCallerIsolatedDefaultArg() async { // CHECK: // function_ref default argument 0 of // CHECK-NEXT: [[GEN:%.*]] = function_ref @$s4test24callerIsolatedDefaultArg1xySi_tYaFfA_ : // CHECK-NEXT: [[ARG:%.*]] = apply [[GEN]]() + +// The following tests failed due to a book-keeping error when processing delayed +// isolated arguments in methods with: +// +// - a `self` parameter +// - delayed arguments that expanded to zero or greater than one value +// - a subsequent delayed argument +// +// https://github.com/swiftlang/swift/issues/84647 + +@MainActor +enum E { + static func tupleIsolatedDefaultArgStatic( + _: Int, + x: Int = main_actor_int_x(), + // need not be isolated defaults + tup: (Int, Int) = (1, 2), + i: Int = 0 + ) {} + + static func voidIsolatedDefaultArgStatic( + _: Int, + v: Void = main_actor_void(), + // need not be isolated defaults + tup: (Int, Int) = (1, 2), + i: Int = 0 + ) {} +} + +func testTupleIsolatedDefaultArgStatic() async { + await E.tupleIsolatedDefaultArgStatic(0) +} + +func testVoidIsolatedDefaultArgStatic() async { + await E.voidIsolatedDefaultArgStatic(0) +} + +@MainActor +final class Klazz { + func tupleIsolatedDefaultArgInstanceMethod( + _: Int, + x: Int = main_actor_int_x(), + // need not be isolated defaults + tup: (Int, Int) = (1, 2), + i: Int = 0 + ) {} + + func voidIsolatedDefaultArgInstanceMethod( + _: Int, + v: Void = main_actor_void(), + // need not be isolated defaults + tup: (Int, Int) = (1, 2), + i: Int = 0 + ) {} +} + +func testTupleIsolatedDefaultArgInstanceMethod(_ klazz: Klazz) async { + await klazz.tupleIsolatedDefaultArgInstanceMethod(0) +} + +func testVoidIsolatedDefaultArgInstanceMethod(_ klazz: Klazz) async { + await klazz.voidIsolatedDefaultArgInstanceMethod(0) +}