Skip to content

Commit 38fdb33

Browse files
Merge pull request #26849 from aschwaighofer/revert_remove_dep_foundation
Revert "Remove stdlib and runtime dependencies on Foundation and CF"
2 parents af0247e + fe69a86 commit 38fdb33

22 files changed

+316
-380
lines changed

include/swift/Runtime/ObjCBridge.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,6 @@ namespace swift {
7979
SWIFT_RUNTIME_EXPORT
8080
void swift_rootObjCDealloc(HeapObject *self);
8181

82-
// Uses Swift bridging to box a C string into an NSString without introducing
83-
// a link-time dependency on NSString.
84-
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_API
85-
id swift_stdlib_NSStringFromUTF8(const char *cstr, int len);
86-
8782
}
8883

8984
#endif // SWIFT_OBJC_INTEROP

stdlib/public/core/BridgeObjectiveC.swift

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -85,22 +85,6 @@ public protocol _ObjectiveCBridgeable {
8585

8686
#if _runtime(_ObjC)
8787

88-
@_silgen_name("swift_stdlib_connectNSBaseClasses")
89-
internal func _connectNSBaseClasses() -> Bool
90-
91-
92-
private let _bridgeInitializedSuccessfully = _connectNSBaseClasses()
93-
internal var _orphanedFoundationSubclassesReparented: Bool = false
94-
95-
/// Reparents the SwiftNativeNS*Base classes to be subclasses of their respective
96-
/// Foundation types, or is false if they couldn't be reparented. Must be run
97-
/// in order to bridge Swift Strings, Arrays, Dictionarys, Sets, or Enumerators to ObjC.
98-
internal func _connectOrphanedFoundationSubclassesIfNeeded() -> Void {
99-
let bridgeWorks = _bridgeInitializedSuccessfully
100-
_debugPrecondition(bridgeWorks)
101-
_orphanedFoundationSubclassesReparented = true
102-
}
103-
10488
//===--- Bridging for metatypes -------------------------------------------===//
10589

10690
/// A stand-in for a value of metatype type.

stdlib/public/core/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ set(swift_core_private_link_libraries)
229229
set(swift_stdlib_compile_flags "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}")
230230
if(SWIFT_PRIMARY_VARIANT_SDK IN_LIST SWIFT_APPLE_PLATFORMS)
231231
list(APPEND swift_core_link_flags "-all_load")
232+
list(APPEND swift_core_framework_depends Foundation)
233+
list(APPEND swift_core_framework_depends CoreFoundation)
232234
list(APPEND swift_core_private_link_libraries icucore)
233235
else()
234236
# With the GNU linker the equivalent of -all_load is to tell the linker

stdlib/public/core/ContiguousArrayBuffer.swift

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -417,27 +417,13 @@ internal struct _ContiguousArrayBuffer<Element>: _ArrayBufferProtocol {
417417
}
418418

419419
#if _runtime(_ObjC)
420-
421420
/// Convert to an NSArray.
422421
///
423422
/// - Precondition: `Element` is bridged to Objective-C.
424423
///
425424
/// - Complexity: O(1).
426-
@usableFromInline
425+
@inlinable
427426
internal __consuming func _asCocoaArray() -> AnyObject {
428-
// _asCocoaArray was @inlinable in Swift 5.0 and 5.1, which means that there
429-
// are existing apps out there that effectively have the old implementation
430-
// Be careful with future changes to this function. Here be dragons!
431-
// The old implementation was
432-
// if count == 0 {
433-
// return _emptyArrayStorage
434-
// }
435-
// if _isBridgedVerbatimToObjectiveC(Element.self) {
436-
// return _storage
437-
// }
438-
// return __SwiftDeferredNSArray(_nativeStorage: _storage)
439-
440-
_connectOrphanedFoundationSubclassesIfNeeded()
441427
if count == 0 {
442428
return _emptyArrayStorage
443429
}

stdlib/public/core/DictionaryBridging.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ internal func _stdlib_NSDictionary_allKeys(
2929
extension _NativeDictionary { // Bridging
3030
@usableFromInline
3131
__consuming internal func bridged() -> AnyObject {
32-
_connectOrphanedFoundationSubclassesIfNeeded()
3332
// We can zero-cost bridge if our keys are verbatim
3433
// or if we're the empty singleton.
3534

@@ -68,7 +67,6 @@ final internal class _SwiftDictionaryNSEnumerator<Key: Hashable, Value>
6867

6968
internal init(_ base: __owned _NativeDictionary<Key, Value>) {
7069
_internalInvariant(_isBridgedVerbatimToObjectiveC(Key.self))
71-
_internalInvariant(_orphanedFoundationSubclassesReparented)
7270
self.base = base
7371
self.bridgedKeys = nil
7472
self.nextBucket = base.hashTable.startBucket
@@ -79,7 +77,6 @@ final internal class _SwiftDictionaryNSEnumerator<Key: Hashable, Value>
7977
@nonobjc
8078
internal init(_ deferred: __owned _SwiftDeferredNSDictionary<Key, Value>) {
8179
_internalInvariant(!_isBridgedVerbatimToObjectiveC(Key.self))
82-
_internalInvariant(_orphanedFoundationSubclassesReparented)
8380
self.base = deferred.native
8481
self.bridgedKeys = deferred.bridgeKeys()
8582
self.nextBucket = base.hashTable.startBucket

stdlib/public/core/Hashing.swift

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,7 @@ internal struct _UnmanagedAnyObjectArray {
7676
// renamed. The old name must not be used in the new runtime.
7777
final internal class __SwiftEmptyNSEnumerator
7878
: __SwiftNativeNSEnumerator, _NSEnumerator {
79-
internal override required init() {
80-
super.init()
81-
_internalInvariant(_orphanedFoundationSubclassesReparented)
82-
}
79+
internal override required init() { super.init() }
8380

8481
@objc
8582
internal func nextObject() -> AnyObject? {

stdlib/public/core/ReflectionMirror.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,10 @@ internal func getChild<T>(of value: T, type: Any.Type, index: Int) -> (label: St
4747
internal func _getQuickLookObject<T>(_: T) -> AnyObject?
4848

4949
@_silgen_name("_swift_stdlib_NSObject_isKindOfClass")
50-
internal func _isImpl(_ object: AnyObject, kindOf: UnsafePointer<CChar>) -> Bool
50+
internal func _isImpl(_ object: AnyObject, kindOf: AnyObject) -> Bool
5151

5252
internal func _is(_ object: AnyObject, kindOf `class`: String) -> Bool {
53-
return `class`.withCString {
54-
return _isImpl(object, kindOf: $0)
55-
}
53+
return _isImpl(object, kindOf: `class` as AnyObject)
5654
}
5755

5856
internal func _getClassPlaygroundQuickLook(

stdlib/public/core/SetBridging.swift

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,24 @@
1414

1515
import SwiftShims
1616

17+
@_silgen_name("swift_stdlib_CFSetGetValues")
18+
internal
19+
func _stdlib_CFSetGetValues(
20+
_ nss: AnyObject,
21+
_: UnsafeMutablePointer<AnyObject>)
22+
1723
/// Equivalent to `NSSet.allObjects`, but does not leave objects on the
1824
/// autorelease pool.
1925
internal func _stdlib_NSSet_allObjects(_ object: AnyObject) -> _BridgingBuffer {
2026
let nss = unsafeBitCast(object, to: _NSSet.self)
21-
let count = nss.count
22-
let storage = _BridgingBuffer(count)
23-
nss.getObjects(storage.baseAddress, count: count)
27+
let storage = _BridgingBuffer(nss.count)
28+
_stdlib_CFSetGetValues(nss, storage.baseAddress)
2429
return storage
2530
}
2631

2732
extension _NativeSet { // Bridging
2833
@usableFromInline
2934
internal __consuming func bridged() -> AnyObject {
30-
_connectOrphanedFoundationSubclassesIfNeeded()
31-
3235
// We can zero-cost bridge if our keys are verbatim
3336
// or if we're the empty singleton.
3437

@@ -67,7 +70,6 @@ final internal class _SwiftSetNSEnumerator<Element: Hashable>
6770

6871
internal init(_ base: __owned _NativeSet<Element>) {
6972
_internalInvariant(_isBridgedVerbatimToObjectiveC(Element.self))
70-
_internalInvariant(_orphanedFoundationSubclassesReparented)
7173
self.base = base
7274
self.bridgedElements = nil
7375
self.nextBucket = base.hashTable.startBucket
@@ -78,7 +80,6 @@ final internal class _SwiftSetNSEnumerator<Element: Hashable>
7880
@nonobjc
7981
internal init(_ deferred: __owned _SwiftDeferredNSSet<Element>) {
8082
_internalInvariant(!_isBridgedVerbatimToObjectiveC(Element.self))
81-
_internalInvariant(_orphanedFoundationSubclassesReparented)
8283
self.base = deferred.native
8384
self.bridgedElements = deferred.bridgeElements()
8485
self.nextBucket = base.hashTable.startBucket

stdlib/public/core/ShadowProtocols.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,6 @@ internal protocol _NSSetCore: _NSCopying, _NSFastEnumeration {
171171
/// supplies.
172172
@unsafe_no_objc_tagged_pointer @objc
173173
internal protocol _NSSet: _NSSetCore {
174-
@objc(getObjects:count:) func getObjects(
175-
_ buffer: UnsafeMutablePointer<AnyObject>,
176-
count: Int
177-
)
178174
}
179175

180176
/// A shadow for the API of NSNumber we will use in the core

stdlib/public/core/StringBridge.swift

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -442,9 +442,6 @@ extension String {
442442
@_effects(releasenone)
443443
public // SPI(Foundation)
444444
func _bridgeToObjectiveCImpl() -> AnyObject {
445-
446-
_connectOrphanedFoundationSubclassesIfNeeded()
447-
448445
// Smol ASCII a) may bridge to tagged pointers, b) can't contain a BOM
449446
if _guts.isSmallASCII {
450447
let maybeTagged = _guts.asSmall.withUTF8 { bufPtr in
@@ -456,7 +453,6 @@ extension String {
456453
}
457454
if let tagged = maybeTagged { return tagged }
458455
}
459-
460456
if _guts.isSmall {
461457
// We can't form a tagged pointer String, so grow to a non-small String,
462458
// and bridge that instead. Also avoids CF deleting any BOM that may be
@@ -501,17 +497,6 @@ public func _getDescription<T>(_ x: T) -> AnyObject {
501497
return String(reflecting: x)._bridgeToObjectiveCImpl()
502498
}
503499

504-
@_silgen_name("swift_stdlib_NSStringFromUTF8")
505-
@usableFromInline //this makes the symbol available to the runtime :(
506-
@available(macOS 9999, iOS 9999, tvOS 9999, watchOS 9999, *)
507-
internal func _NSStringFromUTF8(_ s: UnsafePointer<UInt8>, _ len: Int)
508-
-> AnyObject {
509-
return String(
510-
decoding: UnsafeBufferPointer(start: s, count: len),
511-
as: UTF8.self
512-
)._bridgeToObjectiveCImpl()
513-
}
514-
515500
#else // !_runtime(_ObjC)
516501

517502
internal class __SwiftNativeNSString {

stdlib/public/runtime/ErrorObject.mm

Lines changed: 20 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -42,28 +42,14 @@
4242
using namespace swift;
4343
using namespace swift::hashable_support;
4444

45-
// Mimic the memory layout of NSError so things don't go haywire when we
46-
// switch superclasses to the real thing.
47-
@interface __SwiftNSErrorLayoutStandin : NSObject {
48-
@private
49-
void *_reserved;
50-
NSInteger _code;
51-
id _domain;
52-
id _userInfo;
53-
}
54-
@end
55-
56-
@implementation __SwiftNSErrorLayoutStandin
57-
@end
58-
5945
/// A subclass of NSError used to represent bridged native Swift errors.
6046
/// This type cannot be subclassed, and should not ever be instantiated
6147
/// except by the Swift runtime.
6248
///
6349
/// NOTE: older runtimes called this _SwiftNativeNSError. The two must
6450
/// coexist, so it was renamed. The old name must not be used in the new
6551
/// runtime.
66-
@interface __SwiftNativeNSError : __SwiftNSErrorLayoutStandin
52+
@interface __SwiftNativeNSError : NSError
6753
@end
6854

6955
@implementation __SwiftNativeNSError
@@ -85,29 +71,29 @@ - (void)dealloc {
8571
// layout. This gives us a buffer in case NSError decides to change its stored
8672
// property order.
8773

88-
- (id /* NSString */)domain {
74+
- (NSString*)domain {
8975
auto error = (const SwiftError*)self;
9076
// The domain string should not be nil; if it is, then this error box hasn't
9177
// been initialized yet as an NSError.
9278
auto domain = error->domain.load(SWIFT_MEMORY_ORDER_CONSUME);
9379
assert(domain
9480
&& "Error box used as NSError before initialization");
9581
// Don't need to .retain.autorelease since it's immutable.
96-
return cf_const_cast<id>(domain);
82+
return cf_const_cast<NSString*>(domain);
9783
}
9884

9985
- (NSInteger)code {
10086
auto error = (const SwiftError*)self;
10187
return error->code.load(SWIFT_MEMORY_ORDER_CONSUME);
10288
}
10389

104-
- (id /* NSDictionary */)userInfo {
90+
- (NSDictionary*)userInfo {
10591
auto error = (const SwiftError*)self;
10692
auto userInfo = error->userInfo.load(SWIFT_MEMORY_ORDER_CONSUME);
10793
assert(userInfo
10894
&& "Error box used as NSError before initialization");
10995
// Don't need to .retain.autorelease since it's immutable.
110-
return cf_const_cast<id>(userInfo);
96+
return cf_const_cast<NSDictionary*>(userInfo);
11197
}
11298

11399
- (id)copyWithZone:(NSZone *)zone {
@@ -167,29 +153,16 @@ - (BOOL)isEqual:(id)other {
167153
@end
168154

169155
Class swift::getNSErrorClass() {
170-
return SWIFT_LAZY_CONSTANT(objc_lookUpClass("NSError"));
156+
return SWIFT_LAZY_CONSTANT([NSError class]);
171157
}
172158

173159
const Metadata *swift::getNSErrorMetadata() {
174160
return SWIFT_LAZY_CONSTANT(
175161
swift_getObjCClassMetadata((const ClassMetadata *)getNSErrorClass()));
176162
}
177163

178-
static Class getAndBridgeSwiftNativeNSErrorClass() {
179-
Class nsErrorClass = swift::getNSErrorClass();
180-
Class ourClass = [__SwiftNativeNSError class];
181-
// We want "err as AnyObject" to do *something* even without Foundation
182-
if (nsErrorClass) {
183-
#pragma clang diagnostic push
184-
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
185-
class_setSuperclass(ourClass, nsErrorClass);
186-
#pragma clang diagnostic pop
187-
}
188-
return ourClass;
189-
}
190-
191164
static Class getSwiftNativeNSErrorClass() {
192-
return SWIFT_LAZY_CONSTANT(getAndBridgeSwiftNativeNSErrorClass());
165+
return SWIFT_LAZY_CONSTANT([__SwiftNativeNSError class]);
193166
}
194167

195168
/// Allocate a catchable error object.
@@ -301,7 +274,7 @@ static ErrorBridgingInfo getErrorBridgingInfo() {
301274

302275
const Metadata *SwiftError::getType() const {
303276
if (isPureNSError()) {
304-
id asError = reinterpret_cast<id>(const_cast<SwiftError *>(this));
277+
auto asError = reinterpret_cast<NSError *>(const_cast<SwiftError *>(this));
305278
return swift_getObjCClassMetadata((ClassMetadata*)[asError class]);
306279
}
307280
return type;
@@ -390,9 +363,9 @@ static ErrorBridgingInfo getErrorBridgingInfo() {
390363
#define getErrorDomainNSString \
391364
MANGLE_SYM(s23_getErrorDomainNSStringyyXlSPyxGs0B0RzlF)
392365
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
393-
id getErrorDomainNSString(const OpaqueValue *error,
394-
const Metadata *T,
395-
const WitnessTable *Error);
366+
NSString *getErrorDomainNSString(const OpaqueValue *error,
367+
const Metadata *T,
368+
const WitnessTable *Error);
396369

397370
// internal func _getErrorCode<T : Error>(_ x: UnsafePointer<T>) -> Int
398371
#define getErrorCode \
@@ -406,17 +379,17 @@ NSInteger getErrorCode(const OpaqueValue *error,
406379
#define getErrorUserInfoNSDictionary \
407380
MANGLE_SYM(s29_getErrorUserInfoNSDictionaryyyXlSgSPyxGs0B0RzlF)
408381
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
409-
id getErrorUserInfoNSDictionary(
382+
NSDictionary *getErrorUserInfoNSDictionary(
410383
const OpaqueValue *error,
411384
const Metadata *T,
412385
const WitnessTable *Error);
413386

414387
// @_silgen_name("_swift_stdlib_getErrorDefaultUserInfo")
415388
// internal func _getErrorDefaultUserInfo<T : Error>(_ x: T) -> AnyObject
416389
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
417-
id _swift_stdlib_getErrorDefaultUserInfo(OpaqueValue *error,
418-
const Metadata *T,
419-
const WitnessTable *Error) {
390+
NSDictionary *_swift_stdlib_getErrorDefaultUserInfo(OpaqueValue *error,
391+
const Metadata *T,
392+
const WitnessTable *Error) {
420393
// public func Foundation._getErrorDefaultUserInfo<T: Error>(_ error: T)
421394
// -> AnyObject?
422395
auto foundationGetDefaultUserInfo = getErrorBridgingInfo().GetErrorDefaultUserInfo;
@@ -434,7 +407,7 @@ id _swift_stdlib_getErrorDefaultUserInfo(OpaqueValue *error,
434407
/// at +1.
435408
id
436409
swift::_swift_stdlib_bridgeErrorToNSError(SwiftError *errorObject) {
437-
id ns = reinterpret_cast<id>(errorObject);
410+
auto ns = reinterpret_cast<NSError *>(errorObject);
438411

439412
// If we already have a domain set, then we've already initialized.
440413
// If this is a real NSError, then Cocoa and Core Foundation's initializers
@@ -458,9 +431,9 @@ id _swift_stdlib_getErrorDefaultUserInfo(OpaqueValue *error,
458431
auto type = errorObject->getType();
459432
auto witness = errorObject->getErrorConformance();
460433

461-
id domain = getErrorDomainNSString(value, type, witness);
434+
NSString *domain = getErrorDomainNSString(value, type, witness);
462435
NSInteger code = getErrorCode(value, type, witness);
463-
id userInfo = getErrorUserInfoNSDictionary(value, type, witness);
436+
NSDictionary *userInfo = getErrorUserInfoNSDictionary(value, type, witness);
464437

465438
// Never produce an empty userInfo dictionary.
466439
if (!userInfo)
@@ -507,7 +480,7 @@ id _swift_stdlib_getErrorDefaultUserInfo(OpaqueValue *error,
507480
if (![reinterpret_cast<id>(object) isKindOfClass: NSErrorClass])
508481
return false;
509482

510-
id srcInstance = reinterpret_cast<id>(object);
483+
NSError *srcInstance = reinterpret_cast<NSError *>(object);
511484

512485
// A __SwiftNativeNSError box can always be unwrapped to cast the value back
513486
// out as an Error existential.
@@ -550,7 +523,7 @@ ProtocolDescriptorRef theErrorProtocol(&PROTOCOL_DESCR_SYM(s5Error),
550523
auto *destTypeExistential = dyn_cast<ExistentialTypeMetadata>(destType);
551524
if (destTypeExistential &&
552525
destTypeExistential->getRepresentation() == ExistentialTypeRepresentation::Error) {
553-
auto destBoxAddr = reinterpret_cast<id*>(dest);
526+
auto destBoxAddr = reinterpret_cast<NSError**>(dest);
554527
*destBoxAddr = objc_retain(srcInstance);
555528
return true;
556529
}

0 commit comments

Comments
 (0)