Skip to content

Commit f2da0ce

Browse files
committed
Adopt @unsafe throughout the standard library
Annotate all of the `Unsafe*` types and `unsafe` functions in the standard library (including concurrency, synchronization, etc.) as `@unsafe`. Add a few tests to ensure that we detect uses of these types in clients that have disabled unsafe code.
1 parent 0612986 commit f2da0ce

18 files changed

+48
-1
lines changed

stdlib/cmake/modules/SwiftSource.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,7 @@ function(_compile_swift_files
627627

628628
list(APPEND swift_flags "-enable-experimental-feature" "NoncopyableGenerics2")
629629
list(APPEND swift_flags "-enable-experimental-feature" "SuppressedAssociatedTypes")
630+
list(APPEND swift_flags "-enable-experimental-feature" "AllowUnsafeAttribute")
630631

631632
if(SWIFT_ENABLE_EXPERIMENTAL_NONESCAPABLE_TYPES)
632633
list(APPEND swift_flags "-enable-experimental-feature" "NonescapableTypes")

stdlib/public/Concurrency/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ endif()
6464
list(APPEND SWIFT_RUNTIME_CONCURRENCY_SWIFT_FLAGS
6565
"-enable-experimental-feature"
6666
"IsolatedAny"
67-
)
67+
)
6868

6969
list(APPEND SWIFT_RUNTIME_CONCURRENCY_C_FLAGS
7070
"-D__STDC_WANT_LIB_EXT1__=1")

stdlib/public/Concurrency/PartialAsyncTask.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,7 @@ extension JobPriority: Comparable {
482482
/// without making other changes.
483483
@available(SwiftStdlib 5.1, *)
484484
@frozen
485+
@unsafe
485486
public struct UnsafeContinuation<T, E: Error>: Sendable {
486487
@usableFromInline internal var context: Builtin.RawUnsafeContinuation
487488

@@ -685,6 +686,7 @@ internal func _resumeUnsafeThrowingContinuationWithError<T>(
685686
/// - SeeAlso: `withCheckedThrowingContinuation(function:_:)`
686687
@available(SwiftStdlib 5.1, *)
687688
@_alwaysEmitIntoClient
689+
@unsafe
688690
public func withUnsafeContinuation<T>(
689691
isolation: isolated (any Actor)? = #isolation,
690692
_ fn: (UnsafeContinuation<T, Never>) -> Void
@@ -721,6 +723,7 @@ public func withUnsafeContinuation<T>(
721723
/// - SeeAlso: `withCheckedThrowingContinuation(function:_:)`
722724
@available(SwiftStdlib 5.1, *)
723725
@_alwaysEmitIntoClient
726+
@unsafe
724727
public func withUnsafeThrowingContinuation<T>(
725728
isolation: isolated (any Actor)? = #isolation,
726729
_ fn: (UnsafeContinuation<T, Error>) -> Void

stdlib/public/Concurrency/Task.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,6 +1037,7 @@ public func withUnsafeCurrentTask<T>(body: (UnsafeCurrentTask?) async throws ->
10371037
/// [concurrency]: https://docs.swift.org/swift-book/LanguageGuide/Concurrency.html
10381038
/// [tspl]: https://docs.swift.org/swift-book/
10391039
@available(SwiftStdlib 5.1, *)
1040+
@unsafe
10401041
public struct UnsafeCurrentTask {
10411042
internal let _task: Builtin.NativeObject
10421043

stdlib/public/Synchronization/Mutex/Mutex.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,20 +175,23 @@ extension _MutexHandle {
175175
@available(SwiftStdlib 6.0, *)
176176
@_alwaysEmitIntoClient
177177
@_transparent
178+
@unsafe
178179
public borrowing func unsafeLock() {
179180
_lock()
180181
}
181182

182183
@available(SwiftStdlib 6.0, *)
183184
@_alwaysEmitIntoClient
184185
@_transparent
186+
@unsafe
185187
public borrowing func unsafeTryLock() -> Bool {
186188
_tryLock()
187189
}
188190

189191
@available(SwiftStdlib 6.0, *)
190192
@_alwaysEmitIntoClient
191193
@_transparent
194+
@unsafe
192195
public borrowing func unsafeUnlock() {
193196
_unlock()
194197
}

stdlib/public/Volatile/Volatile.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public struct VolatileMappedRegister<Pointee> {
2929
let _rawPointer: Builtin.RawPointer
3030

3131
@_transparent
32+
@unsafe
3233
public init(unsafeBitPattern: UInt) {
3334
self._rawPointer = Builtin.inttoptr_Word(unsafeBitPattern._builtinWordValue)
3435
}

stdlib/public/core/Builtin.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ func _canBeClass<T>(_: T.Type) -> Int8 {
9191
/// Returns: A new instance of type `U`, cast from `x`.
9292
@inlinable // unsafe-performance
9393
@_transparent
94+
@unsafe
9495
public func unsafeBitCast<T, U>(_ x: T, to type: U.Type) -> U {
9596
_precondition(MemoryLayout<T>.size == MemoryLayout<U>.size,
9697
"Can't unsafeBitCast between types of different sizes")
@@ -242,6 +243,7 @@ internal func _isClassOrObjCExistential<T>(_ x: T.Type) -> Bool {
242243
/// be either a class or a class protocol. Either T, U, or both may be
243244
/// optional references.
244245
@_transparent
246+
@unsafe
245247
public func _unsafeReferenceCast<T, U>(_ x: T, to: U.Type) -> U {
246248
return Builtin.castReference(x)
247249
}
@@ -265,12 +267,14 @@ public func _unsafeReferenceCast<T, U>(_ x: T, to: U.Type) -> U {
265267
/// - type: The type `T` to which `x` is cast.
266268
/// - Returns: The instance `x`, cast to type `T`.
267269
@_transparent
270+
@unsafe
268271
public func unsafeDowncast<T: AnyObject>(_ x: AnyObject, to type: T.Type) -> T {
269272
_debugPrecondition(x is T, "invalid unsafeDowncast")
270273
return Builtin.castReference(x)
271274
}
272275

273276
@_transparent
277+
@unsafe
274278
public func _unsafeUncheckedDowncast<T: AnyObject>(_ x: AnyObject, to type: T.Type) -> T {
275279
_internalInvariant(x is T, "invalid unsafeDowncast")
276280
return Builtin.castReference(x)
@@ -331,6 +335,7 @@ public func _onFastPath() {
331335
// Optimizer hint that the condition is true. The condition is unchecked.
332336
// The builtin acts as an opaque instruction with side-effects.
333337
@usableFromInline @_transparent
338+
@unsafe
334339
func _uncheckedUnsafeAssume(_ condition: Bool) {
335340
_ = Builtin.assume_Int1(condition._value)
336341
}

stdlib/public/core/CTypes.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ public typealias CBool = Bool
150150
/// Opaque pointers are used to represent C pointers to types that
151151
/// cannot be represented in Swift, such as incomplete struct types.
152152
@frozen
153+
@unsafe
153154
public struct OpaquePointer {
154155
@usableFromInline
155156
internal var _rawValue: Builtin.RawPointer

stdlib/public/core/Misc.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ public func _getTypeByMangledNameInContext(
155155
/// Prevents performance diagnostics in the passed closure.
156156
@_alwaysEmitIntoClient
157157
@_semantics("no_performance_analysis")
158+
@unsafe
158159
public func _unsafePerformance<T>(_ c: () -> T) -> T {
159160
return c()
160161
}

stdlib/public/core/Optional.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,7 @@ extension Optional {
338338
/// will never be equal to `nil` and only after you've tried using the
339339
/// postfix `!` operator.
340340
@inlinable
341+
@unsafe
341342
public var unsafelyUnwrapped: Wrapped {
342343
@inline(__always)
343344
get {

0 commit comments

Comments
 (0)