Skip to content

Commit f183e49

Browse files
committed
stdlib/bridging: bridgeFromObjectiveC() can fail to bridge the Objective-C
object to the desired type. Model this with an optional return type. Swift SVN r18077
1 parent c30901c commit f183e49

File tree

10 files changed

+139
-33
lines changed

10 files changed

+139
-33
lines changed

stdlib/core/BridgeObjectiveC.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ protocol _BridgedToObjectiveC {
8282
class func getObjectiveCType() -> Any.Type
8383

8484
func bridgeToObjectiveC() -> ObjectiveCType
85-
class func bridgeFromObjectiveC(x: ObjectiveCType) -> Self
85+
class func bridgeFromObjectiveC(x: ObjectiveCType) -> Self?
8686
}
8787

8888
/// Whether a given type conforming to this protocol bridges to

stdlib/objc/Foundation/Foundation.swift

+8-8
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ extension String : _BridgedToObjectiveC {
397397
return self
398398
}
399399

400-
static func bridgeFromObjectiveC(x: NSString) -> String {
400+
static func bridgeFromObjectiveC(x: NSString) -> String? {
401401
return String(x)
402402
}
403403
}
@@ -427,7 +427,7 @@ extension Int : _BridgedToObjectiveC {
427427
return self
428428
}
429429

430-
static func bridgeFromObjectiveC(x: NSNumber) -> Int {
430+
static func bridgeFromObjectiveC(x: NSNumber) -> Int? {
431431
fatal("implement")
432432
}
433433
}
@@ -451,7 +451,7 @@ extension UInt : _BridgedToObjectiveC {
451451
return self
452452
}
453453

454-
static func bridgeFromObjectiveC(x: NSNumber) -> UInt {
454+
static func bridgeFromObjectiveC(x: NSNumber) -> UInt? {
455455
fatal("implement")
456456
}
457457
}
@@ -473,7 +473,7 @@ extension Float : _BridgedToObjectiveC {
473473
return self
474474
}
475475

476-
static func bridgeFromObjectiveC(x: NSNumber) -> Float {
476+
static func bridgeFromObjectiveC(x: NSNumber) -> Float? {
477477
fatal("implement")
478478
}
479479
}
@@ -495,7 +495,7 @@ extension Double : _BridgedToObjectiveC {
495495
return self
496496
}
497497

498-
static func bridgeFromObjectiveC(x: NSNumber) -> Double {
498+
static func bridgeFromObjectiveC(x: NSNumber) -> Double? {
499499
fatal("implement")
500500
}
501501
}
@@ -518,7 +518,7 @@ extension Bool: _BridgedToObjectiveC {
518518
return self
519519
}
520520

521-
static func bridgeFromObjectiveC(x: NSNumber) -> Bool {
521+
static func bridgeFromObjectiveC(x: NSNumber) -> Bool? {
522522
fatal("implement")
523523
}
524524
}
@@ -579,7 +579,7 @@ extension Array : _ConditionallyBridgedToObjectiveC {
579579
return reinterpretCast(self.buffer.asCocoaArray())
580580
}
581581

582-
static func bridgeFromObjectiveC(x: NSArray) -> Array<T> {
582+
static func bridgeFromObjectiveC(x: NSArray) -> Array<T>? {
583583
fatal("implement")
584584
}
585585

@@ -699,7 +699,7 @@ extension Dictionary : _ConditionallyBridgedToObjectiveC {
699699
return _convertDictionaryToNSDictionary(self)
700700
}
701701

702-
static func bridgeFromObjectiveC(x: NSDictionary) -> Dictionary {
702+
static func bridgeFromObjectiveC(x: NSDictionary) -> Dictionary? {
703703
fatal("implement")
704704
}
705705
}

stdlib/runtime/Metadata.cpp

+17-2
Original file line numberDiff line numberDiff line change
@@ -2619,7 +2619,7 @@ struct _BridgedToObjectiveCWitnessTable {
26192619

26202620
// func bridgeToObjectiveC() -> ObjectiveCType
26212621
HeapObject *(*bridgeToObjectiveC)(OpaqueValue *self, const Metadata *Self);
2622-
// func bridgeFromObjectiveC(x: ObjectiveCType) -> Self
2622+
// func bridgeFromObjectiveC(x: ObjectiveCType) -> Self?
26232623
OpaqueExistentialContainer (*bridgeFromObjectiveC)(HeapObject *sourceValue,
26242624
const Metadata *self,
26252625
const Metadata *selfType);
@@ -2689,29 +2689,41 @@ extern "C" HeapObject *swift_bridgeToObjectiveC(OpaqueValue *value,
26892689
return nullptr;
26902690
}
26912691

2692+
// @asmname("swift_bridgeFromObjectiveC")
2693+
// func bridgeFromObjectiveC<NativeType>(
2694+
// x: AnyObject, nativeType: NativeType.Type
2695+
// ) -> NativeType?
26922696
extern "C" OpaqueExistentialContainer
26932697
swift_bridgeFromObjectiveC(HeapObject *sourceValue, const Metadata *nativeType,
26942698
const Metadata *nativeType_) {
2699+
// Check if the type conforms to _BridgedToObjectiveC.
26952700
const auto *bridgeWitness = findBridgeWitness(nativeType);
26962701
if (bridgeWitness) {
2702+
// Check if the type also conforms to _ConditionallyBridgedToObjectiveC.
26972703
if (auto conditionalWitness = findConditionalBridgeWitness(nativeType)) {
26982704
if (!conditionalWitness->isBridgedToObjectiveC(nativeType, nativeType)) {
2705+
// This type is not bridged.
2706+
// Release the value because it is passed at +1.
26992707
swift_release(sourceValue);
27002708
return _TFSs26_injectNothingIntoOptionalU__FT_GSqQ__(nativeType);
27012709
}
27022710
}
27032711

2704-
// Check if sourceValue has the type required by the protocol.
2712+
// Check if sourceValue has the ObjectiveCType type required by the
2713+
// protocol.
27052714
const Metadata *objectiveCType =
27062715
bridgeWitness->getObjectiveCType(nativeType, nativeType);
27072716
HeapObject *sourceValueAsObjectiveCType =
27082717
reinterpret_cast<HeapObject *>(const_cast<void *>(swift_dynamicCast(
27092718
reinterpret_cast<const void *>(sourceValue), objectiveCType)));
27102719
if (!sourceValueAsObjectiveCType) {
2720+
// The type is not correct.
27112721
swift_release(sourceValue);
27122722
return _TFSs26_injectNothingIntoOptionalU__FT_GSqQ__(nativeType);
27132723
}
27142724

2725+
// The type matches. bridgeFromObjectiveC returns `Self?`, this function
2726+
// returns `NativeType`, so we don't need to re-wrap the optional.
27152727
return bridgeWitness->bridgeFromObjectiveC(sourceValueAsObjectiveCType,
27162728
nativeType, nativeType);
27172729
}
@@ -2724,6 +2736,8 @@ swift_bridgeFromObjectiveC(HeapObject *sourceValue, const Metadata *nativeType,
27242736
return _TFSs26_injectNothingIntoOptionalU__FT_GSqQ__(nativeType);
27252737
}
27262738

2739+
// sourceValue is bridged verbatim. Box it and pass through
2740+
// injectValueIntoOptional.
27272741
ValueBuffer sourceValueBufer;
27282742
*reinterpret_cast<OpaqueValue **>(&sourceValueBufer) =
27292743
reinterpret_cast<OpaqueValue *>(sourceValue);
@@ -2740,6 +2754,7 @@ swift_bridgeFromObjectiveC(HeapObject *sourceValue, const Metadata *nativeType,
27402754
reinterpret_cast<OpaqueValue *>(&outValue), nativeType);
27412755
}
27422756

2757+
// We could not bridge the value.
27432758
swift_release(sourceValue);
27442759
return _TFSs26_injectNothingIntoOptionalU__FT_GSqQ__(nativeType);
27452760
}

test/Inputs/clang-importer-sdk/swift-modules/Foundation.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ extension String : _BridgedToObjectiveC {
4747
func bridgeToObjectiveC() -> NSString {
4848
return NSString()
4949
}
50-
static func bridgeFromObjectiveC(x: NSString) -> String {
50+
static func bridgeFromObjectiveC(x: NSString) -> String? {
5151
fatal("implement")
5252
}
5353
}
@@ -59,7 +59,7 @@ extension Int : _BridgedToObjectiveC {
5959
func bridgeToObjectiveC() -> NSNumber {
6060
return NSNumber()
6161
}
62-
static func bridgeFromObjectiveC(x: NSNumber) -> Int {
62+
static func bridgeFromObjectiveC(x: NSNumber) -> Int? {
6363
fatal("implement")
6464
}
6565
}

test/SILGen/Inputs/Foundation.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ extension String : _BridgedToObjectiveC {
3838
func bridgeToObjectiveC() -> NSString {
3939
return NSString()
4040
}
41-
static func bridgeFromObjectiveC(x: NSString) -> String {
41+
static func bridgeFromObjectiveC(x: NSString) -> String? {
4242
fatal("implement")
4343
}
4444
}
@@ -50,7 +50,7 @@ extension Int : _BridgedToObjectiveC {
5050
func bridgeToObjectiveC() -> NSNumber {
5151
return NSNumber()
5252
}
53-
static func bridgeFromObjectiveC(x: NSNumber) -> Int {
53+
static func bridgeFromObjectiveC(x: NSNumber) -> Int? {
5454
fatal("implement")
5555
}
5656
}

test/expr/cast/array_bridge.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class B : A, _BridgedToObjectiveC {
1111
func bridgeToObjectiveC() -> A {
1212
return A()
1313
}
14-
class func bridgeFromObjectiveC(x: A) -> B {
14+
class func bridgeFromObjectiveC(x: A) -> B? {
1515
fatal("implement")
1616
}
1717
}
@@ -42,7 +42,7 @@ class F : E, _BridgedToObjectiveC {
4242
func bridgeToObjectiveC() -> E {
4343
return self
4444
}
45-
class func bridgeFromObjectiveC(x: E) -> F {
45+
class func bridgeFromObjectiveC(x: E) -> F? {
4646
fatal("implement")
4747
}
4848
}
@@ -64,7 +64,7 @@ class H : G, _ConditionallyBridgedToObjectiveC {
6464
func bridgeToObjectiveC() -> G {
6565
return self
6666
}
67-
class func bridgeFromObjectiveC(x: G) -> H {
67+
class func bridgeFromObjectiveC(x: G) -> H? {
6868
fatal("implement")
6969
}
7070
class func isBridgedToObjectiveC() -> Bool {
@@ -85,7 +85,7 @@ class I : _BridgedToObjectiveC {
8585
func bridgeToObjectiveC() -> AnyObject {
8686
return self
8787
}
88-
class func bridgeFromObjectiveC(x: AnyObject) -> I {
88+
class func bridgeFromObjectiveC(x: AnyObject) -> I? {
8989
fatal("implement")
9090
}
9191
}

test/stdlib/BridgeNonVerbatim.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ struct X : _BridgedToObjectiveC {
7171
return Tracked(value)
7272
}
7373

74-
static func bridgeFromObjectiveC(x: Tracked) -> X {
74+
static func bridgeFromObjectiveC(x: Tracked) -> X? {
7575
fatal("implement")
7676
}
7777

test/stdlib/Bridgeable.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ struct BridgedValueType : _BridgedToObjectiveC {
3737
func bridgeToObjectiveC() -> C {
3838
return C()
3939
}
40-
static func bridgeFromObjectiveC(x: C) -> BridgedValueType {
40+
static func bridgeFromObjectiveC(x: C) -> BridgedValueType? {
4141
fatal("implement")
4242
}
4343
}
@@ -68,7 +68,7 @@ class BridgedClass : _BridgedToObjectiveC {
6868
func bridgeToObjectiveC() -> C {
6969
return C()
7070
}
71-
class func bridgeFromObjectiveC(x: C) -> BridgedClass {
71+
class func bridgeFromObjectiveC(x: C) -> BridgedClass? {
7272
fatal("implement")
7373
}
7474
}
@@ -86,7 +86,7 @@ struct ConditionallyBridged<T>
8686
func bridgeToObjectiveC() -> C {
8787
return C()
8888
}
89-
static func bridgeFromObjectiveC(x: C) -> ConditionallyBridged<T> {
89+
static func bridgeFromObjectiveC(x: C) -> ConditionallyBridged<T>? {
9090
fatal("implement")
9191
}
9292
static func isBridgedToObjectiveC() -> Bool {

test/stdlib/Dictionary.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -1395,7 +1395,7 @@ struct TestBridgedKeyTy : Equatable, Hashable, Printable, _BridgedToObjectiveC {
13951395
return TestObjCKeyTy(value)
13961396
}
13971397

1398-
static func bridgeFromObjectiveC(x: TestObjCKeyTy) -> TestBridgedKeyTy {
1398+
static func bridgeFromObjectiveC(x: TestObjCKeyTy) -> TestBridgedKeyTy? {
13991399
fatal("implement")
14001400
}
14011401

@@ -1431,7 +1431,7 @@ struct TestBridgedValueTy : Printable, _BridgedToObjectiveC {
14311431
return TestObjCValueTy(value)
14321432
}
14331433

1434-
static func bridgeFromObjectiveC(x: TestObjCValueTy) -> TestBridgedValueTy {
1434+
static func bridgeFromObjectiveC(x: TestObjCValueTy) -> TestBridgedValueTy? {
14351435
fatal("implement")
14361436
}
14371437

0 commit comments

Comments
 (0)