From f0f5ffcebf712834a049d6802b166ac69b79a9db Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Mon, 27 Jan 2025 16:39:06 -0500 Subject: [PATCH] Sema: Allow optional-to-optional CGFloat <-> Double conversion After https://github.com/swiftlang/swift/pull/78957, there is no technical reason to not allow this conversion. This is needed for an upcoming optimization. --- lib/Sema/CSSimplify.cpp | 22 +++++-------------- .../implicit_double_cgfloat_conversion.swift | 5 +++++ .../rdar83666783.swift | 2 +- 3 files changed, 12 insertions(+), 17 deletions(-) diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index d4940956288eb..960a2486202dc 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -7392,28 +7392,18 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind, // Look through all value-to-optional promotions to allow // conversions like Double -> CGFloat?? and vice versa. // T -> Optional - if (location.endsWith()) { + if (location.endsWith() || + location.endsWith()) { SmallVector path; auto anchor = location.getLocatorParts(path); - // An attempt at Double/CGFloat conversion through - // optional chaining. This is not supported at the - // moment because solution application doesn't know - // how to map Double to/from CGFloat through optionals. - if (isExpr(anchor)) { - if (!shouldAttemptFixes()) - return getTypeMatchFailure(locator); - - conversionsOrFixes.push_back(ContextualMismatch::create( - *this, nominal1, nominal2, getConstraintLocator(locator))); - break; - } - - // Drop all of the applied `value-to-optional` promotions. + // Drop all of the applied `value-to-optional` and + // `optional-to-optional` conversions. path.erase(llvm::remove_if( path, [](const LocatorPathElt &elt) { - return elt.is(); + return elt.is() || + elt.is(); }), path.end()); diff --git a/test/Constraints/implicit_double_cgfloat_conversion.swift b/test/Constraints/implicit_double_cgfloat_conversion.swift index 32126db0864d0..a70f3c6dfd39f 100644 --- a/test/Constraints/implicit_double_cgfloat_conversion.swift +++ b/test/Constraints/implicit_double_cgfloat_conversion.swift @@ -342,3 +342,8 @@ func test_init_validation() { } } } + +// Optional-to-optional conversion +func optional_to_optional(x: CGFloat?) -> Double? { + return x +} diff --git a/validation-test/Sema/type_checker_crashers_fixed/rdar83666783.swift b/validation-test/Sema/type_checker_crashers_fixed/rdar83666783.swift index 8db0f609b4d13..232fe78a8fb85 100644 --- a/validation-test/Sema/type_checker_crashers_fixed/rdar83666783.swift +++ b/validation-test/Sema/type_checker_crashers_fixed/rdar83666783.swift @@ -12,5 +12,5 @@ func compute(_: Double?) -> Double? { } func test(s: S?) { - _ = compute(s?.test) // expected-error {{cannot implicitly convert value of type 'CGFloat?' to expected type 'Double?'}} + _ = compute(s?.test) }