Skip to content

Commit f175f92

Browse files
Merge pull request #22315 from moiseev/safe-unsafe-5
[5.0][stdlib] Restore concrete initializers on Unsafe{Raw}Pointer
2 parents 468eaca + 2409328 commit f175f92

File tree

4 files changed

+82
-6
lines changed

4 files changed

+82
-6
lines changed

stdlib/public/core/BridgeObjectiveC.swift

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

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

0 commit comments

Comments
 (0)