mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Sema: Disambiguate some more bidirectional conversions
This fixes an ambiguity introduced by the stdlib change in
0f99458900.
Since (borrowing T) -> () and (T) -> () both convert to
each other, we could end up with ambiguous solutions where
neither one was better than the other. Generalize the
existing trick we use for labeled vs unlabeled tuples to
also strip off ownership specifiers and @convention(...)
from function types. This fixes the regression, as well
an existing FIXME in a test I added a while ago where
the same problem arises with @convention(block).
This commit is contained in:
@@ -43,3 +43,37 @@ func baz2(x: (Int, Int)?) {
|
||||
func f(_: (x: Int, y: Int)) {}
|
||||
f(unwrap(x))
|
||||
}
|
||||
|
||||
/////////////
|
||||
|
||||
func borrowingFn(fn: @escaping (borrowing AnyObject) -> ()) -> (AnyObject) -> () {
|
||||
return id(id(fn))
|
||||
}
|
||||
|
||||
/////////////
|
||||
|
||||
infix operator <+
|
||||
infix operator >+
|
||||
|
||||
protocol P {
|
||||
static func <+ (lhs: borrowing Self, rhs: borrowing Self)
|
||||
static func >+ (lhs: borrowing Self, rhs: borrowing Self)
|
||||
}
|
||||
|
||||
extension P {
|
||||
static func >+ (lhs: borrowing Self, rhs: borrowing Self) {}
|
||||
}
|
||||
|
||||
struct S: P {
|
||||
static func <+ (lhs: Self, rhs: Self) {}
|
||||
}
|
||||
|
||||
let _: (S, S) -> () = false ? (<+) : (>+)
|
||||
|
||||
/////////////
|
||||
|
||||
struct MyString: Comparable {
|
||||
static func < (lhs: Self, rhs: Self) -> Bool { fatalError() }
|
||||
}
|
||||
|
||||
let _: (MyString, MyString) -> Bool = false ? (<) : (>)
|
||||
|
||||
@@ -36,14 +36,12 @@ func id<T>(_: T) -> T {}
|
||||
|
||||
func bar3(x: @escaping () -> ()) {
|
||||
func f(_: @escaping @convention(block) () -> ()) {}
|
||||
// FIXME
|
||||
f(id(x)) // expected-error {{conflicting arguments to generic parameter 'T' ('@convention(block) () -> ()' vs. '() -> ()')}}
|
||||
f(id(x))
|
||||
}
|
||||
|
||||
func bar4(x: @escaping @convention(block) () -> ()) {
|
||||
func f(_: @escaping () -> ()) {}
|
||||
// FIXME
|
||||
f(id(x)) // expected-error {{conflicting arguments to generic parameter 'T' ('() -> ()' vs. '@convention(block) () -> ()')}}
|
||||
f(id(x))
|
||||
}
|
||||
|
||||
func bar5(x: Double) {
|
||||
|
||||
Reference in New Issue
Block a user