Skip to content

Commit f24e18c

Browse files
authored
Merge pull request #71688 from lorentey/noncopyable-primitives
[stdlib] Start adopting noncopyable generics in the stdlib
2 parents 6cd49ef + 74bd1e3 commit f24e18c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+2123
-709
lines changed

stdlib/public/Cxx/UnsafeCxxIterators.swift

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -18,12 +18,13 @@
1818
///
1919
/// - SeeAlso: https://en.cppreference.com/w/cpp/named_req/InputIterator
2020
public protocol UnsafeCxxInputIterator: Equatable {
21-
associatedtype Pointee
21+
associatedtype Pointee: ~Copyable
2222

2323
/// Returns the unwrapped result of C++ `operator*()`.
2424
///
2525
/// Generally, Swift creates this property automatically for C++ types that
2626
/// define `operator*()`.
27+
@_borrowed
2728
var pointee: Pointee { get }
2829

2930
/// Returns an iterator pointing to the next item in the sequence.
@@ -33,19 +34,23 @@ public protocol UnsafeCxxInputIterator: Equatable {
3334
func successor() -> Self
3435
}
3536

36-
extension UnsafePointer: UnsafeCxxInputIterator {}
37+
extension UnsafePointer: UnsafeCxxInputIterator
38+
where Pointee: ~Copyable {}
3739

38-
extension UnsafeMutablePointer: UnsafeCxxInputIterator {}
40+
extension UnsafeMutablePointer: UnsafeCxxInputIterator
41+
where Pointee: ~Copyable {}
3942

4043
extension Optional: UnsafeCxxInputIterator where Wrapped: UnsafeCxxInputIterator {
4144
public typealias Pointee = Wrapped.Pointee
4245

4346
@inlinable
4447
public var pointee: Pointee {
45-
if let value = self {
46-
return value.pointee
48+
_read {
49+
guard let value = self else {
50+
fatalError("Could not dereference nullptr")
51+
}
52+
yield value.pointee
4753
}
48-
fatalError("Could not dereference nullptr")
4954
}
5055

5156
@inlinable
@@ -58,10 +63,12 @@ extension Optional: UnsafeCxxInputIterator where Wrapped: UnsafeCxxInputIterator
5863
}
5964

6065
public protocol UnsafeCxxMutableInputIterator: UnsafeCxxInputIterator {
66+
@_borrowed
6167
override var pointee: Pointee { get set }
6268
}
6369

64-
extension UnsafeMutablePointer: UnsafeCxxMutableInputIterator {}
70+
extension UnsafeMutablePointer: UnsafeCxxMutableInputIterator
71+
where Pointee: ~Copyable {}
6572

6673
/// Bridged C++ iterator that allows computing the distance between two of its
6774
/// instances, and advancing an instance by a given number of elements.
@@ -77,10 +84,14 @@ public protocol UnsafeCxxRandomAccessIterator: UnsafeCxxInputIterator {
7784
static func +=(lhs: inout Self, rhs: Distance)
7885
}
7986

80-
extension UnsafePointer: UnsafeCxxRandomAccessIterator {}
87+
extension UnsafePointer: UnsafeCxxRandomAccessIterator
88+
where Pointee: ~Copyable {}
8189

82-
extension UnsafeMutablePointer: UnsafeCxxRandomAccessIterator {}
90+
extension UnsafeMutablePointer: UnsafeCxxRandomAccessIterator
91+
where Pointee: ~Copyable {}
8392

84-
public protocol UnsafeCxxMutableRandomAccessIterator: UnsafeCxxRandomAccessIterator, UnsafeCxxMutableInputIterator {}
93+
public protocol UnsafeCxxMutableRandomAccessIterator:
94+
UnsafeCxxRandomAccessIterator, UnsafeCxxMutableInputIterator {}
8595

86-
extension UnsafeMutablePointer: UnsafeCxxMutableRandomAccessIterator {}
96+
extension UnsafeMutablePointer: UnsafeCxxMutableRandomAccessIterator
97+
where Pointee: ~Copyable {}

stdlib/public/Synchronization/AtomicPointers.swift

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2023 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2023 - 2024 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -15,7 +15,7 @@
1515
//===----------------------------------------------------------------------===//
1616

1717
@available(SwiftStdlib 6.0, *)
18-
extension UnsafePointer: AtomicRepresentable {
18+
extension UnsafePointer: AtomicRepresentable where Pointee: ~Copyable {
1919
/// The storage representation type that `Self` encodes to and decodes from
2020
/// which is a suitable type when used in atomic operations.
2121
@available(SwiftStdlib 6.0, *)
@@ -65,7 +65,7 @@ extension UnsafePointer: AtomicRepresentable {
6565
}
6666

6767
@available(SwiftStdlib 6.0, *)
68-
extension UnsafePointer: AtomicOptionalRepresentable {
68+
extension UnsafePointer: AtomicOptionalRepresentable where Pointee: ~Copyable {
6969
/// The storage representation type that encodes to and decodes from
7070
/// `Optional<Self>` which is a suitable type when used in atomic operations
7171
/// on `Optional`.
@@ -121,7 +121,7 @@ extension UnsafePointer: AtomicOptionalRepresentable {
121121
//===----------------------------------------------------------------------===//
122122

123123
@available(SwiftStdlib 6.0, *)
124-
extension UnsafeMutablePointer: AtomicRepresentable {
124+
extension UnsafeMutablePointer: AtomicRepresentable where Pointee: ~Copyable {
125125
/// The storage representation type that `Self` encodes to and decodes from
126126
/// which is a suitable type when used in atomic operations.
127127
@available(SwiftStdlib 6.0, *)
@@ -171,7 +171,8 @@ extension UnsafeMutablePointer: AtomicRepresentable {
171171
}
172172

173173
@available(SwiftStdlib 6.0, *)
174-
extension UnsafeMutablePointer: AtomicOptionalRepresentable {
174+
extension UnsafeMutablePointer: AtomicOptionalRepresentable
175+
where Pointee: ~Copyable {
175176
/// The storage representation type that encodes to and decodes from
176177
/// `Optional<Self>` which is a suitable type when used in atomic operations
177178
/// on `Optional`.
@@ -773,7 +774,7 @@ extension ObjectIdentifier: AtomicOptionalRepresentable {
773774
#if (_pointerBitWidth(_32) && _hasAtomicBitWidth(_64)) || (_pointerBitWidth(_64) && _hasAtomicBitWidth(_128))
774775

775776
@available(SwiftStdlib 6.0, *)
776-
extension UnsafeBufferPointer: AtomicRepresentable {
777+
extension UnsafeBufferPointer: AtomicRepresentable where Element: ~Copyable {
777778
/// The storage representation type that `Self` encodes to and decodes from
778779
/// which is a suitable type when used in atomic operations.
779780
@available(SwiftStdlib 6.0, *)
@@ -839,7 +840,9 @@ extension UnsafeBufferPointer: AtomicRepresentable {
839840
#if (_pointerBitWidth(_32) && _hasAtomicBitWidth(_64)) || (_pointerBitWidth(_64) && _hasAtomicBitWidth(_128))
840841

841842
@available(SwiftStdlib 6.0, *)
842-
extension UnsafeMutableBufferPointer: AtomicRepresentable {
843+
extension UnsafeMutableBufferPointer: AtomicRepresentable
844+
where Element: ~Copyable
845+
{
843846
/// The storage representation type that `Self` encodes to and decodes from
844847
/// which is a suitable type when used in atomic operations.
845848
@available(SwiftStdlib 6.0, *)

stdlib/public/core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ list(APPEND swift_stdlib_compile_flags "-enable-experimental-feature" "Macros")
314314
list(APPEND swift_stdlib_compile_flags "-enable-experimental-feature" "FreestandingMacros")
315315
list(APPEND swift_stdlib_compile_flags "-enable-experimental-feature" "Extern")
316316
list(APPEND swift_stdlib_compile_flags "-enable-experimental-feature" "BitwiseCopyable")
317+
list(APPEND swift_stdlib_compile_flags "-enable-experimental-feature" "BorrowingSwitch")
317318

318319
if("${SWIFT_NATIVE_SWIFT_TOOLS_PATH}" STREQUAL "")
319320
set(swift_bin_dir "${CMAKE_BINARY_DIR}/bin")

stdlib/public/core/CTypes.swift

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -150,38 +150,58 @@ public struct OpaquePointer {
150150
internal init(_ v: Builtin.RawPointer) {
151151
self._rawValue = v
152152
}
153+
}
154+
155+
@available(*, unavailable)
156+
extension OpaquePointer: Sendable {}
153157

154-
/// Creates an `OpaquePointer` from a given address in memory.
158+
extension OpaquePointer {
159+
/// Creates a new `OpaquePointer` from the given address, specified as a bit
160+
/// pattern.
161+
///
162+
/// - Parameter bitPattern: A bit pattern to use for the address of the new
163+
/// pointer. If `bitPattern` is zero, the result is `nil`.
155164
@_transparent
156165
public init?(bitPattern: Int) {
157166
if bitPattern == 0 { return nil }
158167
self._rawValue = Builtin.inttoptr_Word(bitPattern._builtinWordValue)
159168
}
160169

161-
/// Creates an `OpaquePointer` from a given address in memory.
170+
/// Creates a new `OpaquePointer` from the given address, specified as a bit
171+
/// pattern.
172+
///
173+
/// - Parameter bitPattern: A bit pattern to use for the address of the new
174+
/// pointer. If `bitPattern` is zero, the result is `nil`.
162175
@_transparent
163176
public init?(bitPattern: UInt) {
164177
if bitPattern == 0 { return nil }
165178
self._rawValue = Builtin.inttoptr_Word(bitPattern._builtinWordValue)
166179
}
180+
}
167181

182+
extension OpaquePointer {
168183
/// Converts a typed `UnsafePointer` to an opaque C pointer.
169184
@_transparent
170-
public init<T>(@_nonEphemeral _ from: UnsafePointer<T>) {
185+
@_preInverseGenerics
186+
public init<T: ~Copyable>(@_nonEphemeral _ from: UnsafePointer<T>) {
171187
self._rawValue = from._rawValue
172188
}
173189

174190
/// Converts a typed `UnsafePointer` to an opaque C pointer.
175191
///
176192
/// The result is `nil` if `from` is `nil`.
177193
@_transparent
178-
public init?<T>(@_nonEphemeral _ from: UnsafePointer<T>?) {
194+
@_preInverseGenerics
195+
public init?<T: ~Copyable>(@_nonEphemeral _ from: UnsafePointer<T>?) {
179196
guard let unwrapped = from else { return nil }
180197
self.init(unwrapped)
181198
}
199+
}
182200

201+
extension OpaquePointer {
183202
/// Converts a typed `UnsafeMutablePointer` to an opaque C pointer.
184203
@_transparent
204+
@_preInverseGenerics
185205
public init<T>(@_nonEphemeral _ from: UnsafeMutablePointer<T>) {
186206
self._rawValue = from._rawValue
187207
}
@@ -190,6 +210,7 @@ public struct OpaquePointer {
190210
///
191211
/// The result is `nil` if `from` is `nil`.
192212
@_transparent
213+
@_preInverseGenerics
193214
public init?<T>(@_nonEphemeral _ from: UnsafeMutablePointer<T>?) {
194215
guard let unwrapped = from else { return nil }
195216
self.init(unwrapped)
@@ -215,9 +236,6 @@ extension OpaquePointer: Hashable {
215236
}
216237
}
217238

218-
@available(*, unavailable)
219-
extension OpaquePointer : Sendable { }
220-
221239
@_unavailableInEmbedded
222240
extension OpaquePointer: CustomDebugStringConvertible {
223241
/// A textual representation of the pointer, suitable for debugging.

stdlib/public/core/CompilerProtocols.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -266,7 +266,7 @@ public protocol CaseIterable {
266266
/// `Optional` type conforms to `ExpressibleByNilLiteral`.
267267
/// `ExpressibleByNilLiteral` conformance for types that use `nil` for other
268268
/// purposes is discouraged.
269-
public protocol ExpressibleByNilLiteral {
269+
public protocol ExpressibleByNilLiteral: ~Copyable {
270270
/// Creates an instance initialized with `nil`.
271271
init(nilLiteral: ())
272272
}

0 commit comments

Comments
 (0)