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 {