blob: 7589538137d63ec2153d829e7309cc31b365b98b [file] [log] [blame]
// RUN: %target-parse-verify-swift
// REQUIRES: objc_interop
// FIXME: Should go into the standard library.
public extension _ObjectiveCBridgeable {
static func _unconditionallyBridgeFromObjectiveC(_ source: _ObjectiveCType?)
-> Self {
var result: Self? = nil
_forceBridgeFromObjectiveC(source!, result: &result)
return result!
}
}
class Root : Hashable {
var hashValue: Int {
return 0
}
}
func ==(x: Root, y: Root) -> Bool { return true }
class ObjC : Root {
var x = 0
}
class DerivesObjC : ObjC { }
struct BridgedToObjC : Hashable, _ObjectiveCBridgeable {
func _bridgeToObjectiveC() -> ObjC {
return ObjC()
}
static func _forceBridgeFromObjectiveC(
_ x: ObjC,
result: inout BridgedToObjC?
) {
}
static func _conditionallyBridgeFromObjectiveC(
_ x: ObjC,
result: inout BridgedToObjC?
) -> Bool {
return true
}
var hashValue: Int {
return 0
}
}
func ==(x: BridgedToObjC, y: BridgedToObjC) -> Bool { return true }
func testUpcastBridge() {
var dictRR = Dictionary<Root, Root>()
var dictRO = Dictionary<Root, ObjC>()
var dictOR = Dictionary<ObjC, Root>()
var dictOO = Dictionary<ObjC, ObjC>()
var dictOD = Dictionary<ObjC, DerivesObjC>()
var dictDO = Dictionary<DerivesObjC, ObjC>()
var dictDD = Dictionary<DerivesObjC, DerivesObjC>()
var dictBB = Dictionary<BridgedToObjC, BridgedToObjC>()
var dictBO = Dictionary<BridgedToObjC, ObjC>()
var dictOB = Dictionary<ObjC, BridgedToObjC>()
// Upcast to object types.
dictRR = dictBB as [Root: Root]
dictRR = dictBO as [Root: Root]
dictRR = dictOB as [Root: Root]
dictRO = dictBB as [Root: ObjC]
dictRO = dictBO as [Root: ObjC]
dictRO = dictOB as [Root: ObjC]
dictOR = dictBB as [ObjC: Root]
dictOR = dictBO as [ObjC: Root]
dictOR = dictOB as [ObjC: Root]
dictOO = dictBB as [ObjC: ObjC]
dictOO = dictBO as [ObjC: ObjC]
dictOO = dictOB as [ObjC: ObjC]
// Upcast key or value to object type (but not both)
dictBO = dictBB as [BridgedToObjC: ObjC]
dictOB = dictBB as [ObjC: BridgedToObjC]
dictBB = dictBO // expected-error{{cannot assign value of type 'Dictionary<BridgedToObjC, ObjC>' to type 'Dictionary<BridgedToObjC, BridgedToObjC>'}}
dictBB = dictOB // expected-error{{cannot assign value of type 'Dictionary<ObjC, BridgedToObjC>' to type 'Dictionary<BridgedToObjC, BridgedToObjC>'}}
dictDO = dictBB // expected-error{{cannot assign value of type 'Dictionary<BridgedToObjC, BridgedToObjC>' to type 'Dictionary<DerivesObjC, ObjC>'}}
dictOD = dictBB // expected-error{{cannot assign value of type 'Dictionary<BridgedToObjC, BridgedToObjC>' to type 'Dictionary<ObjC, DerivesObjC>'}}
dictDD = dictBB // expected-error{{cannot assign value of type 'Dictionary<BridgedToObjC, BridgedToObjC>' to type 'Dictionary<DerivesObjC, DerivesObjC>'}}
_ = dictDD; _ = dictDO; _ = dictOD; _ = dictOO; _ = dictOR; _ = dictOR; _ = dictRR; _ = dictRO
}
func testDowncastBridge() {
let dictRR = Dictionary<Root, Root>()
let dictRO = Dictionary<Root, ObjC>()
_ = Dictionary<ObjC, Root>()
_ = Dictionary<ObjC, ObjC>()
_ = Dictionary<ObjC, DerivesObjC>()
let dictDO = Dictionary<DerivesObjC, ObjC>()
_ = Dictionary<DerivesObjC, DerivesObjC>()
_ = Dictionary<BridgedToObjC, BridgedToObjC>()
let dictBO = Dictionary<BridgedToObjC, ObjC>()
let dictOB = Dictionary<ObjC, BridgedToObjC>()
// Downcast to bridged value types.
_ = dictRR as! Dictionary<BridgedToObjC, BridgedToObjC>
_ = dictRR as! Dictionary<BridgedToObjC, ObjC>
_ = dictRR as! Dictionary<ObjC, BridgedToObjC>
_ = dictRO as! Dictionary<BridgedToObjC, BridgedToObjC>
_ = dictRO as! Dictionary<BridgedToObjC, ObjC>
_ = dictRO as! Dictionary<ObjC, BridgedToObjC>
_ = dictBO as Dictionary<BridgedToObjC, BridgedToObjC>
_ = dictOB as Dictionary<BridgedToObjC, BridgedToObjC>
// We don't do mixed down/upcasts.
_ = dictDO as! Dictionary<BridgedToObjC, BridgedToObjC> // expected-error{{'Dictionary<DerivesObjC, ObjC>' is not convertible to 'Dictionary<BridgedToObjC, BridgedToObjC>'}}
}
func testConditionalDowncastBridge() {
var dictRR = Dictionary<Root, Root>()
var dictRO = Dictionary<Root, ObjC>()
var dictOR = Dictionary<ObjC, Root>()
var dictOO = Dictionary<ObjC, ObjC>()
var dictOD = Dictionary<ObjC, DerivesObjC>()
var dictDO = Dictionary<DerivesObjC, ObjC>()
var dictDD = Dictionary<DerivesObjC, DerivesObjC>()
var dictBB = Dictionary<BridgedToObjC, BridgedToObjC>()
var dictBO = Dictionary<BridgedToObjC, ObjC>()
var dictOB = Dictionary<ObjC, BridgedToObjC>()
// Downcast to bridged value types.
if let d = dictRR as? Dictionary<BridgedToObjC, BridgedToObjC> { }
if let d = dictRR as? Dictionary<BridgedToObjC, ObjC> { }
if let d = dictRR as? Dictionary<ObjC, BridgedToObjC> { }
if let d = dictRO as? Dictionary<BridgedToObjC, BridgedToObjC> { }
if let d = dictRO as? Dictionary<BridgedToObjC, ObjC> { }
if let d = dictRO as? Dictionary<ObjC, BridgedToObjC> { }
let d1 = dictBO as Dictionary<BridgedToObjC, BridgedToObjC>
let d2 = dictOB as Dictionary<BridgedToObjC, BridgedToObjC>
// We don't do mixed down/upcasts.
if let d = dictDO as? Dictionary<BridgedToObjC, BridgedToObjC> { } // expected-error{{'Dictionary<DerivesObjC, ObjC>' is not convertible to 'Dictionary<BridgedToObjC, BridgedToObjC>'}}
}