diff --git a/lib/SIL/DynamicCasts.cpp b/lib/SIL/DynamicCasts.cpp index c5551b1225bc9..56c6c6c2f9b52 100644 --- a/lib/SIL/DynamicCasts.cpp +++ b/lib/SIL/DynamicCasts.cpp @@ -1134,19 +1134,22 @@ bool swift::canUseScalarCheckedCastInstructions(SILModule &M, if (!objectType.isAnyClassReferenceType()) return false; + if (M.getASTContext().LangOpts.EnableObjCInterop) { auto super = archetype->getSuperclass(); if (super.isNull()) return false; - // A base class constraint that isn't NSError rules out the archetype being - // bound to NSError. - if (M.getASTContext().LangOpts.EnableObjCInterop) { - if (auto nserror = M.Types.getNSErrorType()) - return !super->isEqual(nserror); + // A base class constraint that isn't NSError rules out the archetype being + // bound to NSError. + if (auto nserror = M.Types.getNSErrorType()) + return !super->isEqual(nserror); + // If NSError wasn't loaded, any base class constraint must not be NSError. + return true; + } else { + // If ObjC bridging isn't enabled, we can do a scalar cast from any + // reference type to any class-constrained archetype. + return archetype->requiresClass(); } - - // If NSError wasn't loaded, any base class constraint must not be NSError. - return true; } if (M.getASTContext().LangOpts.EnableObjCInterop diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp index b32aa543be8b2..ca672031c316c 100644 --- a/lib/Sema/CSApply.cpp +++ b/lib/Sema/CSApply.cpp @@ -3686,7 +3686,10 @@ namespace { auto *locator = cs.getConstraintLocator(expr); if (!choice) { - choice = solution.getDisjunctionChoice(locator); + if (tc.Context.LangOpts.EnableObjCInterop) + choice = solution.getDisjunctionChoice(locator); + else + choice = 0; } // Handle the coercion/bridging of the underlying subexpression, where diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index 6593d89b65344..6556fa6c80d5c 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -3627,6 +3627,11 @@ ConstraintSystem::simplifyBridgingConstraint(Type type1, Type type2, TypeMatchOptions flags, ConstraintLocatorBuilder locator) { + // There's no bridging without ObjC interop, so we shouldn't have set up + // bridging constraints without it. + assert(TC.Context.LangOpts.EnableObjCInterop + && "bridging constraint w/o ObjC interop?!"); + TypeMatchOptions subflags = getDefaultDecompositionOptions(flags); /// Form an unresolved result. @@ -5071,11 +5076,14 @@ void ConstraintSystem::addExplicitConversionConstraint( coerceConstraint->setFavored(); constraints.push_back(coerceConstraint); - // The source type can be explicitly converted to the destination type. - Constraint *bridgingConstraint = - Constraint::create(*this, ConstraintKind::BridgingConversion, - fromType, toType, locatorPtr); - constraints.push_back(bridgingConstraint); + // Bridging. + if (getASTContext().LangOpts.EnableObjCInterop) { + // The source type can be explicitly converted to the destination type. + Constraint *bridgingConstraint = + Constraint::create(*this, ConstraintKind::BridgingConversion, + fromType, toType, locatorPtr); + constraints.push_back(bridgingConstraint); + } if (allowFixes && shouldAttemptFixes()) { Constraint *downcastConstraint = @@ -5086,8 +5094,8 @@ void ConstraintSystem::addExplicitConversionConstraint( } addDisjunctionConstraint(constraints, locator, - allowFixes ? RememberChoice - : ForgetChoice); + getASTContext().LangOpts.EnableObjCInterop && allowFixes ? RememberChoice + : ForgetChoice); } ConstraintSystem::SolutionKind diff --git a/lib/Sema/Constraint.cpp b/lib/Sema/Constraint.cpp index 622cfb1275d74..68a7545c403e9 100644 --- a/lib/Sema/Constraint.cpp +++ b/lib/Sema/Constraint.cpp @@ -612,6 +612,10 @@ Constraint *Constraint::create(ConstraintSystem &cs, ConstraintKind kind, assert((kind != ConstraintKind::LiteralConformsTo) || second->is()); + // Bridging constraints require bridging to be enabled. + assert(kind != ConstraintKind::BridgingConversion + || cs.TC.Context.LangOpts.EnableObjCInterop); + // Create the constraint. unsigned size = totalSizeToAlloc(typeVars.size()); void *mem = cs.getAllocator().Allocate(size, alignof(Constraint)); diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp index 560c2d1e42cca..0afa47c533c09 100644 --- a/lib/Sema/TypeCheckConstraints.cpp +++ b/lib/Sema/TypeCheckConstraints.cpp @@ -2881,7 +2881,8 @@ bool TypeChecker::isExplicitlyConvertibleTo(Type type1, Type type2, bool TypeChecker::isObjCBridgedTo(Type type1, Type type2, DeclContext *dc, bool *unwrappedIUO) { - return (typesSatisfyConstraint(type1, type2, + return (Context.LangOpts.EnableObjCInterop && + typesSatisfyConstraint(type1, type2, /*openArchetypes=*/false, ConstraintKind::BridgingConversion, dc, unwrappedIUO)); @@ -3393,8 +3394,9 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType, } // Check for a bridging conversion. - // Anything bridges to AnyObject. - if (toType->isAnyObject()) + // Anything bridges to AnyObject in ObjC interop mode. + if (Context.LangOpts.EnableObjCInterop + && toType->isAnyObject()) return CheckedCastKind::BridgingCoercion; // Do this check later in Swift 3 mode so that we check for NSNumber and diff --git a/stdlib/public/SDK/ObjectiveC/ObjectiveC.swift b/stdlib/public/SDK/ObjectiveC/ObjectiveC.swift index afa39317a9190..96396389970ef 100644 --- a/stdlib/public/SDK/ObjectiveC/ObjectiveC.swift +++ b/stdlib/public/SDK/ObjectiveC/ObjectiveC.swift @@ -10,8 +10,6 @@ // //===----------------------------------------------------------------------===// -#if _runtime(_ObjC) - @_exported import ObjectiveC import _SwiftObjectiveCOverlayShims @@ -227,5 +225,3 @@ extension NSObject : CVarArg { } } -#endif - diff --git a/stdlib/public/core/BridgeObjectiveC.swift b/stdlib/public/core/BridgeObjectiveC.swift index 0bfef9aced7b8..b26c720f31833 100644 --- a/stdlib/public/core/BridgeObjectiveC.swift +++ b/stdlib/public/core/BridgeObjectiveC.swift @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +#if _runtime(_ObjC) /// A Swift Array or Dictionary of types conforming to /// `_ObjectiveCBridgeable` can be passed to Objective-C as an NSArray or /// NSDictionary, respectively. The elements of the resulting NSArray @@ -82,8 +83,6 @@ public protocol _ObjectiveCBridgeable { -> Self } -#if _runtime(_ObjC) - //===--- Bridging for metatypes -------------------------------------------===// /// A stand-in for a value of metatype type. @@ -641,200 +640,3 @@ public func _getObjCTypeEncoding(_ type: T.Type) -> UnsafePointer { } #endif - -//===--- Bridging without the ObjC runtime --------------------------------===// - -#if !_runtime(_ObjC) - -/// Convert `x` from its Objective-C representation to its Swift -/// representation. -/// COMPILER_INTRINSIC -@_inlineable // FIXME(sil-serialize-all) -public func _forceBridgeFromObjectiveC_bridgeable ( - _ x: T._ObjectiveCType, - _: T.Type -) -> T { - var result: T? - T._forceBridgeFromObjectiveC(x, result: &result) - return result! -} - -/// Attempt to convert `x` from its Objective-C representation to its Swift -/// representation. -/// COMPILER_INTRINSIC -@_inlineable // FIXME(sil-serialize-all) -public func _conditionallyBridgeFromObjectiveC_bridgeable( - _ x: T._ObjectiveCType, - _: T.Type -) -> T? { - var result: T? - T._conditionallyBridgeFromObjectiveC (x, result: &result) - return result -} - -public // SPI(Foundation) -protocol _NSSwiftValue: class { - init(_ value: Any) - var value: Any { get } - static var null: AnyObject { get } -} - -@usableFromInline -internal class _SwiftValue { - @usableFromInline - let value: Any - - @usableFromInline - init(_ value: Any) { - self.value = value - } - - @usableFromInline - static let null = _SwiftValue(Optional.none as Any) -} - -/// COMPILER_INTRISIC -@_silgen_name("swift_unboxFromSwiftValueWithType") -public func swift_unboxFromSwiftValueWithType( - _ source: inout AnyObject, - _ result: UnsafeMutablePointer - ) -> Bool { - - if source === _nullPlaceholder { - if let unpacked = Optional.none as? T { - result.initialize(to: unpacked) - return true - } - } - - if let box = source as? _SwiftValue { - if let value = box.value as? T { - result.initialize(to: value) - return true - } - } else if let box = source as? _NSSwiftValue { - if let value = box.value as? T { - result.initialize(to: value) - return true - } - } - - return false -} - -@_silgen_name("_swift_extractDynamicValue") -public func _extractDynamicValue(_ value: T) -> AnyObject? - -@_silgen_name("_swift_bridgeToObjectiveCUsingProtocolIfPossible") -public func _bridgeToObjectiveCUsingProtocolIfPossible(_ value: T) -> AnyObject? - -@usableFromInline -protocol _Unwrappable { - func unwrap() -> Any? -} - -extension Optional: _Unwrappable { - func unwrap() -> Any? { - return self - } -} - -// This is a best-effort tripmine for detecting the situation -// (which should never happen) of Swift._SwiftValue and -// Foundation._SwiftValue/Foundation.NSNull being used -// in the same process. - -@usableFromInline -internal enum _SwiftValueFlavor: Equatable { - case stdlib - case foundation -} - -@usableFromInline -func _currentSwiftValueFlavor() -> _SwiftValueFlavor { - if _typeByName("Foundation._SwiftValue") as? _NSSwiftValue.Type != nil { - return .foundation - } else { - return .stdlib - } -} - -@usableFromInline -internal var _selectedSwiftValueFlavor: _SwiftValueFlavor = _currentSwiftValueFlavor() - -@usableFromInline -internal func _assertSwiftValueFlavorIsConsistent() { - assert(_selectedSwiftValueFlavor == _currentSwiftValueFlavor()) -} - -@usableFromInline -internal var _nullPlaceholder: AnyObject { - _assertSwiftValueFlavorIsConsistent() - if let foundationType = _typeByName("Foundation._SwiftValue") as? _NSSwiftValue.Type { - return foundationType.null - } else { - return _SwiftValue.null - } -} - -@usableFromInline -func _makeSwiftValue(_ value: Any) -> AnyObject { - _assertSwiftValueFlavorIsConsistent() - if let foundationType = _typeByName("Foundation._SwiftValue") as? _NSSwiftValue.Type { - return foundationType.init(value) - } else { - return _SwiftValue(value) - } -} - -/// Bridge an arbitrary value to an Objective-C object. -/// -/// - If `T` is a class type, it is always bridged verbatim, the function -/// returns `x`; -/// -/// - otherwise, if `T` conforms to `_ObjectiveCBridgeable`, -/// returns the result of `x._bridgeToObjectiveC()`; -/// -/// - otherwise, we use **boxing** to bring the value into Objective-C. -/// The value is wrapped in an instance of a private Objective-C class -/// that is `id`-compatible and dynamically castable back to the type of -/// the boxed value, but is otherwise opaque. -/// -/// COMPILER_INTRINSIC -@inlinable // FIXME(sil-serialize-all) -public func _bridgeAnythingToObjectiveC(_ x: T) -> AnyObject { - var done = false - var result: AnyObject! - - var source: Any = x - - if let dynamicSource = _extractDynamicValue(x) { - result = dynamicSource as AnyObject - done = true - } - - if !done, let wrapper = source as? _Unwrappable { - if let value = wrapper.unwrap() { - result = value as AnyObject - } else { - result = _nullPlaceholder - } - - done = true - } - - if !done { - if type(of: source) as? AnyClass != nil { - result = unsafeBitCast(x, to: AnyObject.self) - } else if let object = _bridgeToObjectiveCUsingProtocolIfPossible(source) { - result = object - } else { - result = _makeSwiftValue(source) - } - } - - return result -} - -#endif // !_runtime(_ObjC) - diff --git a/stdlib/public/core/Codable.swift.gyb b/stdlib/public/core/Codable.swift.gyb index 926e4bed21298..c9740c3131e7a 100644 --- a/stdlib/public/core/Codable.swift.gyb +++ b/stdlib/public/core/Codable.swift.gyb @@ -1171,7 +1171,7 @@ public enum EncodingError : Error { public var _userInfo: AnyObject? { // The error dictionary must be returned as an AnyObject. We can do this // only on platforms with bridging, unfortunately. - #if _runtime(_ObjC) + #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) let context: Context switch self { case .invalidValue(_, let c): context = c @@ -1281,7 +1281,7 @@ public enum DecodingError : Error { public var _userInfo: AnyObject? { // The error dictionary must be returned as an AnyObject. We can do this // only on platforms with bridging, unfortunately. - #if _runtime(_ObjC) + #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) let context: Context switch self { case .keyNotFound(_, let c): context = c diff --git a/stdlib/public/runtime/Casting.cpp b/stdlib/public/runtime/Casting.cpp index ac711bd2cada6..26e1ad9600fbc 100644 --- a/stdlib/public/runtime/Casting.cpp +++ b/stdlib/public/runtime/Casting.cpp @@ -196,6 +196,7 @@ swift::swift_dynamicCastFailure(const Metadata *sourceType, targetType, targetName.c_str(), message); } +#if SWIFT_OBJC_INTEROP // Objective-C bridging helpers. namespace { struct _ObjectiveCBridgeableWitnessTable; @@ -226,6 +227,7 @@ static bool _dynamicCastClassToValueViaObjCBridgeable( const Metadata *targetType, const _ObjectiveCBridgeableWitnessTable *targetBridgeWitness, DynamicCastFlags flags); +#endif /// A convenient method for failing out of a dynamic cast. static bool _fail(OpaqueValue *srcValue, const Metadata *srcType, @@ -798,7 +800,7 @@ static bool _dynamicCastToExistential(OpaqueValue *dest, // A fallback to use if we don't have a more specialized approach // for a non-class type. auto fallbackForNonClass = [&] { -#if SWIFT_OBJC_INTEROP // TODO +#if SWIFT_OBJC_INTEROP // If the destination type is a set of protocols that SwiftValue // implements, we're fine. if (findSwiftValueConformances(targetType, @@ -858,6 +860,7 @@ static bool _dynamicCastToExistential(OpaqueValue *dest, case MetadataKind::Enum: case MetadataKind::Optional: +#if SWIFT_OBJC_INTEROP // If the source type is bridged to Objective-C, try to bridge. if (auto srcBridgeWitness = findBridgeWitness(srcDynamicType)) { bool success = _dynamicCastValueToClassExistentialViaObjCBridgeable( @@ -870,6 +873,7 @@ static bool _dynamicCastToExistential(OpaqueValue *dest, maybeDeallocateSource(success); return success; } +#endif LLVM_FALLTHROUGH; case MetadataKind::Function: @@ -1327,6 +1331,7 @@ swift_dynamicCastMetatypeUnconditionalImpl(const Metadata *sourceType, /********************************** Classes ***********************************/ /******************************************************************************/ +#if SWIFT_OBJC_INTEROP /// Do a dynamic cast to the target class. static void *_dynamicCastUnknownClass(void *object, const Metadata *targetType, @@ -1339,6 +1344,7 @@ static void *_dynamicCastUnknownClass(void *object, return const_cast(swift_dynamicCastUnknownClass(object, targetType)); } +#endif static bool _dynamicCastUnknownClassIndirect(OpaqueValue *dest, void *object, @@ -2047,13 +2053,7 @@ checkDynamicCastFromOptional(OpaqueValue *dest, /**************************** Bridging _SwiftValue ****************************/ /******************************************************************************/ -#if !SWIFT_OBJC_INTEROP // _SwiftValue is a native class -SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL -bool swift_unboxFromSwiftValueWithType(OpaqueValue *source, - OpaqueValue *result, - const Metadata *destinationType); -#endif - +#if SWIFT_OBJC_INTEROP /// Try to unbox a _SwiftValue box to perform a dynamic cast. static bool tryDynamicCastBoxedSwiftValue(OpaqueValue *dest, OpaqueValue *src, @@ -2071,14 +2071,6 @@ static bool tryDynamicCastBoxedSwiftValue(OpaqueValue *dest, return false; } -#if !SWIFT_OBJC_INTEROP // _SwiftValue is a native class: - // TODO: memory management? - if (swift_unboxFromSwiftValueWithType(src, dest, targetType)) { - return true; - } -#endif - -#if SWIFT_OBJC_INTEROP // _SwiftValue is an ObjC class: id srcObject; memcpy(&srcObject, src, sizeof(id)); @@ -2118,10 +2110,10 @@ static bool tryDynamicCastBoxedSwiftValue(OpaqueValue *dest, objc_release((id)srcSwiftValue); return true; } -#endif return false; } +#endif /******************************************************************************/ /******************************** Collections *********************************/ @@ -2416,6 +2408,7 @@ static bool swift_dynamicCastImpl(OpaqueValue *dest, OpaqueValue *src, if (!srcType) return unwrapResult.success; +#if SWIFT_OBJC_INTEROP // A class or AnyObject reference may point to a _SwiftValue box. { auto innerFlags = flags - DynamicCastFlags::Unconditional @@ -2430,6 +2423,7 @@ static bool swift_dynamicCastImpl(OpaqueValue *dest, OpaqueValue *src, // (for example, casting _SwiftValue to NSObject will be successful) } } +#endif switch (targetType->getKind()) { // Handle wrapping an Optional target. @@ -2438,6 +2432,7 @@ static bool swift_dynamicCastImpl(OpaqueValue *dest, OpaqueValue *src, // unwrapping the target. This handles an optional source wrapped within an // existential that Optional conforms to (Any). if (auto srcExistentialType = dyn_cast(srcType)) { +#if SWIFT_OBJC_INTEROP // If coming from AnyObject, we may want to bridge. if (isAnyObjectExistentialType(srcExistentialType)) { if (auto targetBridgeWitness = findBridgeWitness(targetType)) { @@ -2447,6 +2442,7 @@ static bool swift_dynamicCastImpl(OpaqueValue *dest, OpaqueValue *src, flags); } } +#endif return _dynamicCastFromExistential(dest, src, srcExistentialType, targetType, flags); } @@ -2511,6 +2507,7 @@ static bool swift_dynamicCastImpl(OpaqueValue *dest, OpaqueValue *src, case MetadataKind::Enum: case MetadataKind::Optional: { +#if SWIFT_OBJC_INTEROP // If the source type is bridged to Objective-C, try to bridge. if (auto srcBridgeWitness = findBridgeWitness(srcType)) { return _dynamicCastValueToClassViaObjCBridgeable(dest, src, srcType, @@ -2518,6 +2515,7 @@ static bool swift_dynamicCastImpl(OpaqueValue *dest, OpaqueValue *src, srcBridgeWitness, flags); } +#endif return _fail(src, srcType, targetType, flags); } @@ -2566,6 +2564,7 @@ static bool swift_dynamicCastImpl(OpaqueValue *dest, OpaqueValue *src, return _dynamicCastToAnyHashable(dest, src, srcType, targetType, flags); } +#if SWIFT_OBJC_INTEROP // If the target type is bridged to Objective-C, try to bridge. if (auto targetBridgeWitness = findBridgeWitness(targetType)) { return _dynamicCastClassToValueViaObjCBridgeable(dest, src, srcType, @@ -2574,7 +2573,6 @@ static bool swift_dynamicCastImpl(OpaqueValue *dest, OpaqueValue *src, flags); } -#if SWIFT_OBJC_INTEROP // If the source is an NSError, and the target is a bridgeable // Error, try to bridge. if (tryDynamicCastNSErrorToValue(dest, src, srcType, targetType, flags)) { @@ -2673,6 +2671,7 @@ static inline bool swift_isClassOrObjCExistentialTypeImpl(const Metadata *T) { /********************************** Bridging **********************************/ /******************************************************************************/ +#if SWIFT_OBJC_INTEROP //===----------------------------------------------------------------------===// // Bridging to and from Objective-C //===----------------------------------------------------------------------===// @@ -2893,13 +2892,6 @@ static bool _dynamicCastClassToValueViaObjCBridgeable( return success; } -#if !SWIFT_OBJC_INTEROP // _SwiftValue is a native class: - - - -#endif // !_SWIFT_OBJC_INTEROP - -#if SWIFT_OBJC_INTEROP static id bridgeAnythingNonVerbatimToObjectiveC(OpaqueValue *src, const Metadata *srcType, bool consume) { @@ -3000,7 +2992,6 @@ id _bridgeAnythingNonVerbatimToObjectiveC(OpaqueValue *src, return bridgeAnythingNonVerbatimToObjectiveC(src, srcType, /*consume*/shouldConsume); } -#endif //===--- Bridging helpers for the Swift stdlib ----------------------------===// // Functions that must discover and possibly use an arbitrary type's @@ -3008,12 +2999,10 @@ id _bridgeAnythingNonVerbatimToObjectiveC(OpaqueValue *src, // documentation. //===----------------------------------------------------------------------===// -#if SWIFT_OBJC_INTEROP #define BRIDGING_CONFORMANCE_SYM \ MANGLE_SYM(s19_BridgeableMetatypeVs21_ObjectiveCBridgeablesWP) extern "C" const _ObjectiveCBridgeableWitnessTable BRIDGING_CONFORMANCE_SYM; -#endif static const _ObjectiveCBridgeableWitnessTable * findBridgeWitness(const Metadata *T) { @@ -3026,20 +3015,16 @@ findBridgeWitness(const Metadata *T) { // that looks like a metatype value if the metatype can be bridged. switch (T->getKind()) { case MetadataKind::Metatype: { -#if SWIFT_OBJC_INTEROP auto metaTy = static_cast(T); if (metaTy->InstanceType->isAnyClass()) return &BRIDGING_CONFORMANCE_SYM; -#endif break; } case MetadataKind::ExistentialMetatype: { -#if SWIFT_OBJC_INTEROP auto existentialMetaTy = static_cast(T); if (existentialMetaTy->isObjC()) return &BRIDGING_CONFORMANCE_SYM; -#endif break; } @@ -3081,8 +3066,6 @@ const Metadata *_getBridgedNonVerbatimObjectiveCType( return nullptr; } -#if SWIFT_OBJC_INTEROP - // @_silgen_name("_bridgeNonVerbatimFromObjectiveCToAny") // func _bridgeNonVerbatimFromObjectiveCToAny( // x: AnyObject, @@ -3119,6 +3102,7 @@ static bool tryBridgeNonVerbatimFromObjectiveCUniversal( return true; } } + // Check if the value is a box containing a value of the desired type. if (auto srcBox = getAsSwiftValue((id)sourceValue)) { const Metadata *sourceType; @@ -3150,7 +3134,6 @@ _bridgeNonVerbatimFromObjectiveC( OpaqueValue *destValue, const Metadata *nativeType_ ) { - if (tryBridgeNonVerbatimFromObjectiveCUniversal(sourceValue, nativeType, destValue)) return; @@ -3228,8 +3211,6 @@ _bridgeNonVerbatimFromObjectiveCConditional( destValue, nativeType, nativeType, bridgeWitness); } -#endif // SWIFT_OBJC_INTEROP - // func _isBridgedNonVerbatimToObjectiveC(_: T.Type) -> Bool // Called by inlined stdlib code. #define _isBridgedNonVerbatimToObjectiveC \ @@ -3242,6 +3223,7 @@ bool _isBridgedNonVerbatimToObjectiveC(const Metadata *value, auto bridgeWitness = findBridgeWitness(T); return (bool)bridgeWitness; } +#endif // func _isClassOrObjCExistential(x: T.Type) -> Bool SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE @@ -3270,55 +3252,6 @@ bool swift_isOptionalType(const Metadata *type) { return type->getKind() == MetadataKind::Optional; } -#if !SWIFT_OBJC_INTEROP -SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL -bool _swift_isOptional(OpaqueValue *src, const Metadata *type) { - return swift_isOptionalType(type); -} - -SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL -HeapObject *_swift_extractDynamicValue(OpaqueValue *value, const Metadata *self) { - OpaqueValue *outValue; - const Metadata *outType; - bool canTake = false; - - findDynamicValueAndType(value, self, outValue, outType, canTake, - /*isAnyObject*/ true, - /*isExistentialMetatype*/ true); - - if (!outType || (outType != self && outType->isAnyClass())) { - HeapObject *object = *(reinterpret_cast(outValue)); - swift_retain(object); - return object; - } - - return nullptr; -} - -SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL -HeapObject *_swift_bridgeToObjectiveCUsingProtocolIfPossible( - OpaqueValue *src, const Metadata *srcType) { - assert(!swift_isClassOrObjCExistentialTypeImpl(srcType)); - - OpaqueValue *outValue; - const Metadata *outType; - bool canTake = false; - - findDynamicValueAndType(src, srcType, outValue, outType, canTake, - /*isAnyObject*/ false, - /*isExistentialMetatype*/ true); - - auto bridgeWitness = findBridgeWitness(outType); - if (bridgeWitness) { - auto bridgedObject = - bridgeWitness->bridgeToObjectiveC(outValue, outType, bridgeWitness); - return bridgedObject; - } else { - return nullptr; - } -} -#endif - #define OVERRIDE_CASTING COMPATIBILITY_OVERRIDE #include "CompatibilityOverride.def" diff --git a/test/Constraints/bridging_nonobjc.swift b/test/Constraints/bridging_nonobjc.swift new file mode 100644 index 0000000000000..f2c06ee9e168b --- /dev/null +++ b/test/Constraints/bridging_nonobjc.swift @@ -0,0 +1,5 @@ +// RUN: %target-swift-frontend -typecheck -verify %s -disable-objc-interop + + +var x: Any = 1 +var y = x as AnyObject // expected-error{{not convertible}} diff --git a/test/Interpreter/generic_casts.swift b/test/Interpreter/generic_casts.swift index 4008fe16b05f4..0705141eaacac 100644 --- a/test/Interpreter/generic_casts.swift +++ b/test/Interpreter/generic_casts.swift @@ -158,6 +158,16 @@ print(allToAll(type(of: C()), AnyObject.self)) // CHECK-NEXT: true // Bridging print(allToAll(0, AnyObject.self)) // CHECK-NEXT: true +// This will get bridged using _SwiftValue. +struct NotBridged { var x: Int } +print(allToAll(NotBridged(x: 0), AnyObject.self)) // CHECK-NEXT: true +print(allToAll(NotBridged(x: 0), NSCopying.self)) // CHECK-NEXT: true + +// These casts fail (intentionally) even though _SwiftValue does +// technically conform to these protocols through NSObject. +print(allToAll(NotBridged(x: 0), CustomStringConvertible.self)) // CHECK-NEXT: false +print(allToAll(NotBridged(x: 0), (AnyObject & CustomStringConvertible).self)) // CHECK-NEXT: false + // // rdar://problem/19482567 // diff --git a/test/SILGen/generic_casts.swift b/test/SILGen/generic_casts.swift index 74aace8820469..3a8e7fc066f43 100644 --- a/test/SILGen/generic_casts.swift +++ b/test/SILGen/generic_casts.swift @@ -59,9 +59,11 @@ func class_archetype_to_class_archetype (_ t:T) -> U { return t as! U // Error bridging can change the identity of class-constrained archetypes. - // CHECK: unconditional_checked_cast_addr T in {{%.*}} : $*T to U in [[DOWNCAST_ADDR:%.*]] : $*U - // CHECK: [[DOWNCAST:%.*]] = load [take] [[DOWNCAST_ADDR]] - // CHECK: return [[DOWNCAST]] : $U + // CHECK-objc: unconditional_checked_cast_addr T in {{%.*}} : $*T to U in [[DOWNCAST_ADDR:%.*]] : $*U + // CHECK-objc: [[DOWNCAST:%.*]] = load [take] [[DOWNCAST_ADDR]] + // CHECK-objc: return [[DOWNCAST]] : $U + + // CHECK-native: [[DOWNCAST:%.*]] = unconditional_checked_cast {{.*}} : $T to $U } // CHECK-LABEL: sil hidden @$S13generic_casts019class_archetype_is_c1_D0{{[_0-9a-zA-Z]*}}F @@ -69,7 +71,8 @@ func class_archetype_is_class_archetype (_ t:T, u:U.Type) -> Bool { return t is U // Error bridging can change the identity of class-constrained archetypes. - // CHECK: checked_cast_addr_br {{.*}} T in {{%.*}} : $*T to U in {{%.*}} : $*U + // CHECK-objc: checked_cast_addr_br {{.*}} T in {{%.*}} : $*T to U in {{%.*}} : $*U + // CHECK-native: checked_cast_br {{.*}} : $T to $U } // CHECK-LABEL: sil hidden @$S13generic_casts38opaque_archetype_to_addr_only_concrete{{[_0-9a-zA-Z]*}}F @@ -158,16 +161,19 @@ func opaque_existential_is_class_archetype func class_existential_to_class_archetype (_ p:ClassBound) -> T { return p as! T - // CHECK: unconditional_checked_cast_addr ClassBound in {{%.*}} : $*ClassBound to T in [[DOWNCAST_ADDR:%.*]] : $*T - // CHECK: [[DOWNCAST:%.*]] = load [take] [[DOWNCAST_ADDR]] - // CHECK: return [[DOWNCAST]] : $T + // CHECK-objc: unconditional_checked_cast_addr ClassBound in {{%.*}} : $*ClassBound to T in [[DOWNCAST_ADDR:%.*]] : $*T + // CHECK-objc: [[DOWNCAST:%.*]] = load [take] [[DOWNCAST_ADDR]] + // CHECK-objc: return [[DOWNCAST]] : $T + + // CHECK-native: [[DOWNCAST:%.*]] = unconditional_checked_cast {{.*}} : $ClassBound to $T } // CHECK-LABEL: sil hidden @$S13generic_casts021class_existential_is_C10_archetype{{[_0-9a-zA-Z]*}}F func class_existential_is_class_archetype (_ p:ClassBound, _: T) -> Bool { return p is T - // CHECK: checked_cast_addr_br {{.*}} ClassBound in {{%.*}} : $*ClassBound to T in {{%.*}} : $*T + // CHECK-objc: checked_cast_addr_br {{.*}} ClassBound in {{%.*}} : $*ClassBound to T in {{%.*}} : $*T + // CHECK-native: checked_cast_br {{.*}} : $ClassBound to $T } // CHECK-LABEL: sil hidden @$S13generic_casts40opaque_existential_to_addr_only_concrete{{[_0-9a-zA-Z]*}}F diff --git a/test/expr/cast/array_downcast.swift b/test/expr/cast/array_downcast.swift index fddea8a4742fd..475036de10fe9 100644 --- a/test/expr/cast/array_downcast.swift +++ b/test/expr/cast/array_downcast.swift @@ -1,5 +1,7 @@ // RUN: %target-typecheck-verify-swift +// XFAIL: linux + // FIXME: Should go into the standard library. public extension _ObjectiveCBridgeable { static func _unconditionallyBridgeFromObjectiveC(_ source: _ObjectiveCType?) diff --git a/test/stmt/errors_nonobjc.swift b/test/stmt/errors_nonobjc.swift new file mode 100644 index 0000000000000..7f710f7bcb07c --- /dev/null +++ b/test/stmt/errors_nonobjc.swift @@ -0,0 +1,18 @@ +// RUN: %empty-directory(%t) +// RUN: %target-swift-frontend -emit-module -module-name Foundation -o %t/Foundation.swiftmodule %S/Inputs/Foundation-with-NSError.swift +// RUN: %target-swift-frontend -I %t -typecheck -verify %s +// UNSUPPORTED: objc_interop + +import Foundation + +// Catching `as NSError` ought *not* to be exhaustive when ObjC interop is +// disabled. It's just another error type. + +func bar() throws {} + +func foo() { + do { + try bar() // expected-error{{enclosing catch is not exhaustive}} + } catch _ as NSError { + } +} diff --git a/unittests/runtime/Stdlib.cpp b/unittests/runtime/Stdlib.cpp index 03ed7d5c955eb..649513372085d 100644 --- a/unittests/runtime/Stdlib.cpp +++ b/unittests/runtime/Stdlib.cpp @@ -135,12 +135,7 @@ void _bridgeNonVerbatimFromObjectiveCToAny(HeapObject *sourceValue, abort(); } -SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL -bool swift_unboxFromSwiftValueWithType(OpaqueValue *source, - OpaqueValue *result, - const Metadata *destinationType) { - abort(); -} + // ErrorObject SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL