@@ -197,26 +197,30 @@ extension _SmallString {
197
197
internal func withUTF8< Result> (
198
198
_ f: ( UnsafeBufferPointer < UInt8 > ) throws -> Result
199
199
) rethrows -> Result {
200
+ let count = self . count
200
201
var raw = self . zeroTerminatedRawCodeUnits
201
- return try Swift . withUnsafeBytes ( of: & raw) { rawBufPtr in
202
- let ptr = rawBufPtr. baseAddress. _unsafelyUnwrappedUnchecked
203
- . assumingMemoryBound ( to: UInt8 . self)
204
- return try f ( UnsafeBufferPointer ( start: ptr, count: self . count) )
202
+ return try Swift . withUnsafeBytes ( of: & raw) {
203
+ let rawPtr = $0. baseAddress. _unsafelyUnwrappedUnchecked
204
+ // Rebind the underlying (UInt64, UInt64) tuple to UInt8 for the
205
+ // duration of the closure. Accessing self after this rebind is undefined.
206
+ let ptr = rawPtr. bindMemory ( to: UInt8 . self, capacity: count)
207
+ defer {
208
+ // Restore the memory type of self._storage
209
+ _ = rawPtr. bindMemory ( to: RawBitPattern . self, capacity: 1 )
210
+ }
211
+ return try f ( UnsafeBufferPointer ( start: ptr, count: count) )
205
212
}
206
213
}
207
214
208
215
// Overwrite stored code units, including uninitialized. `f` should return the
209
216
// new count.
210
217
@inline ( __always)
211
218
internal mutating func withMutableCapacity(
212
- _ f: ( UnsafeMutableBufferPointer < UInt8 > ) throws -> Int
219
+ _ f: ( UnsafeMutableRawBufferPointer ) throws -> Int
213
220
) rethrows {
214
221
let len = try withUnsafeMutableBytes ( of: & self . _storage) {
215
222
( rawBufPtr: UnsafeMutableRawBufferPointer ) -> Int in
216
- let ptr = rawBufPtr. baseAddress. _unsafelyUnwrappedUnchecked
217
- . assumingMemoryBound ( to: UInt8 . self)
218
- return try f ( UnsafeMutableBufferPointer (
219
- start: ptr, count: _SmallString. capacity) )
223
+ return try f ( rawBufPtr)
220
224
}
221
225
if len == 0 {
222
226
self = _SmallString ( )
@@ -273,7 +277,17 @@ extension _SmallString {
273
277
) rethrows {
274
278
self . init ( )
275
279
try self . withMutableCapacity {
276
- return try initializer ( $0)
280
+ let capacity = $0. count
281
+ let rawPtr = $0. baseAddress. _unsafelyUnwrappedUnchecked
282
+ // Rebind the underlying (UInt64, UInt64) tuple to UInt8 for the
283
+ // duration of the closure. Accessing self after this rebind is undefined.
284
+ let ptr = rawPtr. bindMemory ( to: UInt8 . self, capacity: capacity)
285
+ defer {
286
+ // Restore the memory type of self._storage
287
+ _ = rawPtr. bindMemory ( to: RawBitPattern . self, capacity: 1 )
288
+ }
289
+ return try initializer (
290
+ UnsafeMutableBufferPointer < UInt8 > ( start: ptr, count: capacity) )
277
291
}
278
292
self . _invariantCheck ( )
279
293
}
0 commit comments