Files
swift-mirror/test/Constraints/bidirectional_conversions.swift
Pavel Yaskevich 69bd48e2ea [CSSimplify] CGFloat-Double: Rank narrowing correctly when result is injected into an optional
If result of `CGFloat` -> `Double` conversion is injected into an optional
it should be ranked based on depth just like when locator is fully simplified.

For example:

```swift
func test(v: CGFloat?) {
   _ = v ?? 2.0 / 3.0
}
```

In this expression division should be performed on `Double` and result
narrowed down (based on the rule that narrowing conversion should always
be delayed) but `Double` -> `CGFloat?` was given an incorrect score and
instead of picking `?? (_: T?, _: T) -> T` overload, the solver would
use `?? (_: T?, _: T?) -> T?`.

(cherry picked from commit cb876cbd9e)
2025-06-27 23:43:09 -07:00

113 lines
2.1 KiB
Swift

// RUN: %target-typecheck-verify-swift
// REQUIRES: objc_interop
import Foundation
import CoreGraphics
/////////////
struct G<T> {
var t: T
}
func foo1(x: (x: Int, y: Int)?, y: (Int, Int)) -> G<(x: Int, y: Int)> {
let g = G(t: x ?? y)
return g
}
func foo2(x: (Int, Int)?, y: (x: Int, y: Int)) -> G<(Int, Int)> {
let g = G(t: x ?? y)
return g
}
func foo3(x: (@convention(block) () -> ())?, y: @escaping () -> ()) -> G<@convention(block) () -> ()> {
let g = G(t: x ?? y)
return g
}
func foo4(x: (() -> ())?, y: @escaping @convention(block) () -> ()) -> G<() -> ()> {
let g = G(t: x ?? y)
return g
}
func foo5(x: CGFloat?, y: Double) -> G<CGFloat> {
let g = G(t: x ?? y)
return g
}
func foo6(x: Double?, y: CGFloat) -> G<Double> {
let g = G(t: x ?? y)
return g
}
/////////////
func id<T>(_: T) -> T {}
func bar1(x: (x: Int, y: Int)) {
func f(_: (Int, Int)) {}
f(id(x))
}
func bar2(x: (Int, Int)) {
func f(_: (x: Int, y: Int)) {}
f(id(x))
}
func bar3(x: @escaping () -> ()) {
func f(_: @escaping @convention(block) () -> ()) {}
// FIXME
f(id(x)) // expected-error {{conflicting arguments to generic parameter 'T' ('@convention(block) () -> ()' vs. '() -> ()')}}
}
func bar4(x: @escaping @convention(block) () -> ()) {
func f(_: @escaping () -> ()) {}
// FIXME
f(id(x)) // expected-error {{conflicting arguments to generic parameter 'T' ('() -> ()' vs. '@convention(block) () -> ()')}}
}
func bar5(x: Double) {
func f(_: CGFloat) {}
f(id(x))
}
func bar6(x: CGFloat) {
func f(_: Double) {}
f(id(x))
}
/////////////
func unwrap<T>(_: T?) -> T {}
func baz1(x: (x: Int, y: Int)?) {
func f(_: (Int, Int)) {}
f(unwrap(x))
}
func baz2(x: (Int, Int)?) {
func f(_: (x: Int, y: Int)) {}
f(unwrap(x))
}
func baz3(x: (() -> ())?) {
func f(_: @escaping @convention(block) () -> ()) {}
f(unwrap(x))
}
func baz4(x: (@convention(block) () -> ())?) {
func f(_: @escaping () -> ()) {}
f(unwrap(x))
}
func baz5(x: Double?) {
func f(_: CGFloat) {}
f(unwrap(x))
}
func baz6(x: CGFloat?) {
func f(_: Double) {}
f(unwrap(x))
}