From 692d828e2c30019202a25ff85b1ff99902a798a5 Mon Sep 17 00:00:00 2001 From: kntkymt Date: Sun, 22 Jun 2025 15:48:28 +0900 Subject: [PATCH 1/3] Add getNumCurryLevels() to AnyFunctionType --- include/swift/AST/Types.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h index e8dc2b3d1216e..89154c097e8df 100644 --- a/include/swift/AST/Types.h +++ b/include/swift/AST/Types.h @@ -3884,6 +3884,17 @@ class AnyFunctionType : public TypeBase { return containsPackExpansionType(getParams()); } + /// Returns the number of curry levels of the function type. + unsigned getNumCurryLevels() const { + unsigned num = 1; + auto fn = this; + while (auto resultFn = fn->getResult()->getAs()) { + num++; + fn = resultFn; + } + return num; + } + static bool containsPackExpansionType(ArrayRef params); static void printParams(ArrayRef Params, raw_ostream &OS, From e898bda66b70ed7b20886b9a22db7c4488e1e43e Mon Sep 17 00:00:00 2001 From: kntkymt Date: Sun, 22 Jun 2025 15:53:08 +0900 Subject: [PATCH 2/3] check curryLevels at repairByInsertingExplicitCall not to repair conversion of functions with same curryLevels --- lib/Sema/CSSimplify.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index 7266ac632853a..b9d9b4dd385ef 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -5347,10 +5347,12 @@ bool ConstraintSystem::repairFailures( // this by forming an explicit call. auto convertTo = dstType->lookThroughAllOptionalTypes(); - // If the RHS is a function type, the source must be a function-returning - // function. - if (convertTo->is() && !resultType->is()) - return false; + // If the RHS is a function type, + // the source must have more curry levels. + if (auto convertToFnType = convertTo->getAs()) { + if (fnType->getNumCurryLevels() <= convertToFnType->getNumCurryLevels()) + return false; + } // Right-hand side can't be a type variable or dependent member, or `Any` // (if function conversion to `Any` didn't succeed there is something else From 0f98c1b7317a1ac52fd5fc6d961ed7d4f1c1bbed Mon Sep 17 00:00:00 2001 From: kntkymt Date: Sun, 22 Jun 2025 16:04:17 +0900 Subject: [PATCH 3/3] Add test for function-returning function conversion --- test/Constraints/closures.swift | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/Constraints/closures.swift b/test/Constraints/closures.swift index 26547edae4053..8e76342f255a3 100644 --- a/test/Constraints/closures.swift +++ b/test/Constraints/closures.swift @@ -1366,3 +1366,14 @@ do { try $0.missing // expected-error {{value of type 'Int' has no member 'missing'}} } } + +do { + let a: () -> () -> Void = {{}} + let _: (() -> () -> Void)? = a + let _: (() -> () -> Void)?? = a + + class Super {} + class Sub: Super {} + let b: () -> () -> Sub = {{ return Sub() }} + let _: (() -> () -> Super)? = b +}