From 35077a01d192c4bff8125abfac936cae67ef34b7 Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Mon, 31 Mar 2025 13:58:38 -0700 Subject: [PATCH 1/3] Revert "Sema: Allow optional-to-optional CGFloat <-> Double conversion" This reverts commit f0f5ffcebf712834a049d6802b166ac69b79a9db. --- lib/Sema/CSSimplify.cpp | 22 ++++++++++++++----- .../implicit_double_cgfloat_conversion.swift | 5 ----- .../rdar83666783.swift | 2 +- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index 33df65a49c802..e291d3457ee3b 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -7489,18 +7489,28 @@ 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() || - location.endsWith()) { + if (location.endsWith()) { SmallVector path; auto anchor = location.getLocatorParts(path); - // Drop all of the applied `value-to-optional` and - // `optional-to-optional` conversions. + // 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. path.erase(llvm::remove_if( path, [](const LocatorPathElt &elt) { - return elt.is() || - elt.is(); + return elt.is(); }), path.end()); diff --git a/test/Constraints/implicit_double_cgfloat_conversion.swift b/test/Constraints/implicit_double_cgfloat_conversion.swift index 94bbb3659d265..c25a48978c61f 100644 --- a/test/Constraints/implicit_double_cgfloat_conversion.swift +++ b/test/Constraints/implicit_double_cgfloat_conversion.swift @@ -349,8 +349,3 @@ 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 232fe78a8fb85..8db0f609b4d13 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) + _ = compute(s?.test) // expected-error {{cannot implicitly convert value of type 'CGFloat?' to expected type 'Double?'}} } From 05798e5f45ec1976179a27f5bcd5740b0fd600d6 Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Mon, 31 Mar 2025 14:34:20 -0700 Subject: [PATCH 2/3] Revert "Sema: Remove dead diagnostic" This reverts commit d56d7045a2489eab8af33d5d71fc65fbaf1a3ebb. --- include/swift/AST/DiagnosticsSema.def | 7 +++++++ lib/Sema/CSDiagnostics.cpp | 16 ++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index 619d8d4ce78c4..b8369fc91d007 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -7563,6 +7563,13 @@ ERROR(result_builder_buildpartialblock_accumulated_not_accessible,none, "expression shuffles the elements of this tuple; " "this behavior is deprecated", ()) +//------------------------------------------------------------------------------ +// MARK: Implicit conversion diagnostics +//------------------------------------------------------------------------------ +ERROR(cannot_implicitly_convert_in_optional_context,none, + "cannot implicitly convert value of type %0 to expected type %1", + (Type, Type)) + //------------------------------------------------------------------------------ // MARK: marker protocol diagnostics //------------------------------------------------------------------------------ diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp index aa6ad3a1af7cb..5383ba2ebaeec 100644 --- a/lib/Sema/CSDiagnostics.cpp +++ b/lib/Sema/CSDiagnostics.cpp @@ -2852,6 +2852,22 @@ bool ContextualFailure::diagnoseAsError() { break; } + case ConstraintLocator::OptionalInjection: { + // If this is an attempt at a Double <-> CGFloat conversion + // through optional chaining, let's produce a tailored diagnostic. + if (isExpr(getAnchor())) { + if ((fromType->isDouble() || fromType->isCGFloat()) && + (toType->isDouble() || toType->isCGFloat())) { + fromType = OptionalType::get(fromType); + toType = OptionalType::get(toType); + diagnostic = diag::cannot_implicitly_convert_in_optional_context; + break; + } + } + + return false; + } + case ConstraintLocator::EnumPatternImplicitCastMatch: { // In this case, the types are reversed, as we are checking whether we // can convert the pattern type to the context type. From 00f0d3ab79cb496e2dcc9ad3981f853e8b13ef36 Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Mon, 31 Mar 2025 14:40:07 -0700 Subject: [PATCH 3/3] [Tests] NFC: Add a few test-cases that should type-check successfully --- .../implicit_double_cgfloat_conversion.swift | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/Constraints/implicit_double_cgfloat_conversion.swift b/test/Constraints/implicit_double_cgfloat_conversion.swift index c25a48978c61f..014b112f8de10 100644 --- a/test/Constraints/implicit_double_cgfloat_conversion.swift +++ b/test/Constraints/implicit_double_cgfloat_conversion.swift @@ -349,3 +349,15 @@ func test_init_validation() { } } } + +func test_ternary_and_nil_coalescing() { + func test(_: Double?) {} + + func ternary(v: CGFloat) { + test(true ? v : nil) // Ok + } + + func test_nil_coalescing(v: CGFloat?) { + test(v ?? 0.0) // Ok + } +}