Skip to content

[6.0][stdlib] Round out ~Copyable generalizations in stdlib primitives #73079

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
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
4 changes: 2 additions & 2 deletions stdlib/public/core/CTypes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ extension OpaquePointer {
/// Converts a typed `UnsafeMutablePointer` to an opaque C pointer.
@_transparent
@_preInverseGenerics
public init<T>(@_nonEphemeral _ from: UnsafeMutablePointer<T>) {
public init<T: ~Copyable>(@_nonEphemeral _ from: UnsafeMutablePointer<T>) {
self._rawValue = from._rawValue
}

Expand All @@ -211,7 +211,7 @@ extension OpaquePointer {
/// The result is `nil` if `from` is `nil`.
@_transparent
@_preInverseGenerics
public init?<T>(@_nonEphemeral _ from: UnsafeMutablePointer<T>?) {
public init?<T: ~Copyable>(@_nonEphemeral _ from: UnsafeMutablePointer<T>?) {
guard let unwrapped = from else { return nil }
self.init(unwrapped)
}
Expand Down
31 changes: 24 additions & 7 deletions stdlib/public/core/LifetimeManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,20 @@
/// extended. If `body` has a return value, that value is also used as the
/// return value for the `withExtendedLifetime(_:_:)` method.
/// - Returns: The return value, if any, of the `body` closure parameter.
@inlinable
@_preInverseGenerics
@_alwaysEmitIntoClient
public func withExtendedLifetime<T: ~Copyable, Result: ~Copyable>(
_ x: borrowing T,
_ body: () throws -> Result
_ body: () throws -> Result // FIXME: Typed throws rdar://126576356
) rethrows -> Result {
defer { _fixLifetime(x) }
return try body()
}

@_spi(SwiftStdlibLegacyABI) @available(swift, obsoleted: 1)
@usableFromInline
internal func withExtendedLifetime<T, Result>(
_ x: T,
_ body: () throws -> Result // FIXME: Typed throws rdar://126576356
) rethrows -> Result {
defer { _fixLifetime(x) }
return try body()
Expand All @@ -38,10 +47,18 @@ public func withExtendedLifetime<T: ~Copyable, Result: ~Copyable>(
/// extended. If `body` has a return value, that value is also used as the
/// return value for the `withExtendedLifetime(_:_:)` method.
/// - Returns: The return value, if any, of the `body` closure parameter.
@inlinable
public func withExtendedLifetime<T, Result>(
// FIXME(NCG): This should have T, Result as ~Copyable, but then the closure would need to take a borrow
_ x: T, _ body: (T) throws -> Result
@_alwaysEmitIntoClient
public func withExtendedLifetime<T, Result: ~Copyable>(
_ x: T, _ body: (T) throws -> Result // FIXME: Typed throws rdar://126576356
) rethrows -> Result {
defer { _fixLifetime(x) }
return try body(x)
}

@_spi(SwiftStdlibLegacyABI) @available(swift, obsoleted: 1)
@usableFromInline
internal func withExtendedLifetime<T, Result>(
_ x: T, _ body: (T) throws -> Result // FIXME: Typed throws rdar://126576356
) rethrows -> Result {
defer { _fixLifetime(x) }
return try body(x)
Expand Down
145 changes: 105 additions & 40 deletions stdlib/public/core/ManagedBuffer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,8 @@ extension ManagedBuffer where Element: ~Copyable {
@inlinable
public final class func create(
minimumCapacity: Int,
makingHeaderWith factory: (
ManagedBuffer<Header, Element>) throws -> Header
makingHeaderWith factory: (ManagedBuffer<Header, Element>) throws -> Header
) rethrows -> ManagedBuffer<Header, Element> {

let p = Builtin.allocWithTailElems_1(
self,
minimumCapacity._builtinWordValue, Element.self)
Expand Down Expand Up @@ -124,42 +122,78 @@ extension ManagedBuffer where Element: ~Copyable {
internal final var headerAddress: UnsafeMutablePointer<Header> {
return UnsafeMutablePointer<Header>(Builtin.addressof(&header))
}
}

extension ManagedBuffer where Element: ~Copyable {
/// Call `body` with an `UnsafeMutablePointer` to the stored
/// `Header`.
///
/// - Note: This pointer is valid only for the duration of the
/// call to `body`.
@_preInverseGenerics
@inlinable
public final func withUnsafeMutablePointerToHeader<R>(
_ body: (UnsafeMutablePointer<Header>) throws -> R
) rethrows -> R {
return try withUnsafeMutablePointers { (v, _) in return try body(v) }
@_alwaysEmitIntoClient
@inline(__always)
public final func withUnsafeMutablePointerToHeader<E: Error, R: ~Copyable>(
_ body: (UnsafeMutablePointer<Header>) throws(E) -> R
) throws(E) -> R {
try withUnsafeMutablePointers { (v, _) throws(E) in try body(v) }
}

/// Call `body` with an `UnsafeMutablePointer` to the `Element`
/// storage.
///
/// - Note: This pointer is valid only for the duration of the
/// call to `body`.
@_preInverseGenerics
@inlinable
public final func withUnsafeMutablePointerToElements<R>(
_ body: (UnsafeMutablePointer<Element>) throws -> R
) rethrows -> R {
return try withUnsafeMutablePointers { return try body($1) }
@_alwaysEmitIntoClient
@inline(__always)
public final func withUnsafeMutablePointerToElements<E: Error, R: ~Copyable>(
_ body: (UnsafeMutablePointer<Element>) throws(E) -> R
) throws(E) -> R {
try withUnsafeMutablePointers { (_, v) throws(E) in try body(v) }
}

/// Call `body` with `UnsafeMutablePointer`s to the stored `Header`
/// and raw `Element` storage.
///
/// - Note: These pointers are valid only for the duration of the
/// call to `body`.
@_preInverseGenerics
@inlinable
public final func withUnsafeMutablePointers<R>(
_ body: (UnsafeMutablePointer<Header>, UnsafeMutablePointer<Element>) throws -> R
@_alwaysEmitIntoClient
@inline(__always)
public final func withUnsafeMutablePointers<E: Error, R: ~Copyable>(
_ body: (
UnsafeMutablePointer<Header>, UnsafeMutablePointer<Element>
) throws(E) -> R
) throws(E) -> R {
defer { _fixLifetime(self) }
return try body(headerAddress, firstElementAddress)
}
}

extension ManagedBuffer {
@_spi(SwiftStdlibLegacyABI) @available(swift, obsoleted: 1)
@_silgen_name("$ss13ManagedBufferC25withUnsafeMutablePointersyqd__qd__SpyxG_Spyq_GtKXEKlF")
@usableFromInline
internal final func __legacy_withUnsafeMutablePointerToHeader<R>(
_ body: (UnsafeMutablePointer<Header>) throws -> R
) rethrows -> R {
return try withUnsafeMutablePointers { (v, _) in return try body(v) }
}

@_spi(SwiftStdlibLegacyABI) @available(swift, obsoleted: 1)
@_silgen_name("$ss13ManagedBufferC32withUnsafeMutablePointerToHeaderyqd__qd__SpyxGKXEKlF")
@usableFromInline
internal final func __legacy_withUnsafeMutablePointerToElements<R>(
_ body: (UnsafeMutablePointer<Element>) throws -> R
) rethrows -> R {
return try withUnsafeMutablePointers { return try body($1) }
}

@_spi(SwiftStdlibLegacyABI) @available(swift, obsoleted: 1)
@_silgen_name("$ss13ManagedBufferC34withUnsafeMutablePointerToElementsyqd__qd__Spyq_GKXEKlF")
@usableFromInline
internal final func __legacy_withUnsafeMutablePointers<R>(
_ body: (
UnsafeMutablePointer<Header>, UnsafeMutablePointer<Element>
) throws -> R
) rethrows -> R {
defer { _fixLifetime(self) }
return try body(headerAddress, firstElementAddress)
Expand Down Expand Up @@ -202,7 +236,10 @@ extension ManagedBuffer where Element: ~Copyable {
/// }
///
@frozen
public struct ManagedBufferPointer<Header, Element: ~Copyable> {
public struct ManagedBufferPointer<
Header,
Element: ~Copyable
>: Copyable {

@_preInverseGenerics
@usableFromInline
Expand Down Expand Up @@ -244,9 +281,6 @@ public struct ManagedBufferPointer<Header, Element: ~Copyable> {
ManagedBufferPointer(unsafeBufferObject: $0).capacity
}))
}
// FIXME: workaround for <rdar://problem/18619176>. If we don't
// access header somewhere, its addressor gets linked away
_ = header
}

/// Manage the given `buffer`.
Expand Down Expand Up @@ -352,7 +386,9 @@ extension ManagedBufferPointer where Element: ~Copyable {
yield &_headerPointer.pointee
}
}
}

extension ManagedBufferPointer where Element: ~Copyable {
/// Returns the object instance being used for storage.
@_preInverseGenerics
@inlinable
Expand All @@ -379,39 +415,36 @@ extension ManagedBufferPointer where Element: ~Copyable {
///
/// - Note: This pointer is valid only
/// for the duration of the call to `body`.
@_preInverseGenerics
@inlinable
public func withUnsafeMutablePointerToHeader<R>(
_ body: (UnsafeMutablePointer<Header>) throws -> R
) rethrows -> R {
return try withUnsafeMutablePointers { (v, _) in return try body(v) }
@_alwaysEmitIntoClient
public func withUnsafeMutablePointerToHeader<E: Error, R: ~Copyable>(
_ body: (UnsafeMutablePointer<Header>) throws(E) -> R
) throws(E) -> R {
try withUnsafeMutablePointers { (v, _) throws(E) in try body(v) }
}

/// Call `body` with an `UnsafeMutablePointer` to the `Element`
/// storage.
///
/// - Note: This pointer is valid only for the duration of the
/// call to `body`.
@_preInverseGenerics
@inlinable
public func withUnsafeMutablePointerToElements<R>(
_ body: (UnsafeMutablePointer<Element>) throws -> R
) rethrows -> R {
return try withUnsafeMutablePointers { return try body($1) }
@_alwaysEmitIntoClient
public func withUnsafeMutablePointerToElements<E: Error, R: ~Copyable>(
_ body: (UnsafeMutablePointer<Element>) throws(E) -> R
) throws(E) -> R {
try withUnsafeMutablePointers { (_, v) throws(E) in try body(v) }
}

/// Call `body` with `UnsafeMutablePointer`s to the stored `Header`
/// and raw `Element` storage.
///
/// - Note: These pointers are valid only for the duration of the
/// call to `body`.
@_preInverseGenerics
@inlinable
public func withUnsafeMutablePointers<R>(
@_alwaysEmitIntoClient
public func withUnsafeMutablePointers<E: Error, R: ~Copyable>(
_ body: (
UnsafeMutablePointer<Header>, UnsafeMutablePointer<Element>
) throws -> R
) rethrows -> R {
) throws(E) -> R
) throws(E) -> R {
defer { _fixLifetime(_nativeBuffer) }
return try body(_headerPointer, _elementPointer)
}
Expand All @@ -427,6 +460,38 @@ extension ManagedBufferPointer where Element: ~Copyable {
}
}

extension ManagedBufferPointer {
@_spi(SwiftStdlibLegacyABI) @available(swift, obsoleted: 1)
@_silgen_name("$ss20ManagedBufferPointerV017withUnsafeMutableC8ToHeaderyqd__qd__SpyxGKXEKlF")
@usableFromInline
internal func withUnsafeMutablePointerToHeader<R>(
_ body: (UnsafeMutablePointer<Header>) throws -> R
) rethrows -> R {
try withUnsafeMutablePointers { (v, _) in try body(v) }
}

@_spi(SwiftStdlibLegacyABI) @available(swift, obsoleted: 1)
@_silgen_name("$ss20ManagedBufferPointerV017withUnsafeMutableC10ToElementsyqd__qd__Spyq_GKXEKlF")
@usableFromInline
internal func withUnsafeMutablePointerToElements<R>(
_ body: (UnsafeMutablePointer<Element>) throws -> R
) rethrows -> R {
try withUnsafeMutablePointers { (_, v) in try body(v) }
}

@_spi(SwiftStdlibLegacyABI) @available(swift, obsoleted: 1)
@_silgen_name("$ss20ManagedBufferPointerV25withUnsafeMutablePointersyqd__qd__SpyxG_Spyq_GtKXEKlF")
@usableFromInline
internal func withUnsafeMutablePointers<R>(
_ body: (
UnsafeMutablePointer<Header>, UnsafeMutablePointer<Element>
) throws -> R
) rethrows -> R {
defer { _fixLifetime(_nativeBuffer) }
return try body(_headerPointer, _elementPointer)
}
}

extension ManagedBufferPointer where Element: ~Copyable {
@_preInverseGenerics
@inlinable
Expand Down
52 changes: 41 additions & 11 deletions stdlib/public/core/Optional.swift
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,24 @@ extension Optional {
/// of the instance.
/// - Returns: The result of the given closure. If this instance is `nil`,
/// returns `nil`.
@inlinable
public func map<U>(
// FIXME: This needs to support typed throws.
@_alwaysEmitIntoClient
@_disfavoredOverload // FIXME: Workaround for source compat issue with
// functions that used to shadow the original map
// (rdar://125016028)
public func map<E: Error, U: ~Copyable>(
_ transform: (Wrapped) throws(E) -> U
) throws(E) -> U? {
switch self {
case .some(let y):
return .some(try transform(y))
case .none:
return .none
}
}

@_spi(SwiftStdlibLegacyABI) @available(swift, obsoleted: 1)
@usableFromInline
internal func map<U>(
_ transform: (Wrapped) throws -> U
) rethrows -> U? {
switch self {
Expand Down Expand Up @@ -220,7 +235,7 @@ extension Optional where Wrapped: ~Copyable {
) throws(E) -> U? {
#if $NoncopyableGenerics
switch self {
case .some(_borrowing y):
case .some(borrowing y):
return .some(try transform(y))
case .none:
return .none
Expand Down Expand Up @@ -251,9 +266,24 @@ extension Optional {
/// of the instance.
/// - Returns: The result of the given closure. If this instance is `nil`,
/// returns `nil`.
@inlinable
public func flatMap<U>(
// FIXME: This needs to support typed throws.
@_alwaysEmitIntoClient
@_disfavoredOverload // FIXME: Workaround for source compat issue with
// functions that used to shadow the original flatMap
// (rdar://125016028)
public func flatMap<E: Error, U: ~Copyable>(
_ transform: (Wrapped) throws(E) -> U?
) throws(E) -> U? {
switch self {
case .some(let y):
return try transform(y)
case .none:
return .none
}
}

@_spi(SwiftStdlibLegacyABI) @available(swift, obsoleted: 1)
@usableFromInline
internal func flatMap<U>(
_ transform: (Wrapped) throws -> U?
) rethrows -> U? {
switch self {
Expand Down Expand Up @@ -286,7 +316,7 @@ extension Optional where Wrapped: ~Copyable {
_ transform: (borrowing Wrapped) throws(E) -> U?
) throws(E) -> U? {
switch self {
case .some(_borrowing y):
case .some(borrowing y):
return try transform(y)
case .none:
return .none
Expand Down Expand Up @@ -770,10 +800,9 @@ extension Optional where Wrapped: ~Copyable {
/// type as the `Wrapped` type of `optional`.
@_transparent
@_alwaysEmitIntoClient
// FIXME: This needs to support typed throws.
public func ?? <T: ~Copyable>(
optional: consuming T?,
defaultValue: @autoclosure () throws -> T
defaultValue: @autoclosure () throws -> T // FIXME: typed throw
) rethrows -> T {
switch consume optional {
case .some(let value):
Expand All @@ -784,8 +813,9 @@ public func ?? <T: ~Copyable>(
}

@_spi(SwiftStdlibLegacyABI) @available(swift, obsoleted: 1)
@_silgen_name("$ss2qqoiyxxSg_xyKXKtKlF")
@usableFromInline
internal func ?? <T>(
internal func _legacy_abi_optionalNilCoalescingOperator <T>(
optional: T?,
defaultValue: @autoclosure () throws -> T
) rethrows -> T {
Expand Down
Loading