Skip to content

Commit 39389b9

Browse files
committed
[SE-0125] Remove isUniquelyReferenced and the NonObjectiveCBase class
We can express the same using the `isUniquelyReferencedNonObjC` API. - Rename `isUniquelyReferencedNonObjC` to `isKnownUniquelyReferenced`. - Cleanup `ManagedBufferPointer` by removing holdsUniqueOrPinnedReference` and renaming `holdsUniqueReference` to `isUniqueReference`. - No longer promise to return false from `isKnownUniquelyReferenced` for @objc class instances. SR-1962 rdar://21886410
1 parent e051c61 commit 39389b9

12 files changed

+75
-105
lines changed

stdlib/public/SDK/Foundation/Boxing.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ extension _MutableBoxing {
5454
@inline(__always)
5555
mutating func _applyMutation<ReturnType>(_ whatToDo : @noescape(ReferenceType) -> ReturnType) -> ReturnType {
5656
// Only create a new box if we are not uniquely referenced
57-
if !isUniquelyReferencedNonObjC(&_handle) {
57+
if !isKnownUniquelyReferenced(&_handle) {
5858
let ref = _handle._pointer
5959
_handle = _MutableHandle(reference: ref)
6060
}
@@ -187,7 +187,7 @@ extension _MutablePairBoxing {
187187
case .Immutable(_):
188188
break
189189
case .Mutable(_):
190-
unique = isUniquelyReferencedNonObjC(&_wrapped)
190+
unique = isKnownUniquelyReferenced(&_wrapped)
191191
}
192192

193193
switch (wrapper) {

stdlib/public/SDK/Foundation/IndexSet.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -734,7 +734,7 @@ public struct IndexSet : ReferenceConvertible, Equatable, BidirectionalCollectio
734734
case .Default(_):
735735
break
736736
case .Mutable(_):
737-
unique = isUniquelyReferencedNonObjC(&_handle)
737+
unique = isKnownUniquelyReferenced(&_handle)
738738
}
739739

740740
switch _handle._pointer {

stdlib/public/SDK/Foundation/URLRequest.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public struct URLRequest : ReferenceConvertible, Equatable, Hashable {
2626
internal var _handle: _MutableHandle<NSMutableURLRequest>
2727

2828
internal mutating func _applyMutation<ReturnType>(_ whatToDo : @noescape (NSMutableURLRequest) -> ReturnType) -> ReturnType {
29-
if !isUniquelyReferencedNonObjC(&_handle) {
29+
if !isKnownUniquelyReferenced(&_handle) {
3030
let ref = _handle._uncopiedReference()
3131
_handle = _MutableHandle(reference: ref)
3232
}

stdlib/public/core/ContiguousArrayBuffer.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -411,14 +411,14 @@ struct _ContiguousArrayBuffer<Element> : _ArrayBufferProtocol {
411411
/// may need to be considered, such as whether the buffer could be
412412
/// some immutable Cocoa container.
413413
public mutating func isUniquelyReferenced() -> Bool {
414-
return __bufferPointer.holdsUniqueReference()
414+
return __bufferPointer.isUniqueReference()
415415
}
416416

417417
/// Returns `true` iff this buffer's storage is either
418418
/// uniquely-referenced or pinned. NOTE: this does not mean
419419
/// the buffer is mutable; see the comment on isUniquelyReferenced.
420420
public mutating func isUniquelyReferencedOrPinned() -> Bool {
421-
return __bufferPointer.holdsUniqueOrPinnedReference()
421+
return __bufferPointer._isUniqueOrPinnedReference()
422422
}
423423

424424
#if _runtime(_ObjC)

stdlib/public/core/HeapBuffer.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ internal func _swift_bufferAllocate(
4040
/// either in a derived class, or it can be in some manager object
4141
/// that owns the _HeapBuffer.
4242
public // @testable (test/Prototypes/MutableIndexableDict.swift)
43-
class _HeapBufferStorage<Value, Element> : NonObjectiveCBase {
44-
public override init() {}
43+
class _HeapBufferStorage<Value, Element> {
44+
public init() {}
4545

4646
/// The type used to actually manage instances of
4747
/// `_HeapBufferStorage<Value, Element>`.

stdlib/public/core/ManagedBuffer.swift

+49-56
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,6 @@
1212

1313
import SwiftShims
1414

15-
/// A common base class for classes that need to be non-`@objc`,
16-
/// recognizably in the type system.
17-
///
18-
/// - SeeAlso: `isUniquelyReferenced`
19-
public class NonObjectiveCBase {
20-
public init() {}
21-
}
22-
2315
/// A base class of `ManagedBuffer<Header, Element>`, used during
2416
/// instance creation.
2517
///
@@ -28,7 +20,7 @@ public class NonObjectiveCBase {
2820
/// `header` property is as-yet uninitialized, and therefore
2921
/// `ManagedProtoBuffer` does not offer access to the as-yet
3022
/// uninitialized `header` property of `ManagedBuffer`.
31-
public class ManagedProtoBuffer<Header, Element> : NonObjectiveCBase {
23+
public class ManagedProtoBuffer<Header, Element> {
3224
/// The actual number of elements that can be stored in this object.
3325
///
3426
/// This header may be nontrivial to compute; it is usually a good
@@ -299,18 +291,10 @@ public struct ManagedBufferPointer<Header, Element> : Equatable {
299291
/// Returns `true` iff `self` holds the only strong reference to its buffer.
300292
///
301293
/// See `isUniquelyReferenced` for details.
302-
public mutating func holdsUniqueReference() -> Bool {
294+
public mutating func isUniqueReference() -> Bool {
303295
return _isUnique(&_nativeBuffer)
304296
}
305297

306-
/// Returns `true` iff either `self` holds the only strong reference
307-
/// to its buffer or the pinned has been 'pinned'.
308-
///
309-
/// See `isUniquelyReferenced` for details.
310-
public mutating func holdsUniqueOrPinnedReference() -> Bool {
311-
return _isUniqueOrPinned(&_nativeBuffer)
312-
}
313-
314298
//===--- internal/private API -------------------------------------------===//
315299

316300
/// Create with new storage containing space for an initial `Header`
@@ -453,6 +437,10 @@ public struct ManagedBufferPointer<Header, Element> : Equatable {
453437
toAlignment: alignof(Element.self))
454438
}
455439

440+
internal mutating func _isUniqueOrPinnedReference() -> Bool {
441+
return _isUniqueOrPinned(&_nativeBuffer)
442+
}
443+
456444
internal var _nativeBuffer: Builtin.NativeObject
457445
}
458446

@@ -466,19 +454,18 @@ public func == <Header, Element>(
466454
// FIXME: when our calling convention changes to pass self at +0,
467455
// inout should be dropped from the arguments to these functions.
468456

469-
/// Returns `true` iff `object` is a non-`@objc` class instance with
470-
/// a single strong reference.
457+
/// Returns `true` iff `object` is known to be a class instance with a single
458+
/// strong reference.
471459
///
472460
/// * Does *not* modify `object`; the use of `inout` is an
473461
/// implementation artifact.
474-
/// * If `object` is an Objective-C class instance, returns `false`.
475462
/// * Weak references do not affect the result of this function.
476463
///
477464
/// Useful for implementing the copy-on-write optimization for the
478465
/// deep storage of value types:
479466
///
480467
/// mutating func modifyMe(_ arg: X) {
481-
/// if isUniquelyReferencedNonObjC(&myStorage) {
468+
/// if isKnownUniquelyReferenced(&myStorage) {
482469
/// myStorage.modifyInPlace(arg)
483470
/// }
484471
/// else {
@@ -489,16 +476,16 @@ public func == <Header, Element>(
489476
/// This function is safe to use for `mutating` functions in
490477
/// multithreaded code because a false positive would imply that there
491478
/// is already a user-level data race on the value being mutated.
492-
public func isUniquelyReferencedNonObjC<T : AnyObject>(_ object: inout T) -> Bool
479+
public func isKnownUniquelyReferenced<T : AnyObject>(_ object: inout T) -> Bool
493480
{
494481
return _isUnique(&object)
495482
}
496483

497-
internal func isUniquelyReferencedOrPinnedNonObjC<T : AnyObject>(_ object: inout T) -> Bool {
484+
internal func _isKnownUniquelyReferencedOrPinned<T : AnyObject>(_ object: inout T) -> Bool {
498485
return _isUniqueOrPinned(&object)
499486
}
500487

501-
/// Returns `true` iff `object` is a non-`@objc` class instance with a single
488+
/// Returns `true` iff `object` is known to be a class instance with a single
502489
/// strong reference.
503490
///
504491
/// * Does *not* modify `object`; the use of `inout` is an
@@ -509,36 +496,7 @@ internal func isUniquelyReferencedOrPinnedNonObjC<T : AnyObject>(_ object: inout
509496
/// deep storage of value types:
510497
///
511498
/// mutating func modifyMe(_ arg: X) {
512-
/// if isUniquelyReferenced(&myStorage) {
513-
/// myStorage.modifyInPlace(arg)
514-
/// }
515-
/// else {
516-
/// myStorage = myStorage.createModified(arg)
517-
/// }
518-
/// }
519-
///
520-
/// This function is safe to use for `mutating` functions in
521-
/// multithreaded code because a false positive would imply that there
522-
/// is already a user-level data race on the value being mutated.
523-
public func isUniquelyReferenced<T : NonObjectiveCBase>(
524-
_ object: inout T
525-
) -> Bool {
526-
return _isUnique(&object)
527-
}
528-
529-
/// Returns `true` iff `object` is a non-`@objc` class instance with
530-
/// a single strong reference.
531-
///
532-
/// * Does *not* modify `object`; the use of `inout` is an
533-
/// implementation artifact.
534-
/// * If `object` is an Objective-C class instance, returns `false`.
535-
/// * Weak references do not affect the result of this function.
536-
///
537-
/// Useful for implementing the copy-on-write optimization for the
538-
/// deep storage of value types:
539-
///
540-
/// mutating func modifyMe(_ arg: X) {
541-
/// if isUniquelyReferencedNonObjC(&myStorage) {
499+
/// if isKnownUniquelyReferenced(&myStorage) {
542500
/// myStorage.modifyInPlace(arg)
543501
/// }
544502
/// else {
@@ -549,7 +507,7 @@ public func isUniquelyReferenced<T : NonObjectiveCBase>(
549507
/// This function is safe to use for `mutating` functions in
550508
/// multithreaded code because a false positive would imply that there
551509
/// is already a user-level data race on the value being mutated.
552-
public func isUniquelyReferencedNonObjC<T : AnyObject>(
510+
public func isKnownUniquelyReferenced<T : AnyObject>(
553511
_ object: inout T?
554512
) -> Bool {
555513
return _isUnique(&object)
@@ -560,4 +518,39 @@ extension ManagedBufferPointer {
560518
public var allocatedElementCount: Int {
561519
Builtin.unreachable()
562520
}
521+
522+
@available(*, unavailable, renamed: "isUniqueReference")
523+
public mutating func holdsUniqueReference() -> Bool {
524+
Builtin.unreachable()
525+
}
526+
527+
@available(*, unavailable, message: "this API is no longer available")
528+
public mutating func holdsUniqueOrPinnedReference() -> Bool {
529+
Builtin.unreachable()
530+
}
531+
}
532+
533+
@available(*, unavailable, renamed: "isKnownUniquelyReferenced")
534+
public func isUniquelyReferenced<T>(
535+
_ object: inout T
536+
) -> Bool {
537+
Builtin.unreachable()
538+
}
539+
540+
@available(*, unavailable, message: "use isKnownUniquelyReferenced instead")
541+
public class NonObjectiveCBase {}
542+
543+
544+
@available(*, unavailable, renamed: "isKnownUniquelyReferenced")
545+
public func isUniquelyReferencedNonObjC<T : AnyObject>(
546+
_ object: inout T
547+
) -> Bool {
548+
Builtin.unreachable()
549+
}
550+
551+
@available(*, unavailable, renamed: "isKnownUniquelyReferenced")
552+
public func isUniquelyReferencedNonObjC<T : AnyObject>(
553+
_ object: inout T?
554+
) -> Bool {
555+
Builtin.unreachable()
563556
}

stdlib/public/core/SliceBuffer.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -235,11 +235,11 @@ struct _SliceBuffer<Element> : _ArrayBufferProtocol, RandomAccessCollection {
235235
}
236236

237237
mutating func isUniquelyReferenced() -> Bool {
238-
return isUniquelyReferencedNonObjC(&owner)
238+
return isKnownUniquelyReferenced(&owner)
239239
}
240240

241241
mutating func isUniquelyReferencedOrPinned() -> Bool {
242-
return isUniquelyReferencedOrPinnedNonObjC(&owner)
242+
return _isKnownUniquelyReferencedOrPinned(&owner)
243243
}
244244

245245
@_versioned

stdlib/public/core/StringCore.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,7 @@ extension _StringCore : RangeReplaceableCollection {
614614
let appending = bounds.lowerBound == endIndex
615615

616616
let existingStorage = !hasCocoaBuffer && (
617-
appending || isUniquelyReferencedNonObjC(&_owner)
617+
appending || isKnownUniquelyReferenced(&_owner)
618618
) ? _claimCapacity(newCount, minElementWidth: width).1 : nil
619619

620620
if _fastPath(existingStorage != nil) {
@@ -666,7 +666,7 @@ extension _StringCore : RangeReplaceableCollection {
666666

667667
public mutating func reserveCapacity(_ n: Int) {
668668
if _fastPath(!hasCocoaBuffer) {
669-
if _fastPath(isUniquelyReferencedNonObjC(&_owner)) {
669+
if _fastPath(isKnownUniquelyReferenced(&_owner)) {
670670

671671
let bounds: Range<UnsafePointer<_RawByte>>
672672
= UnsafePointer(_pointer(toElementAt:0))..<UnsafePointer(_pointer(toElementAt:count))

test/1_stdlib/ManagedBuffer.swift

+9-28
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,6 @@ import StdlibUnittest
1919
import Foundation
2020
#endif
2121

22-
// Check that `NonObjectiveCBase` can be subclassed and the subclass can be
23-
// created.
24-
public class SubclassOfNonObjectiveCBase : NonObjectiveCBase {
25-
public override init() {}
26-
}
27-
func createSubclassOfNonObjectiveCBase() {
28-
_ = SubclassOfNonObjectiveCBase()
29-
}
30-
3122
// Check that the generic parameters are called 'Header' and 'Element'.
3223
protocol TestProtocol1 {}
3324

@@ -199,11 +190,11 @@ tests.test("ManagedBufferPointer") {
199190
CountAndCapacity(
200191
count: LifetimeTracked(0), capacity: getRealCapacity(buffer))
201192
}
202-
expectTrue(mgr.holdsUniqueReference())
193+
expectTrue(mgr.isUniqueReference())
203194

204195
let buf = mgr.buffer as? TestManagedBuffer<LifetimeTracked>
205196
expectTrue(buf != nil)
206-
expectFalse(mgr.holdsUniqueReference())
197+
expectFalse(mgr.isUniqueReference())
207198

208199
let s = buf!
209200
expectEqual(0, s.count)
@@ -232,38 +223,28 @@ tests.test("ManagedBufferPointer") {
232223
minimumCapacity: 0
233224
) { _, _ in CountAndCapacity(count: LifetimeTracked(0), capacity: 99) }
234225

235-
expectTrue(mgr.holdsUniqueReference())
226+
expectTrue(mgr.isUniqueReference())
236227
expectEqual(mgr.header.count.value, 0)
237228
expectEqual(mgr.header.capacity, 99)
238229

239230
let s2 = mgr.buffer as! MyBuffer<LifetimeTracked>
240-
expectFalse(mgr.holdsUniqueReference())
231+
expectFalse(mgr.isUniqueReference())
241232

242233
let val = mgr.withUnsafeMutablePointerToHeader { $0 }.pointee
243234
expectEqual(val.count.value, 0)
244235
expectEqual(val.capacity, 99)
245236
}
246237
}
247238

248-
tests.test("isUniquelyReferenced") {
249-
var s = TestManagedBuffer<LifetimeTracked>.create(0)
250-
expectTrue(isUniquelyReferenced(&s))
251-
var s2 = s
252-
expectFalse(isUniquelyReferenced(&s))
253-
expectFalse(isUniquelyReferenced(&s2))
254-
_fixLifetime(s)
255-
_fixLifetime(s2)
256-
}
257-
258-
tests.test("isUniquelyReferencedNonObjC") {
239+
tests.test("isKnownUniquelyReferenced") {
259240
var s = TestManagedBuffer<LifetimeTracked>.create(0)
260-
expectTrue(isUniquelyReferencedNonObjC(&s))
241+
expectTrue(isKnownUniquelyReferenced(&s))
261242
var s2 = s
262-
expectFalse(isUniquelyReferencedNonObjC(&s))
263-
expectFalse(isUniquelyReferencedNonObjC(&s2))
243+
expectFalse(isKnownUniquelyReferenced(&s))
244+
expectFalse(isKnownUniquelyReferenced(&s2))
264245
#if _runtime(_ObjC)
265246
var s3 = NSArray()
266-
expectFalse(isUniquelyReferencedNonObjC(&s3))
247+
expectFalse(isKnownUniquelyReferenced(&s3))
267248
#endif
268249
_fixLifetime(s)
269250
_fixLifetime(s2)

test/1_stdlib/Runtime.swift.gyb

-3
Original file line numberDiff line numberDiff line change
@@ -349,9 +349,6 @@ Runtime.test("typeByName") {
349349
expectTrue(_typeByName("a.SomeSubclass") == SomeSubclass.self)
350350
// name lookup will be via protocol conformance table
351351
expectTrue(_typeByName("a.SomeConformingClass") == SomeConformingClass.self)
352-
// FIXME: NonObjectiveCBase is slated to die, but I can't think of another
353-
// nongeneric public class in the stdlib...
354-
expectTrue(_typeByName("Swift.NonObjectiveCBase") == NonObjectiveCBase.self)
355352
}
356353

357354
Runtime.test("demangleName") {

0 commit comments

Comments
 (0)