Skip to content

Commit 351c129

Browse files
committed
Restore concrete initializers on Unsafe{Raw}Pointer
1 parent cf53143 commit 351c129

File tree

4 files changed

+83
-7
lines changed

4 files changed

+83
-7
lines changed

stdlib/public/core/BridgeObjectiveC.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,35 @@ public struct AutoreleasingUnsafeMutablePointer<Pointee /* TODO : class */>
419419
}
420420
}
421421

422+
/// Explicit construction from an UnsafeMutablePointer.
423+
///
424+
/// This is inherently unsafe; UnsafeMutablePointer assumes the
425+
/// referenced memory has +1 strong ownership semantics, whereas
426+
/// AutoreleasingUnsafeMutablePointer implies +0 semantics.
427+
///
428+
/// - Warning: Accessing `pointee` as a type that is unrelated to
429+
/// the underlying memory's bound type is undefined.
430+
@_transparent
431+
public init<U>(_ from: UnsafeMutablePointer<U>) {
432+
self._rawValue = from._rawValue
433+
}
434+
435+
/// Explicit construction from an UnsafeMutablePointer.
436+
///
437+
/// Returns nil if `from` is nil.
438+
///
439+
/// This is inherently unsafe; UnsafeMutablePointer assumes the
440+
/// referenced memory has +1 strong ownership semantics, whereas
441+
/// AutoreleasingUnsafeMutablePointer implies +0 semantics.
442+
///
443+
/// - Warning: Accessing `pointee` as a type that is unrelated to
444+
/// the underlying memory's bound type is undefined.
445+
@_transparent
446+
public init?<U>(_ from: UnsafeMutablePointer<U>?) {
447+
guard let unwrapped = from else { return nil }
448+
self.init(unwrapped)
449+
}
450+
422451
/// Explicit construction from a UnsafePointer.
423452
///
424453
/// This is inherently unsafe because UnsafePointers do not imply

stdlib/public/core/UnsafePointer.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,27 @@ public struct UnsafeMutablePointer<Pointee>: _Pointer {
544544
guard let unwrapped = other else { return nil }
545545
self.init(mutating: unwrapped)
546546
}
547+
548+
/// Creates an immutable typed pointer referencing the same memory as the
549+
/// given mutable pointer.
550+
///
551+
/// - Parameter other: The pointer to convert.
552+
@_transparent
553+
public init(_ other: UnsafeMutablePointer<Pointee>) {
554+
self._rawValue = other._rawValue
555+
}
556+
557+
/// Creates an immutable typed pointer referencing the same memory as the
558+
/// given mutable pointer.
559+
///
560+
/// - Parameter other: The pointer to convert. If `other` is `nil`, the
561+
/// result is `nil`.
562+
@_transparent
563+
public init?(_ other: UnsafeMutablePointer<Pointee>?) {
564+
guard let unwrapped = other else { return nil }
565+
self.init(unwrapped)
566+
}
567+
547568

548569
/// Allocates uninitialized memory for the specified number of instances of
549570
/// type `Pointee`.

stdlib/public/core/UnsafeRawPointer.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,32 @@ public struct UnsafeRawPointer: _Pointer {
235235
_rawValue = unwrapped._rawValue
236236
}
237237

238+
/// Creates a new raw pointer from the given typed pointer.
239+
///
240+
/// Use this initializer to explicitly convert `other` to an `UnsafeRawPointer`
241+
/// instance. This initializer creates a new pointer to the same address as
242+
/// `other` and performs no allocation or copying.
243+
///
244+
/// - Parameter other: The typed pointer to convert.
245+
@_transparent
246+
public init<T>(_ other: UnsafeMutablePointer<T>) {
247+
_rawValue = other._rawValue
248+
}
249+
250+
/// Creates a new raw pointer from the given typed pointer.
251+
///
252+
/// Use this initializer to explicitly convert `other` to an `UnsafeRawPointer`
253+
/// instance. This initializer creates a new pointer to the same address as
254+
/// `other` and performs no allocation or copying.
255+
///
256+
/// - Parameter other: The typed pointer to convert. If `other` is `nil`, the
257+
/// result is `nil`.
258+
@_transparent
259+
public init?<T>(_ other: UnsafeMutablePointer<T>?) {
260+
guard let unwrapped = other else { return nil }
261+
_rawValue = unwrapped._rawValue
262+
}
263+
238264
/// Deallocates the previously allocated memory block referenced by this pointer.
239265
///
240266
/// The memory to be deallocated must be uninitialized or initialized to a

test/stdlib/UnsafePointerDiagnostics.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ func unsafePointerConversionAvailability(
6161
_ = UnsafeMutablePointer<Int>(umpi)
6262
_ = UnsafeMutablePointer<Int>(oumpi)
6363

64-
_ = UnsafeMutablePointer<Void>(rp) // expected-warning 4 {{UnsafeMutablePointer<Void> has been replaced by UnsafeMutableRawPointer}} expected-error {{cannot convert value of type 'UnsafeRawPointer' to expected argument type 'RawPointer'}}
65-
_ = UnsafeMutablePointer<Void>(mrp) // expected-error {{cannot convert value of type 'UnsafeMutableRawPointer' to expected argument type 'RawPointer'}} expected-warning 4 {{UnsafeMutablePointer<Void> has been replaced by UnsafeMutableRawPointer}}
64+
_ = UnsafeMutablePointer<Void>(rp) // expected-warning 4 {{UnsafeMutablePointer<Void> has been replaced by UnsafeMutableRawPointer}} expected-error {{cannot invoke initializer for type 'UnsafeMutablePointer<Void>' with an argument list of type '(UnsafeRawPointer)'}} expected-note {{overloads for 'UnsafeMutablePointer<Void>' exist with these partially matching parameter lists: (RawPointer), (UnsafeMutablePointer<Pointee>), (UnsafeMutablePointer<Pointee>?)}} expected-note {{Pointer conversion restricted: use '.assumingMemoryBound(to:)' or '.bindMemory(to:capacity:)' to view memory as a type.}}
65+
_ = UnsafeMutablePointer<Void>(mrp) // expected-warning 4 {{UnsafeMutablePointer<Void> has been replaced by UnsafeMutableRawPointer}} expected-error {{cannot invoke initializer for type 'UnsafeMutablePointer<Void>' with an argument list of type '(UnsafeMutableRawPointer)'}} expected-note {{overloads for 'UnsafeMutablePointer<Void>' exist with these partially matching parameter lists: (RawPointer), (UnsafeMutablePointer<Pointee>), (UnsafeMutablePointer<Pointee>?)}} expected-note {{Pointer conversion restricted: use '.assumingMemoryBound(to:)' or '.bindMemory(to:capacity:)' to view memory as a type.}}
6666
_ = UnsafeMutablePointer<Void>(umpv) // expected-warning {{UnsafeMutablePointer<Void> has been replaced by UnsafeMutableRawPointer}}
6767
_ = UnsafeMutablePointer<Void>(umpi) // expected-warning {{UnsafeMutablePointer<Void> has been replaced by UnsafeMutableRawPointer}}
6868
_ = UnsafeMutablePointer<Void>(umps) // expected-warning {{UnsafeMutablePointer<Void> has been replaced by UnsafeMutableRawPointer}}
@@ -76,10 +76,10 @@ func unsafePointerConversionAvailability(
7676
_ = UnsafePointer<Void>(umps) // expected-warning {{UnsafePointer<Void> has been replaced by UnsafeRawPointer}}
7777
_ = UnsafePointer<Void>(ups) // expected-warning {{UnsafePointer<Void> has been replaced by UnsafeRawPointer}}
7878

79-
_ = UnsafeMutablePointer<Int>(rp) // expected-error {{cannot convert value of type 'UnsafeRawPointer' to expected argument type 'RawPointer'}}
80-
_ = UnsafeMutablePointer<Int>(mrp) // expected-error {{cannot convert value of type 'UnsafeMutableRawPointer' to expected argument type 'RawPointer'}}
81-
_ = UnsafeMutablePointer<Int>(orp) // expected-error {{cannot convert value of type 'UnsafeRawPointer?' to expected argument type 'RawPointer'}}
82-
_ = UnsafeMutablePointer<Int>(omrp) // expected-error {{cannot convert value of type 'UnsafeMutableRawPointer?' to expected argument type 'RawPointer'}}
79+
_ = UnsafeMutablePointer<Int>(rp) // expected-error {{cannot invoke initializer for type 'UnsafeMutablePointer<Int>' with an argument list of type '(UnsafeRawPointer)'}} expected-note {{overloads for 'UnsafeMutablePointer<Int>' exist with these partially matching parameter lists: (RawPointer), (UnsafeMutablePointer<Pointee>), (UnsafeMutablePointer<Pointee>?)}} expected-note {{Pointer conversion restricted: use '.assumingMemoryBound(to:)' or '.bindMemory(to:capacity:)' to view memory as a type.}}
80+
_ = UnsafeMutablePointer<Int>(mrp) // expected-error {{cannot invoke initializer for type 'UnsafeMutablePointer<Int>' with an argument list of type '(UnsafeMutableRawPointer)'}} expected-note {{Pointer conversion restricted: use '.assumingMemoryBound(to:)' or '.bindMemory(to:capacity:)' to view memory as a type.}} expected-note {{overloads for 'UnsafeMutablePointer<Int>' exist with these partially matching parameter lists: (RawPointer), (UnsafeMutablePointer<Pointee>), (UnsafeMutablePointer<Pointee>?)}}
81+
_ = UnsafeMutablePointer<Int>(orp) // expected-error {{cannot invoke initializer for type 'UnsafeMutablePointer<Int>' with an argument list of type '(UnsafeRawPointer?)'}} expected-note {{overloads for 'UnsafeMutablePointer<Int>' exist with these partially matching parameter lists: (RawPointer), (UnsafeMutablePointer<Pointee>), (UnsafeMutablePointer<Pointee>?)}} expected-note {{Pointer conversion restricted: use '.assumingMemoryBound(to:)' or '.bindMemory(to:capacity:)' to view memory as a type.}}
82+
_ = UnsafeMutablePointer<Int>(omrp) // expected-error {{cannot invoke initializer for type 'UnsafeMutablePointer<Int>' with an argument list of type '(UnsafeMutableRawPointer?)'}} expected-note {{overloads for 'UnsafeMutablePointer<Int>' exist with these partially matching parameter lists: (RawPointer), (UnsafeMutablePointer<Pointee>), (UnsafeMutablePointer<Pointee>?)}} expected-note {{Pointer conversion restricted: use '.assumingMemoryBound(to:)' or '.bindMemory(to:capacity:)' to view memory as a type.}}
8383

8484
_ = UnsafePointer<Int>(rp) // expected-error {{cannot convert value of type 'UnsafeRawPointer' to expected argument type 'RawPointer'}}
8585
_ = UnsafePointer<Int>(mrp) // expected-error {{cannot convert value of type 'UnsafeMutableRawPointer' to expected argument type 'RawPointer'}}
@@ -114,4 +114,4 @@ func unsafeRawBufferPointerConversions(
114114
_ = UnsafeRawBufferPointer(start: omrp, count: 1)
115115
_ = UnsafeMutableRawBufferPointer(start: orp, count: 1) // expected-error {{cannot convert value of type 'UnsafeRawPointer?' to expected argument type 'UnsafeMutableRawPointer?'}}
116116
_ = UnsafeRawBufferPointer(start: orp, count: 1)
117-
}
117+
}

0 commit comments

Comments
 (0)