Skip to content

[5.10][SE-0331][stdlib] Mark unsafe pointer conformances to Sendable as explicitly unavailable #69136

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/swift/AST/KnownStdlibTypes.def
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ KNOWN_STDLIB_TYPE_DECL(UnsafeRawPointer, NominalTypeDecl, 0)
KNOWN_STDLIB_TYPE_DECL(UnsafeMutablePointer, NominalTypeDecl, 1)
KNOWN_STDLIB_TYPE_DECL(UnsafePointer, NominalTypeDecl, 1)
KNOWN_STDLIB_TYPE_DECL(OpaquePointer, NominalTypeDecl, 0)
KNOWN_STDLIB_TYPE_DECL(CVaListPointer, NominalTypeDecl, 0)
KNOWN_STDLIB_TYPE_DECL(AutoreleasingUnsafeMutablePointer, NominalTypeDecl, 1)

KNOWN_STDLIB_TYPE_DECL(UnsafeBufferPointer, NominalTypeDecl, 1)
Expand Down
3 changes: 2 additions & 1 deletion stdlib/public/core/BridgeObjectiveC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,8 @@ extension UnsafeRawPointer {
}
}

extension AutoreleasingUnsafeMutablePointer { }
@available(*, unavailable)
extension AutoreleasingUnsafeMutablePointer: Sendable { }

internal struct _CocoaFastEnumerationStackBuf {
// Clang uses 16 pointers. So do we.
Expand Down
6 changes: 6 additions & 0 deletions stdlib/public/core/CTypes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,9 @@ extension OpaquePointer: Hashable {
}
}

@available(*, unavailable)
extension OpaquePointer : Sendable { }

extension OpaquePointer: CustomDebugStringConvertible {
/// A textual representation of the pointer, suitable for debugging.
public var debugDescription: String {
Expand Down Expand Up @@ -297,6 +300,9 @@ extension CVaListPointer: CustomDebugStringConvertible {

#endif

@available(*, unavailable)
extension CVaListPointer: Sendable { }

/// Copy `size` bytes of memory from `src` into `dest`.
///
/// The memory regions `src..<src + size` and
Expand Down
6 changes: 6 additions & 0 deletions stdlib/public/core/UnsafeBufferPointer.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -1197,8 +1197,14 @@ extension Unsafe${Mutable}BufferPointer: CustomDebugStringConvertible {
+ "(start: \(_position.map(String.init(describing:)) ?? "nil"), count: \(count))"
}
}

@available(*, unavailable)
extension Unsafe${Mutable}BufferPointer: Sendable { }
%end

@available(*, unavailable)
extension UnsafeBufferPointer.Iterator: Sendable { }


// ${'Local Variables'}:
// eval: (read-only-mode 1)
Expand Down
5 changes: 5 additions & 0 deletions stdlib/public/core/UnsafePointer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1172,3 +1172,8 @@ public struct UnsafeMutablePointer<Pointee>: _Pointer {
)._unsafelyUnwrappedUnchecked
}
}

@available(*, unavailable)
extension UnsafePointer: Sendable { }
@available(*, unavailable)
extension UnsafeMutablePointer: Sendable { }
8 changes: 8 additions & 0 deletions stdlib/public/core/UnsafeRawBufferPointer.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -1303,6 +1303,14 @@ public func _withUnprotectedUnsafeBytes<T, Result>(
return try body(buffer)
}

@available(*, unavailable)
extension UnsafeRawBufferPointer: Sendable { }
@available(*, unavailable)
extension UnsafeRawBufferPointer.Iterator: Sendable { }
@available(*, unavailable)
extension UnsafeMutableRawBufferPointer: Sendable { }


// ${'Local Variables'}:
// eval: (read-only-mode 1)
// End:
5 changes: 5 additions & 0 deletions stdlib/public/core/UnsafeRawPointer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1486,3 +1486,8 @@ extension OpaquePointer {
self._rawValue = unwrapped._rawValue
}
}

@available(*, unavailable)
extension UnsafeRawPointer: Sendable { }
@available(*, unavailable)
extension UnsafeMutableRawPointer: Sendable { }
33 changes: 33 additions & 0 deletions test/Concurrency/sendable_checking.swift
Original file line number Diff line number Diff line change
Expand Up @@ -316,3 +316,36 @@ func testLocalCaptures() {
// expected-complete-and-sns-warning@-1 {{capture of 'ns' with non-sendable type 'NonSendable' in a `@Sendable` local function}}
}
}

func testPointersAreNotSendable() {
func testSendable<T: Sendable>(_: T) {}

func testUnsafePointer(ptr: UnsafePointer<Int>,
mutablePtr: UnsafeMutablePointer<String>) {
testSendable(ptr) // expected-warning {{conformance of 'UnsafePointer<Pointee>' to 'Sendable' is unavailable}}
testSendable(mutablePtr) // expected-warning {{conformance of 'UnsafeMutablePointer<Pointee>' to 'Sendable' is unavailable}}
}

func testRawPointer(ptr: UnsafeRawPointer,
mutablePtr: UnsafeMutableRawPointer) {
testSendable(ptr) // expected-warning {{conformance of 'UnsafeRawPointer' to 'Sendable' is unavailable}}
testSendable(mutablePtr) // expected-warning {{conformance of 'UnsafeMutableRawPointer' to 'Sendable' is unavailable}}
}

func testOpaqueAndCPointers(opaquePtr: OpaquePointer, cPtr: CVaListPointer, autoReleasePtr: AutoreleasingUnsafeMutablePointer<Int>) {
testSendable(opaquePtr) // expected-warning {{conformance of 'OpaquePointer' to 'Sendable' is unavailable}}
testSendable(cPtr) // expected-warning {{conformance of 'CVaListPointer' to 'Sendable' is unavailable}}
testSendable(autoReleasePtr) // expected-warning {{conformance of 'AutoreleasingUnsafeMutablePointer<Pointee>' to 'Sendable' is unavailable}}
}

func testBufferPointers(buffer: UnsafeBufferPointer<Int>, mutableBuffer: UnsafeMutableBufferPointer<Int>,
rawBuffer: UnsafeRawBufferPointer, rawMutableBuffer: UnsafeMutableRawBufferPointer) {
testSendable(buffer) // expected-warning {{conformance of 'UnsafeBufferPointer<Element>' to 'Sendable' is unavailable}}
testSendable(mutableBuffer) // expected-warning {{conformance of 'UnsafeMutableBufferPointer<Element>' to 'Sendable' is unavailable}}
testSendable(buffer.makeIterator()) // expected-warning {{conformance of 'UnsafeBufferPointer<Element>.Iterator' to 'Sendable' is unavailable}}
testSendable(rawBuffer) // expected-warning {{conformance of 'UnsafeRawBufferPointer' to 'Sendable' is unavailable}}
testSendable(rawBuffer.makeIterator()) // expected-warning {{conformance of 'UnsafeRawBufferPointer.Iterator' to 'Sendable' is unavailable}}
testSendable(rawMutableBuffer) // expected-warning {{conformance of 'UnsafeMutableRawBufferPointer' to 'Sendable' is unavailable}}
testSendable(rawMutableBuffer.makeIterator()) // expected-warning {{conformance of 'UnsafeRawBufferPointer.Iterator' to 'Sendable' is unavailable}}
}
}