From c593d49b087cfe97be476a68f144d4e1590a2fb1 Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Sat, 2 Aug 2014 01:03:41 +0000 Subject: [PATCH] Rework the _ObjectiveCBridgeable to use inout parameters rather than returns. The _forceBridgeFromObjectiveC and _conditionallyBridgeFromObjectiveC requirements of the _ObjectiveCBridgeable protocol previously returned Self and Self?, respectively, where 'Self' is the value type that is bridged. This use of returns is fairly hostile to the idea of calling the witnesses for these requirements from the C++ part of the runtime, leading to "interesting" tricks with OpaqueExistentialContainer that made it hard to use these witnesses within the dynamic casting infrastructure. Replace the returns with inout Self? parameters, which are far easier to deal with in the C++ part of the runtime. Despite the churn because we're changing the _ObjectiveCBridgeable protocol, this is NFC. Swift SVN r20934 --- stdlib/core/BridgeObjectiveC.swift | 42 ++++- stdlib/core/ImplicitlyUnwrappedOptional.swift | 16 +- stdlib/objc/Foundation/Foundation.swift | 170 ++++++++++++------ stdlib/objc/Foundation/NSValue.swift | 15 +- stdlib/runtime/Casting.cpp | 44 +++-- test/Constraints/bridging.swift | 12 +- .../swift-modules/Foundation.swift | 63 ++++--- test/SILGen/Inputs/Foundation.swift | 50 ++++-- test/SILGen/collection_downcast.swift | 13 +- test/SILGen/collection_upcast.swift | 13 +- test/expr/cast/array_bridge.swift | 52 ++++-- test/expr/cast/array_downcast.swift | 13 +- test/expr/cast/bridged.swift | 13 +- test/expr/cast/dictionary_bridge.swift | 13 +- test/stdlib/ArrayBridge.swift | 25 ++- test/stdlib/BridgeNonVerbatim.swift | 15 +- test/stdlib/Bridgeable.swift | 21 ++- test/stdlib/Dictionary.swift | 57 +++--- test/stdlib/DictionaryTraps.swift | 15 +- test/stdlib/Runtime.swift | 58 ++++-- 20 files changed, 484 insertions(+), 236 deletions(-) diff --git a/stdlib/core/BridgeObjectiveC.swift b/stdlib/core/BridgeObjectiveC.swift index 17f07507794..fc6a9418c27 100644 --- a/stdlib/core/BridgeObjectiveC.swift +++ b/stdlib/core/BridgeObjectiveC.swift @@ -133,7 +133,11 @@ public protocol _ObjectiveCBridgeable { /// via as), and may defer complete checking until later. For /// example, when bridging from NSArray to Array, we can defer /// the checking for the individual elements of the array. - class func _forceBridgeFromObjectiveC(source: _ObjectiveCType) -> Self + /// + /// :param: result The location where the result is written. The optional + /// will always contain a value. + class func _forceBridgeFromObjectiveC(source: _ObjectiveCType, + inout result: Self?) /// Try to bridge from an Objective-C object of the bridged class /// type to a value of the Self type. @@ -143,11 +147,16 @@ public protocol _ObjectiveCBridgeable { /// complete conversion to the value type; it cannot defer checking /// to a later time. /// - /// Returns the bridged value if bridging succeeded, nil if bridging - /// did not succeed. + /// :param: result The location where the result is written. + /// + /// :returns: true if bridging succeeded, false otherwise. This redundant + /// information is provided for the convenience of the runtime's dynamic_cast + /// implementation, so that it need not look into the optional representation + /// to determine success. class func _conditionallyBridgeFromObjectiveC( - source: _ObjectiveCType - ) -> Self? + source: _ObjectiveCType, + inout result: Self? + ) -> Bool } //===--- Bridging facilities written in Objective-C -----------------------===// @@ -199,7 +208,10 @@ public func _forceBridgeFromObjectiveC(x: AnyObject, _: T.Type) -> T { if _fastPath(_isClassOrObjCExistential(T.self)) { return x as T } - return _bridgeNonVerbatimFromObjectiveC(x, T.self) + + var result: T? + _bridgeNonVerbatimFromObjectiveC(x, T.self, &result) + return result! } /// Attempt to convert `x` from its Objective-C representation to its Swift @@ -222,15 +234,27 @@ public func _conditionallyBridgeFromObjectiveC( if _fastPath(_isClassOrObjCExistential(T.self)) { return x as? T } - return _bridgeNonVerbatimFromObjectiveCConditional(x, T.self) + + var result: T? + _bridgeNonVerbatimFromObjectiveCConditional(x, T.self, &result) + return result } @asmname("swift_bridgeNonVerbatimFromObjectiveC") -func _bridgeNonVerbatimFromObjectiveC(x: AnyObject, nativeType: T.Type) -> T +func _bridgeNonVerbatimFromObjectiveC(x: AnyObject, nativeType: T.Type, + inout result: T?) +/// Runtime optional to conditionall perform a bridge from an object to a value +/// type. +/// +/// :param: result Will be set to the resulting value if bridging succeeds, and +/// unchanged otherwise. +/// +/// :returns: true to indicate success, false to indicate failure @asmname("swift_bridgeNonVerbatimFromObjectiveCConditional") func _bridgeNonVerbatimFromObjectiveCConditional(x: AnyObject, - nativeType: T.Type) -> T? + nativeType: T.Type, + inout result: T?) -> Bool /// Determines if values of a given type can be converted to an Objective-C /// representation. diff --git a/stdlib/core/ImplicitlyUnwrappedOptional.swift b/stdlib/core/ImplicitlyUnwrappedOptional.swift index 1ed67f18132..1f7424c15b4 100644 --- a/stdlib/core/ImplicitlyUnwrappedOptional.swift +++ b/stdlib/core/ImplicitlyUnwrappedOptional.swift @@ -128,17 +128,23 @@ extension ImplicitlyUnwrappedOptional : _ObjectiveCBridgeable { } } - public static func _forceBridgeFromObjectiveC(x: AnyObject) -> T! { - return Swift._forceBridgeFromObjectiveC(x, T.self) + public static func _forceBridgeFromObjectiveC( + x: AnyObject, + inout result: T!? + ) { + result = Swift._forceBridgeFromObjectiveC(x, T.self) } - public static func _conditionallyBridgeFromObjectiveC(x: AnyObject) -> T!? { + public static func _conditionallyBridgeFromObjectiveC( + x: AnyObject, + inout result: T!? + ) -> Bool { let bridged: T? = Swift._conditionallyBridgeFromObjectiveC(x, T.self) if let value = bridged { - return value + result = value } - return .None + return false } public static func _isBridgedToObjectiveC() -> Bool { diff --git a/stdlib/objc/Foundation/Foundation.swift b/stdlib/objc/Foundation/Foundation.swift index a7484bdeead..58bb7b11f51 100644 --- a/stdlib/objc/Foundation/Foundation.swift +++ b/stdlib/objc/Foundation/Foundation.swift @@ -85,11 +85,13 @@ class NSConstantString {} @asmname("swift_convertStringToNSString") internal func _convertStringToNSString(string: String) -> NSString { - return String._forceBridgeFromObjectiveC(string) + return string._bridgeToObjectiveC() } internal func _convertNSStringToString(nsstring: NSString) -> String { - return String._forceBridgeFromObjectiveC(nsstring) + var result: String? + String._forceBridgeFromObjectiveC(nsstring, result: &result) + return result! } extension NSString : StringLiteralConvertible { @@ -332,14 +334,19 @@ extension String : _ObjectiveCBridgeable { return unsafeBitCast(_bridgeToObjectiveCImpl(), NSString.self) } - public static func _forceBridgeFromObjectiveC(x: NSString) -> String { - return String(unsafeBitCast(x, NSString.self)) + public static func _forceBridgeFromObjectiveC( + x: NSString, + inout result: String? + ) { + result = String(unsafeBitCast(x, NSString.self)) } public static func _conditionallyBridgeFromObjectiveC( - x: NSString - ) -> String? { - return self._forceBridgeFromObjectiveC(x) + x: NSString, + inout result: String? + ) -> Bool { + self._forceBridgeFromObjectiveC(x, result: &result) + return result != nil } } @@ -368,12 +375,19 @@ extension Int : _ObjectiveCBridgeable { return NSNumber(integer: self) } - public static func _forceBridgeFromObjectiveC(x: NSNumber) -> Int { - return x.integerValue + public static func _forceBridgeFromObjectiveC( + x: NSNumber, + inout result: Int? + ) { + result = x.integerValue } - public static func _conditionallyBridgeFromObjectiveC(x: NSNumber) -> Int? { - return self._forceBridgeFromObjectiveC(x) + public static func _conditionallyBridgeFromObjectiveC( + x: NSNumber, + inout result: Int? + ) -> Bool { + self._forceBridgeFromObjectiveC(x, result: &result) + return true } } @@ -396,11 +410,18 @@ extension UInt : _ObjectiveCBridgeable { return NSNumber(unsignedInteger: Int(self.value)) } - public static func _forceBridgeFromObjectiveC(x: NSNumber) -> UInt { - return UInt(x.unsignedIntegerValue.value) + public static func _forceBridgeFromObjectiveC( + x: NSNumber, + inout result: UInt? + ) { + result = UInt(x.unsignedIntegerValue.value) } - public static func _conditionallyBridgeFromObjectiveC(x: NSNumber) -> UInt? { - return self._forceBridgeFromObjectiveC(x) + public static func _conditionallyBridgeFromObjectiveC( + x: NSNumber, + inout result: UInt? + ) -> Bool { + self._forceBridgeFromObjectiveC(x, result: &result) + return true } } @@ -421,12 +442,19 @@ extension Float : _ObjectiveCBridgeable { return NSNumber(float: self) } - public static func _forceBridgeFromObjectiveC(x: NSNumber) -> Float { - return x.floatValue + public static func _forceBridgeFromObjectiveC( + x: NSNumber, + inout result: Float? + ) { + result = x.floatValue } - public static func _conditionallyBridgeFromObjectiveC(x: NSNumber) -> Float? { - return self._forceBridgeFromObjectiveC(x) + public static func _conditionallyBridgeFromObjectiveC( + x: NSNumber, + inout result: Float? + ) -> Bool { + self._forceBridgeFromObjectiveC(x, result: &result) + return true } } @@ -447,14 +475,19 @@ extension Double : _ObjectiveCBridgeable { return NSNumber(double: self) } - public static func _forceBridgeFromObjectiveC(x: NSNumber) -> Double { - return x.doubleValue + public static func _forceBridgeFromObjectiveC( + x: NSNumber, + inout result: Double? + ) { + result = x.doubleValue } public static func _conditionallyBridgeFromObjectiveC( - x: NSNumber - ) -> Double? { - return self._forceBridgeFromObjectiveC(x) + x: NSNumber, + inout result: Double? + ) -> Bool { + self._forceBridgeFromObjectiveC(x, result: &result) + return true } } @@ -476,12 +509,19 @@ extension Bool: _ObjectiveCBridgeable { return NSNumber(bool: self) } - public static func _forceBridgeFromObjectiveC(x: NSNumber) -> Bool { - return x.boolValue + public static func _forceBridgeFromObjectiveC( + x: NSNumber, + inout result: Bool? + ) { + result = x.boolValue } - public static func _conditionallyBridgeFromObjectiveC(x: NSNumber) -> Bool? { - return self._forceBridgeFromObjectiveC(x) + public static func _conditionallyBridgeFromObjectiveC( + x: NSNumber, + inout result: Bool? + ) -> Bool { + self._forceBridgeFromObjectiveC(x, result: &result) + return true } } @@ -503,14 +543,21 @@ extension CGFloat : _ObjectiveCBridgeable { return self.native._bridgeToObjectiveC() } - public static func _forceBridgeFromObjectiveC(x: NSNumber) -> CGFloat { - return CGFloat(CGFloat.NativeType._forceBridgeFromObjectiveC(x)) + public static func _forceBridgeFromObjectiveC( + x: NSNumber, + inout result: CGFloat? + ) { + var nativeResult: CGFloat.NativeType? = 0.0 + CGFloat.NativeType._forceBridgeFromObjectiveC(x, result: &nativeResult) + result = CGFloat(nativeResult!) } public static func _conditionallyBridgeFromObjectiveC( - x: NSNumber - ) -> CGFloat? { - return self._forceBridgeFromObjectiveC(x) + x: NSNumber, + inout result: CGFloat? + ) -> Bool { + self._forceBridgeFromObjectiveC(x, result: &result) + return true } } @@ -555,7 +602,9 @@ extension NSArray : ArrayLiteralConvertible { /// to Objective-C code as a method that accepts an `NSArray`. This operation /// is referred to as a "forced conversion" in ../../../docs/Arrays.rst public func _convertNSArrayToArray(source: NSArray) -> [T] { - return Array._forceBridgeFromObjectiveC(source) + var result: [T]? + Array._forceBridgeFromObjectiveC(source, result: &result) + return result! } /// The entry point for converting `Array` to `NSArray` in bridge @@ -593,31 +642,38 @@ extension Array : _ObjectiveCBridgeable { return unsafeBitCast(self._buffer._asCocoaArray(), NSArray.self) } - public static func _forceBridgeFromObjectiveC(source: NSArray) -> Array { + public static func _forceBridgeFromObjectiveC( + source: NSArray, + inout result: Array? + ) { _precondition( Swift._isBridgedToObjectiveC(T.self), "array element type is not bridged to Objective-C") // If we have the appropriate native storage already, just adopt it. - if let result = Array._bridgeFromObjectiveCAdoptingNativeStorage(source) { - return result + if let native = Array._bridgeFromObjectiveCAdoptingNativeStorage(source) { + result = native + return } if _fastPath(_isBridgedVerbatimToObjectiveC(T.self)) { // Forced down-cast (possible deferred type-checking) - return Array(_fromNSArray: source) + result = Array(_fromNSArray: source) + return } - return _arrayForceCast([AnyObject](_fromNSArray: source)) + result = _arrayForceCast([AnyObject](_fromNSArray: source)) } public static func _conditionallyBridgeFromObjectiveC( - source: NSArray - ) -> Array? { + source: NSArray, + inout result: Array? + ) -> Bool { // Construct the result array by conditionally bridging each element. var anyObjectArr = [AnyObject](_fromNSArray: source) - return _arrayConditionalCast(anyObjectArr) + result = _arrayConditionalCast(anyObjectArr) + return result != nil } } @@ -667,7 +723,9 @@ public func _convertNSDictionaryToDictionary< -> [Key : Value] { // Note: there should be *a good justification* for doing something else // than just dispatching to `_forceBridgeFromObjectiveC`. - return Dictionary._forceBridgeFromObjectiveC(d) + var result: [Key : Value]? + Dictionary._forceBridgeFromObjectiveC(d, result: &result) + return result! } /// The entry point for bridging `Dictionary` to `NSDictionary` in bridge @@ -700,16 +758,21 @@ extension Dictionary : _ObjectiveCBridgeable { return unsafeBitCast(_bridgeToObjectiveCImpl(), NSDictionary.self) } - public static func _forceBridgeFromObjectiveC(d: NSDictionary) -> Dictionary { - if let result = [Key : Value]._bridgeFromObjectiveCAdoptingNativeStorage( + public static func _forceBridgeFromObjectiveC( + d: NSDictionary, + inout result: Dictionary? + ) { + if let native = [Key : Value]._bridgeFromObjectiveCAdoptingNativeStorage( d as AnyObject) { - return result + result = native + return } if _isBridgedVerbatimToObjectiveC(Key.self) && _isBridgedVerbatimToObjectiveC(Value.self) { - return [Key : Value]( + result = [Key : Value]( _cocoaDictionary: unsafeBitCast(d, _SwiftNSDictionaryType.self)) + return } // `Dictionary` where either `Key` or `Value` is a value type @@ -722,19 +785,22 @@ extension Dictionary : _ObjectiveCBridgeable { key: Swift._forceBridgeFromObjectiveC(anyObjectKey, Key.self), value: Swift._forceBridgeFromObjectiveC(anyObjectValue, Value.self)) } - return builder.take() + result = builder.take() } public static func _conditionallyBridgeFromObjectiveC( - x: NSDictionary - ) -> Dictionary? { + x: NSDictionary, + inout result: Dictionary? + ) -> Bool { let anyDict = x as [NSObject : AnyObject] if _isBridgedVerbatimToObjectiveC(Key.self) && _isBridgedVerbatimToObjectiveC(Value.self) { - return Swift._dictionaryDownCastConditional(anyDict) + result = Swift._dictionaryDownCastConditional(anyDict) + return result != nil } - return Swift._dictionaryBridgeFromObjectiveCConditional(anyDict) + result = Swift._dictionaryBridgeFromObjectiveCConditional(anyDict) + return result != nil } public static func _isBridgedToObjectiveC() -> Bool { diff --git a/stdlib/objc/Foundation/NSValue.swift b/stdlib/objc/Foundation/NSValue.swift index 2bb9f6446d2..8b5cd61e931 100644 --- a/stdlib/objc/Foundation/NSValue.swift +++ b/stdlib/objc/Foundation/NSValue.swift @@ -23,13 +23,18 @@ extension NSRange : _ObjectiveCBridgeable { return NSValue(range: self) } - public static func _forceBridgeFromObjectiveC(x: NSValue) -> NSRange { - return x.rangeValue + public static func _forceBridgeFromObjectiveC( + x: NSValue, + inout result: NSRange? + ) { + result = x.rangeValue } public static func _conditionallyBridgeFromObjectiveC( - x: NSValue - ) -> NSRange? { - return self._forceBridgeFromObjectiveC(x) + x: NSValue, + inout result: NSRange? + ) -> Bool { + self._forceBridgeFromObjectiveC(x, result: &result) + return true } } diff --git a/stdlib/runtime/Casting.cpp b/stdlib/runtime/Casting.cpp index 6a1a7c430c1..0f27610408c 100644 --- a/stdlib/runtime/Casting.cpp +++ b/stdlib/runtime/Casting.cpp @@ -1605,16 +1605,19 @@ struct _ObjectiveCBridgeableWitnessTable { // func _bridgeToObjectiveC() -> _ObjectiveCType HeapObject *(*bridgeToObjectiveC)(OpaqueValue *self, const Metadata *Self); - // class func _forceBridgeFromObjectiveC(x: _ObjectiveCType) -> Self - OpaqueExistentialContainer (*forceBridgeFromObjectiveC)(HeapObject *sourceValue, - const Metadata *self, - const Metadata *selfType); + // class func _forceBridgeFromObjectiveC(x: _ObjectiveCType, + // inout result: Self?) + void (*forceBridgeFromObjectiveC)(HeapObject *sourceValue, + OpaqueValue *result, + const Metadata *self, + const Metadata *selfType); - // class func _conditionallyBridgeFromObjectiveC(x: _ObjectiveCType) -> Self? - OpaqueExistentialContainer (*conditionallyBridgeFromObjectiveC)( - HeapObject *sourceValue, - const Metadata *self, - const Metadata *selfType); + // class func _conditionallyBridgeFromObjectiveC(x: _ObjectiveCType, + // inout result: Self?) -> Bool + bool (*conditionallyBridgeFromObjectiveC)(HeapObject *sourceValue, + OpaqueValue *result, + const Metadata *self, + const Metadata *selfType); }; // } @@ -1720,10 +1723,11 @@ extern "C" const Metadata *swift_getBridgedNonVerbatimObjectiveCType( // func _bridgeNonVerbatimFromObjectiveC( // x: AnyObject, nativeType: NativeType.Type // ) -> NativeType -extern "C" OpaqueExistentialContainer +extern "C" void swift_bridgeNonVerbatimFromObjectiveC( HeapObject *sourceValue, const Metadata *nativeType, + OpaqueValue *destValue, const Metadata *nativeType_ ) { // Check if the type conforms to _BridgedToObjectiveC. @@ -1743,9 +1747,10 @@ swift_bridgeNonVerbatimFromObjectiveC( if (sourceValueAsObjectiveCType) { // The type matches. _forceBridgeFromObjectiveC returns `Self`, so // we can just return it directly. - return bridgeWitness->forceBridgeFromObjectiveC( + bridgeWitness->forceBridgeFromObjectiveC( static_cast(sourceValueAsObjectiveCType), - nativeType, nativeType); + destValue, nativeType, nativeType); + return; } } } @@ -1758,22 +1763,23 @@ swift_bridgeNonVerbatimFromObjectiveC( // func _bridgeNonVerbatimFromObjectiveCConditional( // x: AnyObject, nativeType: NativeType.Type // ) -> NativeType? -extern "C" OpaqueExistentialContainer +extern "C" bool swift_bridgeNonVerbatimFromObjectiveCConditional( HeapObject *sourceValue, const Metadata *nativeType, + OpaqueValue *destValue, const Metadata *nativeType_ ) { - // Local function that releases the source and produces a nil. - auto produceNil = [&] () -> OpaqueExistentialContainer { + // Local function that releases the source and returns false. + auto fail = [&] () -> bool { swift_unknownRelease(sourceValue); - return _TFSs26_injectNothingIntoOptionalU__FT_GSqQ__(nativeType); + return false; }; // Check if the type conforms to _BridgedToObjectiveC. const auto *bridgeWitness = findBridgeWitness(nativeType); if (!bridgeWitness) - return produceNil(); + return fail(); // Dig out the Objective-C class type through which the native type // is bridged. @@ -1786,13 +1792,13 @@ swift_bridgeNonVerbatimFromObjectiveCConditional( const_cast(swift_dynamicCastUnknownClass(sourceValue, objectiveCType)); if (!sourceValueAsObjectiveCType) - return produceNil(); + return fail(); // If the type also conforms to _ConditionallyBridgedToObjectiveC, // use conditional bridging. return bridgeWitness->conditionallyBridgeFromObjectiveC( static_cast(sourceValueAsObjectiveCType), - nativeType, nativeType); + destValue, nativeType, nativeType); } // func isBridgedNonVerbatimToObjectiveC(x: T.Type) -> Bool diff --git a/test/Constraints/bridging.swift b/test/Constraints/bridging.swift index db84e16bca2..9fee782f8b6 100644 --- a/test/Constraints/bridging.swift +++ b/test/Constraints/bridging.swift @@ -26,14 +26,16 @@ struct BridgedStruct : Hashable, _ObjectiveCBridgeable { return BridgedClass() } - static func _forceBridgeFromObjectiveC(x: BridgedClass) -> BridgedStruct { - return BridgedStruct() + static func _forceBridgeFromObjectiveC( + x: BridgedClass, + inout result: BridgedStruct?) { } static func _conditionallyBridgeFromObjectiveC( - x: BridgedClass - ) -> BridgedStruct? { - return self._forceBridgeFromObjectiveC(x) + x: BridgedClass, + inout result: BridgedStruct? + ) -> Bool { + return true } } diff --git a/test/Inputs/clang-importer-sdk/swift-modules/Foundation.swift b/test/Inputs/clang-importer-sdk/swift-modules/Foundation.swift index 298cca2de4e..4a3d3d8746b 100644 --- a/test/Inputs/clang-importer-sdk/swift-modules/Foundation.swift +++ b/test/Inputs/clang-importer-sdk/swift-modules/Foundation.swift @@ -56,13 +56,14 @@ extension String : _ObjectiveCBridgeable { public func _bridgeToObjectiveC() -> NSString { return NSString() } - public static func _forceBridgeFromObjectiveC(x: NSString) -> String { - _fatalError("implement") + public static func _forceBridgeFromObjectiveC(x: NSString, + inout result: String?) { } public static func _conditionallyBridgeFromObjectiveC( - x: NSString - ) -> String? { - return self._forceBridgeFromObjectiveC(x) + x: NSString, + inout result: String? + ) -> Bool { + return true } } @@ -77,13 +78,16 @@ extension Int : _ObjectiveCBridgeable { public func _bridgeToObjectiveC() -> NSNumber { return NSNumber() } - public static func _forceBridgeFromObjectiveC(x: NSNumber) -> Int { - _fatalError("implement") + public static func _forceBridgeFromObjectiveC( + x: NSNumber, + inout result: Int? + ) { } public static func _conditionallyBridgeFromObjectiveC( - x: NSNumber - ) -> Int? { - return self._forceBridgeFromObjectiveC(x) + x: NSNumber, + inout result: Int? + ) -> Bool { + return true } } @@ -98,13 +102,16 @@ extension Array : _ObjectiveCBridgeable { public func _bridgeToObjectiveC() -> NSArray { return NSArray() } - public static func _forceBridgeFromObjectiveC(x: NSArray) -> Array { - return [] + public static func _forceBridgeFromObjectiveC( + x: NSArray, + inout result: Array? + ) { } public static func _conditionallyBridgeFromObjectiveC( - x: NSArray - ) -> Array? { - return self._forceBridgeFromObjectiveC(x) + x: NSArray, + inout result: Array? + ) -> Bool { + return true } } @@ -119,13 +126,16 @@ extension Dictionary : _ObjectiveCBridgeable { public func _bridgeToObjectiveC() -> NSDictionary { return NSDictionary() } - public static func _forceBridgeFromObjectiveC(x: NSDictionary) -> Dictionary { - return [:] + public static func _forceBridgeFromObjectiveC( + x: NSDictionary, + inout result: Dictionary? + ) { } public static func _conditionallyBridgeFromObjectiveC( - x: NSDictionary - ) -> Dictionary? { - return self._forceBridgeFromObjectiveC(x) + x: NSDictionary, + inout result: Dictionary? + ) -> Bool { + return true } } @@ -140,12 +150,15 @@ extension CGFloat : _ObjectiveCBridgeable { public func _bridgeToObjectiveC() -> NSNumber { return NSNumber() } - public static func _forceBridgeFromObjectiveC(x: NSNumber) -> CGFloat { - return CGFloat() + public static func _forceBridgeFromObjectiveC( + x: NSNumber, + inout result: CGFloat? + ) { } public static func _conditionallyBridgeFromObjectiveC( - x: NSNumber - ) -> CGFloat? { - return self._forceBridgeFromObjectiveC(x) + x: NSNumber, + inout result: CGFloat? + ) -> Bool { + return true } } diff --git a/test/SILGen/Inputs/Foundation.swift b/test/SILGen/Inputs/Foundation.swift index 864301249f6..0109d74f08b 100644 --- a/test/SILGen/Inputs/Foundation.swift +++ b/test/SILGen/Inputs/Foundation.swift @@ -42,13 +42,16 @@ extension String : _ObjectiveCBridgeable { public func _bridgeToObjectiveC() -> NSString { return NSString() } - public static func _forceBridgeFromObjectiveC(x: NSString) -> String { - fatalError("implement") + public static func _forceBridgeFromObjectiveC( + x: NSString, + inout result: String? + ) { } public static func _conditionallyBridgeFromObjectiveC( - x: NSString - ) -> String? { - return self._forceBridgeFromObjectiveC(x) + x: NSString, + inout result: String? + ) -> Bool { + return true } } @@ -63,13 +66,16 @@ extension Int : _ObjectiveCBridgeable { public func _bridgeToObjectiveC() -> NSNumber { return NSNumber() } - public static func _forceBridgeFromObjectiveC(x: NSNumber) -> Int { - fatal("implement") + public static func _forceBridgeFromObjectiveC( + x: NSNumber, + inout result: Int? + ) { } public static func _conditionallyBridgeFromObjectiveC( - x: NSNumber - ) -> Int? { - return self._forceBridgeFromObjectiveC(x) + x: NSNumber, + inout result: Int? + ) -> Bool { + return true } } @@ -80,10 +86,15 @@ extension Array : _ObjectiveCBridgeable { public func _bridgeToObjectiveC() -> NSArray { return NSArray() } - public static func _forceBridgeFromObjectiveC(x: NSArray) -> Array { - fatal("implement") + public static func _forceBridgeFromObjectiveC( + x: NSArray, + inout result: Array? + ) { } - public static func _conditionallyBridgeFromObjectiveC(x: NSArray) -> Array? { + public static func _conditionallyBridgeFromObjectiveC( + x: NSArray, + inout result: Array? + ) -> Bool { return nil } public static func _isBridgedToObjectiveC() -> Bool { @@ -98,11 +109,16 @@ extension Dictionary : _ObjectiveCBridgeable { public func _bridgeToObjectiveC() -> NSDictionary { return NSDictionary() } - public static func _forceBridgeFromObjectiveC(x: NSDictionary) -> Dictionary { - fatal("implement") + public static func _forceBridgeFromObjectiveC( + x: NSDictionary, + inout result: Dictionary? + ) { } - public static func _conditionallyBridgeFromObjectiveC(x: NSDictionary) -> Dictionary? { - return nil + public static func _conditionallyBridgeFromObjectiveC( + x: NSDictionary, + inout result: Dictionary? + ) -> Bool { + return true } public static func _isBridgedToObjectiveC() -> Bool { return Swift._isBridgedToObjectiveC(T.self) diff --git a/test/SILGen/collection_downcast.swift b/test/SILGen/collection_downcast.swift index 55c5d72c4ab..ad800c2e628 100644 --- a/test/SILGen/collection_downcast.swift +++ b/test/SILGen/collection_downcast.swift @@ -22,13 +22,16 @@ struct BridgedSwift : Hashable, _ObjectiveCBridgeable { return BridgedObjC() } - static func _forceBridgeFromObjectiveC(x: BridgedObjC) -> BridgedSwift { - return BridgedSwift() + static func _forceBridgeFromObjectiveC( + x: BridgedObjC, + inout result: BridgedSwift? + ) { } static func _conditionallyBridgeFromObjectiveC( - x: BridgedObjC - ) -> BridgedSwift? { - return BridgedSwift() + x: BridgedObjC, + inout result: BridgedSwift? + ) -> Bool { + return true } } diff --git a/test/SILGen/collection_upcast.swift b/test/SILGen/collection_upcast.swift index 49b3e3784f0..148496057ac 100644 --- a/test/SILGen/collection_upcast.swift +++ b/test/SILGen/collection_upcast.swift @@ -22,13 +22,16 @@ struct BridgedSwift : Hashable, _ObjectiveCBridgeable { return BridgedObjC() } - static func _forceBridgeFromObjectiveC(x: BridgedObjC) -> BridgedSwift { - return BridgedSwift() + static func _forceBridgeFromObjectiveC( + x: BridgedObjC, + inout result: BridgedSwift? + ) { } static func _conditionallyBridgeFromObjectiveC( - x: BridgedObjC - ) -> BridgedSwift? { - return BridgedSwift() + x: BridgedObjC, + inout result: BridgedSwift? + ) -> Bool { + return true } } diff --git a/test/expr/cast/array_bridge.swift b/test/expr/cast/array_bridge.swift index 75f8457f019..1a6dff6748e 100644 --- a/test/expr/cast/array_bridge.swift +++ b/test/expr/cast/array_bridge.swift @@ -15,11 +15,16 @@ struct B : _ObjectiveCBridgeable { func _bridgeToObjectiveC() -> A { return A() } - static func _forceBridgeFromObjectiveC(x: A) -> B { - return B() + static func _forceBridgeFromObjectiveC( + x: A, + inout result: B? + ){ } - static func _conditionallyBridgeFromObjectiveC(x: A) -> B? { - return B() + static func _conditionallyBridgeFromObjectiveC( + x: A, + inout result: B? + ) -> Bool { + return true } } @@ -54,11 +59,16 @@ struct F : _ObjectiveCBridgeable { func _bridgeToObjectiveC() -> E { return E() } - static func _forceBridgeFromObjectiveC(x: E) -> F { - return F() + static func _forceBridgeFromObjectiveC( + x: E, + inout result: F? + ) { } - static func _conditionallyBridgeFromObjectiveC(x: E) -> F? { - return F() + static func _conditionallyBridgeFromObjectiveC( + x: E, + inout result: F? + ) -> Bool { + return true } } @@ -79,11 +89,16 @@ struct H : _ObjectiveCBridgeable { func _bridgeToObjectiveC() -> G { return G() } - static func _forceBridgeFromObjectiveC(x: G) -> H { - return H() + static func _forceBridgeFromObjectiveC( + x: G, + inout result: H? + ) { } - static func _conditionallyBridgeFromObjectiveC(x: G) -> H? { - _preconditionFailure("implement") + static func _conditionallyBridgeFromObjectiveC( + x: G, + inout result: H? + ) -> Bool { + return true } static func _isBridgedToObjectiveC() -> Bool { return false @@ -107,11 +122,16 @@ struct I : _ObjectiveCBridgeable { func _bridgeToObjectiveC() -> AnyObject { return A() } - static func _forceBridgeFromObjectiveC(x: AnyObject) -> I { - return I() + static func _forceBridgeFromObjectiveC( + x: AnyObject, + inout result: I? + ) { } - static func _conditionallyBridgeFromObjectiveC(x: AnyObject) -> I? { - return I() + static func _conditionallyBridgeFromObjectiveC( + x: AnyObject, + inout result: I? + ) -> Bool { + return true } } diff --git a/test/expr/cast/array_downcast.swift b/test/expr/cast/array_downcast.swift index 83b4459d41a..b6d0fd0dfdb 100644 --- a/test/expr/cast/array_downcast.swift +++ b/test/expr/cast/array_downcast.swift @@ -39,11 +39,16 @@ struct B : _ObjectiveCBridgeable { func _bridgeToObjectiveC() -> A { return A() } - static func _forceBridgeFromObjectiveC(x: A) -> B { - return B() + static func _forceBridgeFromObjectiveC( + x: A, + inout result: B? + ) { } - static func _conditionallyBridgeFromObjectiveC(x: A) -> B? { - return B() + static func _conditionallyBridgeFromObjectiveC( + x: A, + inout result: B? + ) -> Bool { + return true } } diff --git a/test/expr/cast/bridged.swift b/test/expr/cast/bridged.swift index cc0c27aa03f..97365d27e73 100644 --- a/test/expr/cast/bridged.swift +++ b/test/expr/cast/bridged.swift @@ -20,11 +20,16 @@ struct BridgedStruct : _ObjectiveCBridgeable { return BridgedClass() } - static func _forceBridgeFromObjectiveC(x: BridgedClass) -> BridgedStruct { - return BridgedStruct() + static func _forceBridgeFromObjectiveC( + x: BridgedClass, + inout result: BridgedStruct? + ) { } - static func _conditionallyBridgeFromObjectiveC(x: BridgedClass) -> BridgedStruct? { - return BridgedStruct() + static func _conditionallyBridgeFromObjectiveC( + x: BridgedClass, + inout result: BridgedStruct? + ) -> Bool { + return true } } diff --git a/test/expr/cast/dictionary_bridge.swift b/test/expr/cast/dictionary_bridge.swift index dc4d8f48e26..5b8a3a8c111 100644 --- a/test/expr/cast/dictionary_bridge.swift +++ b/test/expr/cast/dictionary_bridge.swift @@ -25,11 +25,16 @@ struct BridgedToObjC : Hashable, _ObjectiveCBridgeable { func _bridgeToObjectiveC() -> ObjC { return ObjC() } - static func _forceBridgeFromObjectiveC(x: ObjC) -> BridgedToObjC { - return BridgedToObjC() + static func _forceBridgeFromObjectiveC( + x: ObjC, + inout result: BridgedToObjC? + ) { } - static func _conditionallyBridgeFromObjectiveC(x: ObjC) -> BridgedToObjC? { - return BridgedToObjC() + static func _conditionallyBridgeFromObjectiveC( + x: ObjC, + inout result: BridgedToObjC? + ) -> Bool { + return true } var hashValue: Int { diff --git a/test/stdlib/ArrayBridge.swift b/test/stdlib/ArrayBridge.swift index 2ef8a8cac98..2717f14471e 100644 --- a/test/stdlib/ArrayBridge.swift +++ b/test/stdlib/ArrayBridge.swift @@ -109,14 +109,26 @@ struct BridgedSwift : Printable, _ObjectiveCBridgeable { return true } - static func _forceBridgeFromObjectiveC(x: BridgedObjC) -> BridgedSwift { + static func _forceBridgeFromObjectiveC( + x: BridgedObjC, + inout result: BridgedSwift? + ) { assert(x.value >= 0, "not bridged") ++bridgeFromOperationCount - return BridgedSwift(x.value) + result = BridgedSwift(x.value) } - static func _conditionallyBridgeFromObjectiveC(x: BridgedObjC) -> BridgedSwift? { - return x.value >= 0 ? BridgedSwift(x.value) : nil + static func _conditionallyBridgeFromObjectiveC( + x: BridgedObjC, + inout result: BridgedSwift? + ) -> Bool { + if x.value >= 0 { + result = BridgedSwift(x.value) + return true + } + + result = nil + return false } var description: String { @@ -323,7 +335,8 @@ func testExplicitlyBridged() { // Make sure we can bridge back. let roundTripBridgedSwifts - = [BridgedSwift]._forceBridgeFromObjectiveC(bridgedSwiftsAsNSArray) + = Swift._forceBridgeFromObjectiveC(bridgedSwiftsAsNSArray, + [BridgedSwift].self) // CHECK-NEXT-NOT: [BridgedSwift#[[id00]](42), BridgedSwift#[[id01]](17)] // CHECK-NEXT: [BridgedSwift#[[id10:[0-9]+]](42), BridgedSwift#[[id11:[0-9]+]](17)] println("roundTripBridgedSwifts = \(roundTripBridgedSwifts))") @@ -333,7 +346,7 @@ func testExplicitlyBridged() { // ...and bridge *that* back let bridgedBackSwifts - = [BridgedSwift]._forceBridgeFromObjectiveC(cocoaBridgedSwifts) + = Swift._forceBridgeFromObjectiveC(cocoaBridgedSwifts, [BridgedSwift].self) // CHECK-NEXT-NOT: [BridgedSwift#[[id00]](42), BridgedSwift#[[id01]](17)] // CHECK-NEXT-NOT: [BridgedSwift#[[id10]](42), BridgedSwift#[[id11]](17)] // CHECK-NEXT: [BridgedSwift#{{[0-9]+}}(42), BridgedSwift#{{[0-9]+}}(17)] diff --git a/test/stdlib/BridgeNonVerbatim.swift b/test/stdlib/BridgeNonVerbatim.swift index b09e660e709..0d924796196 100644 --- a/test/stdlib/BridgeNonVerbatim.swift +++ b/test/stdlib/BridgeNonVerbatim.swift @@ -75,12 +75,19 @@ struct X : _ObjectiveCBridgeable { return Tracked(value) } - static func _forceBridgeFromObjectiveC(x: Tracked) -> X { - return X(x.value) + static func _forceBridgeFromObjectiveC( + x: Tracked, + inout result: X? + ) { + result = X(x.value) } - static func _conditionallyBridgeFromObjectiveC(x: Tracked) -> X? { - return X(x.value) + static func _conditionallyBridgeFromObjectiveC( + x: Tracked, + inout result: X? + ) -> Bool { + result = X(x.value) + return true } var value: Int diff --git a/test/stdlib/Bridgeable.swift b/test/stdlib/Bridgeable.swift index 01922d28bde..e3568ca90b2 100644 --- a/test/stdlib/Bridgeable.swift +++ b/test/stdlib/Bridgeable.swift @@ -41,10 +41,16 @@ struct BridgedValueType : _ObjectiveCBridgeable { func _bridgeToObjectiveC() -> C { return C() } - static func _forceBridgeFromObjectiveC(x: C) -> BridgedValueType { + static func _forceBridgeFromObjectiveC( + x: C, + inout result: BridgedValueType? + ) { _preconditionFailure("implement") } - static func _conditionallyBridgeFromObjectiveC(x: C) -> BridgedValueType? { + static func _conditionallyBridgeFromObjectiveC( + x: C, + inout result: BridgedValueType? + ) -> Bool { _preconditionFailure("implement") } } @@ -75,11 +81,16 @@ struct ConditionallyBridged : _ObjectiveCBridgeable { func _bridgeToObjectiveC() -> C { return C() } - static func _forceBridgeFromObjectiveC(x: C) -> ConditionallyBridged { + static func _forceBridgeFromObjectiveC( + x: C, + inout result: ConditionallyBridged? + ) { _preconditionFailure("implement") } - static func _conditionallyBridgeFromObjectiveC(x: C) - -> ConditionallyBridged? { + static func _conditionallyBridgeFromObjectiveC( + x: C, + inout result: ConditionallyBridged? + ) -> Bool { _preconditionFailure("implement") } static func _isBridgedToObjectiveC() -> Bool { diff --git a/test/stdlib/Dictionary.swift b/test/stdlib/Dictionary.swift index 81c0f4a2f62..35303c705de 100644 --- a/test/stdlib/Dictionary.swift +++ b/test/stdlib/Dictionary.swift @@ -1496,15 +1496,20 @@ struct TestBridgedKeyTy return TestObjCKeyTy(value) } - static func _forceBridgeFromObjectiveC(x: TestObjCKeyTy) -> TestBridgedKeyTy { + static func _forceBridgeFromObjectiveC( + x: TestObjCKeyTy, + inout result: TestBridgedKeyTy? + ) { TestBridgedKeyTy.bridgeOperations++ - return TestBridgedKeyTy(x.value) + result = TestBridgedKeyTy(x.value) } static func _conditionallyBridgeFromObjectiveC( - x: TestObjCKeyTy - ) -> TestBridgedKeyTy? { - return self._forceBridgeFromObjectiveC(x) + x: TestObjCKeyTy, + inout result: TestBridgedKeyTy? + ) -> Bool { + self._forceBridgeFromObjectiveC(x, result: &result) + return true } var value: Int @@ -1555,16 +1560,19 @@ struct TestBridgedValueTy : Printable, _ObjectiveCBridgeable { } static func _forceBridgeFromObjectiveC( - x: TestObjCValueTy - ) -> TestBridgedValueTy { + x: TestObjCValueTy, + inout result: TestBridgedValueTy? + ) { TestBridgedValueTy.bridgeOperations++ - return TestBridgedValueTy(x.value) + result = TestBridgedValueTy(x.value) } static func _conditionallyBridgeFromObjectiveC( - x: TestObjCValueTy - ) -> TestBridgedValueTy? { - return self._forceBridgeFromObjectiveC(x) + x: TestObjCValueTy, + inout result: TestBridgedValueTy? + ) -> Bool { + self._forceBridgeFromObjectiveC(x, result: &result) + return true } var value: Int @@ -1598,15 +1606,18 @@ struct TestBridgedEquatableValueTy } static func _forceBridgeFromObjectiveC( - x: TestObjCEquatableValueTy - ) -> TestBridgedEquatableValueTy { - return TestBridgedEquatableValueTy(x.value) + x: TestObjCEquatableValueTy, + inout result: TestBridgedEquatableValueTy? + ) { + result = TestBridgedEquatableValueTy(x.value) } static func _conditionallyBridgeFromObjectiveC( - x: TestObjCEquatableValueTy - ) -> TestBridgedEquatableValueTy? { - return self._forceBridgeFromObjectiveC(x) + x: TestObjCEquatableValueTy, + inout result: TestBridgedEquatableValueTy? + ) -> Bool { + self._forceBridgeFromObjectiveC(x, result: &result) + return true } var value: Int @@ -1723,18 +1734,18 @@ func getBridgedVerbatimDictionaryAndNSMutableDictionary() func getBridgedNonverbatimDictionary() -> Dictionary { var nsd = getAsNSDictionary([ 10: 1010, 20: 1020, 30: 1030 ]) - return Dictionary._forceBridgeFromObjectiveC(nsd) + return Swift._forceBridgeFromObjectiveC(nsd, Dictionary.self) } func getBridgedNonverbatimDictionary(d: Dictionary) -> Dictionary { var nsd = getAsNSDictionary(d) - return Dictionary._forceBridgeFromObjectiveC(nsd) + return Swift._forceBridgeFromObjectiveC(nsd, Dictionary.self) } func getBridgedNonverbatimDictionaryAndNSMutableDictionary() -> (Dictionary, NSMutableDictionary) { var nsd = getAsNSMutableDictionary([ 10: 1010, 20: 1020, 30: 1030 ]) - return (Dictionary._forceBridgeFromObjectiveC(nsd), nsd) + return (Swift._forceBridgeFromObjectiveC(nsd, Dictionary.self), nsd) } func getBridgedVerbatimEquatableDictionary(d: Dictionary) -> Dictionary { @@ -1744,7 +1755,7 @@ func getBridgedVerbatimEquatableDictionary(d: Dictionary) -> Dictionar func getBridgedNonverbatimEquatableDictionary(d: Dictionary) -> Dictionary { var nsd = getAsEquatableNSDictionary(d) - return Dictionary._forceBridgeFromObjectiveC(nsd) + return Swift._forceBridgeFromObjectiveC(nsd, Dictionary.self) } func getHugeBridgedVerbatimDictionaryHelper() -> NSDictionary { @@ -1765,7 +1776,7 @@ func getHugeBridgedVerbatimDictionary() -> Dictionary { func getHugeBridgedNonverbatimDictionary() -> Dictionary { var nsd = getHugeBridgedVerbatimDictionaryHelper() - return Dictionary._forceBridgeFromObjectiveC(nsd) + return Swift._forceBridgeFromObjectiveC(nsd, Dictionary.self) } /// A mock dictionary that stores its keys and values in parallel arrays, which @@ -1825,7 +1836,7 @@ func getParallelArrayBridgedVerbatimDictionary() -> Dictionary Dictionary { var nsd: NSDictionary = ParallelArrayDictionary() - return Dictionary._forceBridgeFromObjectiveC(nsd) + return Swift._forceBridgeFromObjectiveC(nsd, Dictionary.self) } func test_BridgedFromObjC_Verbatim_DictionaryIsCopied() { diff --git a/test/stdlib/DictionaryTraps.swift b/test/stdlib/DictionaryTraps.swift index af1506df394..23072e7e783 100644 --- a/test/stdlib/DictionaryTraps.swift +++ b/test/stdlib/DictionaryTraps.swift @@ -155,14 +155,19 @@ struct TestBridgedKeyTy : Hashable, _ObjectiveCBridgeable { return TestObjCKeyTy(value) } - static func _forceBridgeFromObjectiveC(x: TestObjCKeyTy) -> TestBridgedKeyTy { - return TestBridgedKeyTy(x.value) + static func _forceBridgeFromObjectiveC( + x: TestObjCKeyTy, + inout result: TestBridgedKeyTy? + ) { + result = TestBridgedKeyTy(x.value) } static func _conditionallyBridgeFromObjectiveC( - x: TestObjCKeyTy - ) -> TestBridgedKeyTy? { - return TestBridgedKeyTy(x.value) + x: TestObjCKeyTy, + inout result: TestBridgedKeyTy? + ) -> Bool { + result = TestBridgedKeyTy(x.value) + return true } var value: Int diff --git a/test/stdlib/Runtime.swift b/test/stdlib/Runtime.swift index c2453ad7822..57c38ab4fd6 100644 --- a/test/stdlib/Runtime.swift +++ b/test/stdlib/Runtime.swift @@ -63,18 +63,25 @@ struct BridgedValueType : _ObjectiveCBridgeable { return true } - static func _forceBridgeFromObjectiveC(x: ClassA) -> BridgedValueType { + static func _forceBridgeFromObjectiveC( + x: ClassA, + inout result: BridgedValueType? + ) { assert(x.value % 2 == 0, "not bridged to Objective-C") - return BridgedValueType(value: x.value) + result = BridgedValueType(value: x.value) } static func _conditionallyBridgeFromObjectiveC( - x: ClassA - ) -> BridgedValueType? { + x: ClassA, + inout result: BridgedValueType? + ) -> Bool { if x.value % 2 == 0 { - return BridgedValueType(value: x.value) + result = BridgedValueType(value: x.value) + return true } - return .None + + result = nil + return false } var value: Int @@ -106,16 +113,25 @@ struct BridgedLargeValueType : _ObjectiveCBridgeable { return true } - static func _forceBridgeFromObjectiveC(x: ClassA) -> BridgedLargeValueType { + static func _forceBridgeFromObjectiveC( + x: ClassA, + inout result: BridgedLargeValueType? + ) { assert(x.value % 2 == 0, "not bridged to Objective-C") - return BridgedLargeValueType(value: x.value) + result = BridgedLargeValueType(value: x.value) } - static func _conditionallyBridgeFromObjectiveC(x: ClassA) -> BridgedLargeValueType? { + static func _conditionallyBridgeFromObjectiveC( + x: ClassA, + inout result: BridgedLargeValueType? + ) -> Bool { if x.value % 2 == 0 { - return BridgedLargeValueType(value: x.value) + result = BridgedLargeValueType(value: x.value) + return true } - return .None + + result = nil + return false } var value: Int { @@ -145,18 +161,24 @@ struct ConditionallyBridgedValueType : _ObjectiveCBridgeable { } static func _forceBridgeFromObjectiveC( - x: ClassA - ) -> ConditionallyBridgedValueType { + x: ClassA, + inout result: ConditionallyBridgedValueType? + ) { assert(x.value % 2 == 0, "not bridged from Objective-C") - return ConditionallyBridgedValueType(value: x.value) + result = ConditionallyBridgedValueType(value: x.value) } - static func _conditionallyBridgeFromObjectiveC(x: ClassA) - -> ConditionallyBridgedValueType? { + static func _conditionallyBridgeFromObjectiveC( + x: ClassA, + inout result: ConditionallyBridgedValueType? + ) -> Bool { if x.value % 2 == 0 { - return ConditionallyBridgedValueType(value: x.value) + result = ConditionallyBridgedValueType(value: x.value) + return true } - return .None + + result = nil + return false } static func _isBridgedToObjectiveC() -> Bool {