@@ -243,8 +243,8 @@ public struct UnsafePointer<Pointee>: _Pointer {
243243 }
244244 }
245245
246- /// Executes the given closure while temporarily binding the specified number
247- /// of instances to the given type.
246+ /// Executes the given closure while temporarily binding memory to
247+ /// the specified number of instances of type `T` .
248248 ///
249249 /// Use this method when you have a pointer to memory bound to one type and
250250 /// you need to access that memory as instances of another type. Accessing
@@ -253,15 +253,23 @@ public struct UnsafePointer<Pointee>: _Pointer {
253253 /// the same memory as an unrelated type without first rebinding the memory
254254 /// is undefined.
255255 ///
256- /// The region of memory starting at this pointer and covering `count`
257- /// instances of the pointer's `Pointee` type must be initialized.
256+ /// The region of memory that starts at this pointer and covers `count`
257+ /// strides of `T` instances must be bound to `Pointee`.
258+ /// Any instance of `T` within the re-bound region may be initialized or
259+ /// uninitialized. Every instance of `Pointee` overlapping with a given
260+ /// instance of `T` should have the same initialization state (i.e.
261+ /// initialized or uninitialized.) Accessing a `T` whose underlying
262+ /// `Pointee` storage is in a mixed initialization state shall be
263+ /// undefined behaviour.
258264 ///
259265 /// The following example temporarily rebinds the memory of a `UInt64`
260266 /// pointer to `Int64`, then accesses a property on the signed integer.
261267 ///
262268 /// let uint64Pointer: UnsafePointer<UInt64> = fetchValue()
263- /// let isNegative = uint64Pointer.withMemoryRebound(to: Int64.self, capacity: 1) { ptr in
264- /// return ptr.pointee < 0
269+ /// let isNegative = uint64Pointer.withMemoryRebound(
270+ /// to: Int64.self, capacity: 1
271+ /// ) {
272+ /// return $0.pointee < 0
265273 /// }
266274 ///
267275 /// Because this pointer's memory is no longer bound to its `Pointee` type
@@ -274,31 +282,60 @@ public struct UnsafePointer<Pointee>: _Pointer {
274282 /// `Pointee` type.
275283 ///
276284 /// - Note: Only use this method to rebind the pointer's memory to a type
277- /// with the same size and stride as the currently bound `Pointee` type.
278- /// To bind a region of memory to a type that is a different size, convert
279- /// the pointer to a raw pointer and use the `bindMemory(to:capacity:)`
280- /// method.
285+ /// that is layout compatible with the `Pointee` type. The stride of the
286+ /// temporary type (`T`) may be an integer multiple or a whole fraction
287+ /// of `Pointee`'s stride, for example to point to one element of
288+ /// an aggregate.
289+ /// To bind a region of memory to a type that does not match these
290+ /// requirements, convert the pointer to a raw pointer and use the
291+ /// `bindMemory(to:)` method.
292+ /// If `T` and `Pointee` have different alignments, this pointer
293+ /// must be aligned with the larger of the two alignments.
281294 ///
282295 /// - Parameters:
283296 /// - type: The type to temporarily bind the memory referenced by this
284- /// pointer. The type `T` must be the same size and be layout compatible
297+ /// pointer. The type `T` must be layout compatible
285298 /// with the pointer's `Pointee` type.
286- /// - count: The number of instances of `Pointee` to bind to `type` .
287- /// - body: A closure that takes a typed pointer to the
299+ /// - count: The number of instances of `T` in the re-bound region .
300+ /// - body: A closure that takes a typed pointer to the
288301 /// same memory as this pointer, only bound to type `T`. The closure's
289302 /// pointer argument is valid only for the duration of the closure's
290303 /// execution. If `body` has a return value, that value is also used as
291304 /// the return value for the `withMemoryRebound(to:capacity:_:)` method.
305+ /// - pointer: The pointer temporarily bound to `T`.
292306 /// - Returns: The return value, if any, of the `body` closure parameter.
293307 @inlinable
294- public func withMemoryRebound< T, Result> ( to type: T . Type , capacity count: Int ,
308+ @_alwaysEmitIntoClient
309+ // This custom silgen name is chosen to not interfere with the old ABI
310+ @_silgen_name ( " _swift_se0333_UnsafePointer_withMemoryRebound " )
311+ public func withMemoryRebound< T, Result> (
312+ to type: T . Type ,
313+ capacity count: Int ,
314+ _ body: ( _ pointer: UnsafePointer < T > ) throws -> Result
315+ ) rethrows -> Result {
316+ _debugPrecondition (
317+ Int ( bitPattern: . init( _rawValue) ) & ( MemoryLayout < T > . alignment- 1 ) == 0 &&
318+ MemoryLayout < Pointee > . stride > MemoryLayout< T> . stride
319+ ? MemoryLayout< Pointee> . stride % MemoryLayout < T > . stride == 0
320+ : MemoryLayout < T > . stride % MemoryLayout < Pointee > . stride == 0
321+ )
322+ let binding = Builtin . bindMemory ( _rawValue, count. _builtinWordValue, T . self)
323+ defer { Builtin . rebindMemory ( _rawValue, binding) }
324+ return try body ( . init( _rawValue) )
325+ }
326+
327+ // This unavailable implementation uses the expected mangled name
328+ // of `withMemoryRebound`, and provides an entry point for any
329+ // binary compiled against the stlib binary for Swift 5.6 and older.
330+ @available ( * , unavailable)
331+ @_silgen_name ( " $sSP17withMemoryRebound2to8capacity_qd_0_qd__m_Siqd_0_SPyqd__GKXEtKr0_lF " )
332+ @usableFromInline
333+ internal func _legacy_se0333_withMemoryRebound< T, Result> (
334+ to type: T . Type ,
335+ capacity count: Int ,
295336 _ body: ( UnsafePointer < T > ) throws -> Result
296337 ) rethrows -> Result {
297- Builtin . bindMemory ( _rawValue, count. _builtinWordValue, T . self)
298- defer {
299- Builtin . bindMemory ( _rawValue, count. _builtinWordValue, Pointee . self)
300- }
301- return try body ( UnsafePointer < T > ( _rawValue) )
338+ return try withMemoryRebound ( to: T . self, capacity: count, body)
302339 }
303340
304341 /// Accesses the pointee at the specified offset from this pointer.
@@ -894,8 +931,8 @@ public struct UnsafeMutablePointer<Pointee>: _Pointer {
894931 return UnsafeMutableRawPointer ( self )
895932 }
896933
897- /// Executes the given closure while temporarily binding the specified number
898- /// of instances to the given type.
934+ /// Executes the given closure while temporarily binding memory to
935+ /// the specified number of instances of the given type.
899936 ///
900937 /// Use this method when you have a pointer to memory bound to one type and
901938 /// you need to access that memory as instances of another type. Accessing
@@ -904,15 +941,21 @@ public struct UnsafeMutablePointer<Pointee>: _Pointer {
904941 /// the same memory as an unrelated type without first rebinding the memory
905942 /// is undefined.
906943 ///
907- /// The region of memory starting at this pointer and covering `count`
908- /// instances of the pointer's `Pointee` type must be initialized.
944+ /// The region of memory that starts at this pointer and covers `count`
945+ /// strides of `T` instances must be bound to `Pointee`.
946+ /// Any instance of `T` within the re-bound region may be initialized or
947+ /// uninitialized. Every instance of `Pointee` overlapping with a given
948+ /// instance of `T` should have the same initialization state (i.e.
949+ /// initialized or uninitialized.) Accessing a `T` whose underlying
950+ /// `Pointee` storage is in a mixed initialization state shall be
951+ /// undefined behaviour.
909952 ///
910953 /// The following example temporarily rebinds the memory of a `UInt64`
911- /// pointer to `Int64`, then accesses a property on the signed integer.
954+ /// pointer to `Int64`, then modifies the signed integer.
912955 ///
913956 /// let uint64Pointer: UnsafeMutablePointer<UInt64> = fetchValue()
914- /// let isNegative = uint64Pointer.withMemoryRebound(to: Int64.self, capacity: 1) { ptr in
915- /// return ptr .pointee < 0
957+ /// uint64Pointer.withMemoryRebound(to: Int64.self, capacity: 1) {
958+ /// $0 .pointee.negate()
916959 /// }
917960 ///
918961 /// Because this pointer's memory is no longer bound to its `Pointee` type
@@ -925,31 +968,60 @@ public struct UnsafeMutablePointer<Pointee>: _Pointer {
925968 /// `Pointee` type.
926969 ///
927970 /// - Note: Only use this method to rebind the pointer's memory to a type
928- /// with the same size and stride as the currently bound `Pointee` type.
929- /// To bind a region of memory to a type that is a different size, convert
930- /// the pointer to a raw pointer and use the `bindMemory(to:capacity:)`
931- /// method.
971+ /// that is layout compatible with the `Pointee` type. The stride of the
972+ /// temporary type (`T`) may be an integer multiple or a whole fraction
973+ /// of `Pointee`'s stride, for example to point to one element of
974+ /// an aggregate.
975+ /// To bind a region of memory to a type that does not match these
976+ /// requirements, convert the pointer to a raw pointer and use the
977+ /// `bindMemory(to:)` method.
978+ /// If `T` and `Pointee` have different alignments, this pointer
979+ /// must be aligned with the larger of the two alignments.
932980 ///
933981 /// - Parameters:
934982 /// - type: The type to temporarily bind the memory referenced by this
935- /// pointer. The type `T` must be the same size and be layout compatible
983+ /// pointer. The type `T` must be layout compatible
936984 /// with the pointer's `Pointee` type.
937- /// - count: The number of instances of `Pointee` to bind to `type` .
985+ /// - count: The number of instances of `T` in the re-bound region .
938986 /// - body: A closure that takes a mutable typed pointer to the
939987 /// same memory as this pointer, only bound to type `T`. The closure's
940988 /// pointer argument is valid only for the duration of the closure's
941989 /// execution. If `body` has a return value, that value is also used as
942990 /// the return value for the `withMemoryRebound(to:capacity:_:)` method.
991+ /// - pointer: The pointer temporarily bound to `T`.
943992 /// - Returns: The return value, if any, of the `body` closure parameter.
944993 @inlinable
945- public func withMemoryRebound< T, Result> ( to type: T . Type , capacity count: Int ,
994+ @_alwaysEmitIntoClient
995+ // This custom silgen name is chosen to not interfere with the old ABI
996+ @_silgen_name ( " $_swift_se0333_UnsafeMutablePointer_withMemoryRebound " )
997+ public func withMemoryRebound< T, Result> (
998+ to type: T . Type ,
999+ capacity count: Int ,
1000+ _ body: ( _ pointer: UnsafeMutablePointer < T > ) throws -> Result
1001+ ) rethrows -> Result {
1002+ _debugPrecondition (
1003+ Int ( bitPattern: . init( _rawValue) ) & ( MemoryLayout < T > . alignment- 1 ) == 0 &&
1004+ MemoryLayout < Pointee > . stride > MemoryLayout< T> . stride
1005+ ? MemoryLayout< Pointee> . stride % MemoryLayout < T > . stride == 0
1006+ : MemoryLayout < T > . stride % MemoryLayout < Pointee > . stride == 0
1007+ )
1008+ let binding = Builtin . bindMemory ( _rawValue, count. _builtinWordValue, T . self)
1009+ defer { Builtin . rebindMemory ( _rawValue, binding) }
1010+ return try body ( . init( _rawValue) )
1011+ }
1012+
1013+ // This unavailable implementation uses the expected mangled name
1014+ // of `withMemoryRebound`, and provides an entry point for any
1015+ // binary compiled against the stlib binary for Swift 5.6 and older.
1016+ @available ( * , unavailable)
1017+ @_silgen_name ( " $sSp17withMemoryRebound2to8capacity_qd_0_qd__m_Siqd_0_Spyqd__GKXEtKr0_lF " )
1018+ @usableFromInline
1019+ internal func _legacy_se0333_withMemoryRebound< T, Result> (
1020+ to type: T . Type ,
1021+ capacity count: Int ,
9461022 _ body: ( UnsafeMutablePointer < T > ) throws -> Result
9471023 ) rethrows -> Result {
948- Builtin . bindMemory ( _rawValue, count. _builtinWordValue, T . self)
949- defer {
950- Builtin . bindMemory ( _rawValue, count. _builtinWordValue, Pointee . self)
951- }
952- return try body ( UnsafeMutablePointer < T > ( _rawValue) )
1024+ return try withMemoryRebound ( to: T . self, capacity: count, body)
9531025 }
9541026
9551027 /// Accesses the pointee at the specified offset from this pointer.
0 commit comments