1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
|
// RUN: %target-typecheck-verify-swift
// REQUIRES: objc_interop
// FIXME: Should go into the standard library.
public extension _ObjectiveCBridgeable {
static func _unconditionallyBridgeFromObjectiveC(_ source: _ObjectiveCType?)
-> Self {
var result: Self?
_forceBridgeFromObjectiveC(source!, result: &result)
return result!
}
}
class Root : Hashable {
func hash(into hasher: inout Hasher) {}
}
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
}
func hash(into hasher: inout Hasher) {}
}
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 '[BridgedToObjC : ObjC]' to type '[BridgedToObjC : BridgedToObjC]'}}
// expected-note@-1 {{arguments to generic parameter 'Value' ('ObjC' and 'BridgedToObjC') are expected to be equal}}
dictBB = dictOB // expected-error{{cannot assign value of type '[ObjC : BridgedToObjC]' to type '[BridgedToObjC : BridgedToObjC]'}}
// expected-note@-1 {{arguments to generic parameter 'Key' ('ObjC' and 'BridgedToObjC') are expected to be equal}}
dictDO = dictBB // expected-error{{cannot assign value of type '[BridgedToObjC : BridgedToObjC]' to type '[DerivesObjC : ObjC]'}}
//expected-note@-1 {{arguments to generic parameter 'Key' ('BridgedToObjC' and 'DerivesObjC') are expected to be equal}}
//expected-note@-2 {{arguments to generic parameter 'Value' ('BridgedToObjC' and 'ObjC') are expected to be equal}}
dictOD = dictBB // expected-error {{cannot assign value of type '[BridgedToObjC : BridgedToObjC]' to type '[ObjC : DerivesObjC]'}}
//expected-note@-1 {{arguments to generic parameter 'Key' ('BridgedToObjC' and 'ObjC') are expected to be equal}}
//expected-note@-2 {{arguments to generic parameter 'Value' ('BridgedToObjC' and 'DerivesObjC') are expected to be equal}}
dictDD = dictBB // expected-error {{cannot assign value of type '[BridgedToObjC : BridgedToObjC]' to type '[DerivesObjC : DerivesObjC]'}}
//expected-note@-1 {{arguments to generic parameter 'Key' ('BridgedToObjC' and 'DerivesObjC') are expected to be equal}}
//expected-note@-2 {{arguments to generic parameter 'Value' ('BridgedToObjC' and 'DerivesObjC') are expected to be equal}}
_ = 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-warning{{forced cast from '[DerivesObjC : ObjC]' to 'Dictionary<BridgedToObjC, BridgedToObjC>' always succeeds; did you mean to use 'as'?}}
}
func testConditionalDowncastBridge() {
let dictRR = Dictionary<Root, Root>()
let dictRO = Dictionary<Root, ObjC>()
let dictOR = Dictionary<ObjC, Root>()
let dictOO = Dictionary<ObjC, ObjC>()
let dictOD = Dictionary<ObjC, DerivesObjC>()
let dictDO = Dictionary<DerivesObjC, ObjC>()
let dictDD = Dictionary<DerivesObjC, DerivesObjC>()
let dictBB = Dictionary<BridgedToObjC, BridgedToObjC>()
let dictBO = Dictionary<BridgedToObjC, ObjC>()
let dictOB = Dictionary<ObjC, BridgedToObjC>()
// Downcast to bridged value types.
if let d = dictRR as? Dictionary<BridgedToObjC, BridgedToObjC> { _ = d }
if let d = dictRR as? Dictionary<BridgedToObjC, ObjC> { _ = d }
if let d = dictRR as? Dictionary<ObjC, BridgedToObjC> { _ = d }
if let d = dictRO as? Dictionary<BridgedToObjC, BridgedToObjC> { _ = d }
if let d = dictRO as? Dictionary<BridgedToObjC, ObjC> { _ = d }
if let d = dictRO as? Dictionary<ObjC, BridgedToObjC> { _ = d }
let d1 = dictBO as Dictionary<BridgedToObjC, BridgedToObjC>
let d2 = dictOB as Dictionary<BridgedToObjC, BridgedToObjC>
// Mixed down/upcasts.
if let d = dictDO as? Dictionary<BridgedToObjC, BridgedToObjC> { _ = d }
// expected-warning@-1{{conditional cast from '[DerivesObjC : ObjC]' to 'Dictionary<BridgedToObjC, BridgedToObjC>' always succeeds}}
_ = dictRR
_ = dictRO
_ = dictOR
_ = dictOO
_ = dictOD
_ = dictDO
_ = dictDD
_ = dictBB
_ = dictBO
_ = dictOB
_ = d1
_ = d2
}
|