mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
We need to have a notion of "complete" binding set before we can allow inference from generic parameters and ternary, otherwise we'd make a favoring decision that might not be correct i.e. `v ?? (<<cond>> ? nil : o)` where `o` is `Int`. `getBindingsFor` doesn't currently infer transitive bindings which means that for a ternary we'd only have a single binding - `Int` which could lead to favoring overload of `??` and has non-optional parameter on the right-hand side.
65 lines
1.7 KiB
Swift
65 lines
1.7 KiB
Swift
// RUN: %target-swift-frontend -dump-ast %s | %FileCheck %s
|
|
|
|
struct B {
|
|
static var _none: B { B() }
|
|
}
|
|
|
|
struct A {
|
|
init(_ other: B) {}
|
|
// CHECK: constructor_decl{{.*}}interface_type="(A.Type) -> (B?) -> A"
|
|
init(_ other: B?) {
|
|
// CHECK: dot_syntax_call_expr type="(B) -> A"
|
|
self.init(other ?? ._none)
|
|
}
|
|
}
|
|
|
|
do {
|
|
class Super {}
|
|
class Sub: Super {}
|
|
|
|
func flatMap<R>(_: (Int) -> R?) -> R? {}
|
|
|
|
func test() {
|
|
let dict: Dictionary<Int, Sub>
|
|
let sup: Super
|
|
|
|
// CHECK: declref_expr type="(consuming Super?, @autoclosure () throws -> Super) throws -> Super" {{.*}} decl="Swift.(file).??
|
|
let x = flatMap { dict[$0] } ?? sup // Ok
|
|
let _: Super = x
|
|
}
|
|
}
|
|
|
|
// Reduced from vapor project. Favoring _only_ an overload of `??` and takes `T?` as a second parameter would result in an invalid solution.
|
|
extension Array where Element == UInt8 {
|
|
init?(decodingBase32 str: String) {
|
|
guard let decoded = str.utf8.withContiguousStorageIfAvailable({ Array(decodingBase32: $0) }) ?? Array(decodingBase32: Array(str.utf8)) else { // Ok
|
|
return nil
|
|
}
|
|
self = decoded
|
|
}
|
|
|
|
init?<C>(decodingBase32 bytes: C) where C: RandomAccessCollection, C.Element == UInt8, C.Index == Int {
|
|
fatalError()
|
|
}
|
|
}
|
|
|
|
func test_no_incorrect_favoring(v: Int?, o: Int) {
|
|
func ternary<T>(_: T, _: T) -> T { fatalError() }
|
|
|
|
func nilCoelesing<T>(_: T?, _: T) -> T { fatalError() }
|
|
func nilCoelesing<T>(_: T?, _: T?) -> T? { fatalError() }
|
|
|
|
let t1 = v ?? (true ? nil : v)
|
|
let t2 = v ?? ternary(nil, o)
|
|
|
|
let s1 = nilCoelesing(v, (true ? nil : v))
|
|
let s2 = nilCoelesing(v, ternary(nil, o))
|
|
|
|
func sameType<T>(_: T, as: T.Type) {}
|
|
|
|
sameType(t1, as: Int?.self)
|
|
sameType(t2, as: Int?.self)
|
|
sameType(s1, as: Int?.self)
|
|
sameType(s2, as: Int?.self)
|
|
}
|