Skip to content

Commit 3616a05

Browse files
committed
[stdlib] Substring.makeContiguousUTF8: Do not lose context in base
1 parent c9adf7a commit 3616a05

File tree

1 file changed

+25
-10
lines changed

1 file changed

+25
-10
lines changed

stdlib/public/core/StringProtocol.swift

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -235,10 +235,31 @@ extension Substring {
235235
///
236236
/// Complexity: O(n) if non-contiguous, O(1) if already contiguous
237237
///
238-
@_alwaysEmitIntoClient
238+
@_alwaysEmitIntoClient @inline(__always)
239239
public mutating func makeContiguousUTF8() {
240-
if _fastPath(isContiguousUTF8) { return }
241-
self = String._copying(self)[...]
240+
if isContiguousUTF8 { return }
241+
return _slowMakeContiguousUTF8()
242+
}
243+
244+
@_alwaysEmitIntoClient // Swift 5.7
245+
@inline(never)
246+
internal mutating func _slowMakeContiguousUTF8() {
247+
_internalInvariant(!isContiguousUTF8)
248+
249+
let scalarOffset = base.unicodeScalars.distance(
250+
from: base.startIndex, to: startIndex)
251+
let scalarCount = base.unicodeScalars.distance(
252+
from: startIndex, to: endIndex)
253+
254+
let scalars = String._copying(base).unicodeScalars
255+
256+
var newStart = scalars.index(scalars.startIndex, offsetBy: scalarOffset)
257+
var newEnd = scalars.index(newStart, offsetBy: scalarCount)
258+
259+
if startIndex._isCharacterAligned { newStart = newStart._characterAligned }
260+
if endIndex._isCharacterAligned { newEnd = newEnd._characterAligned }
261+
262+
self = Substring(_unchecked: scalars._guts, bounds: newStart ..< newEnd)
242263
}
243264

244265
/// Runs `body` over the content of this substring in contiguous memory. If
@@ -258,13 +279,7 @@ extension Substring {
258279
public mutating func withUTF8<R>(
259280
_ body: (UnsafeBufferPointer<UInt8>) throws -> R
260281
) rethrows -> R {
261-
if _fastPath(isContiguousUTF8) {
262-
return try _wholeGuts.withFastUTF8(range: self._offsetRange) {
263-
return try body($0)
264-
}
265-
}
266-
267282
makeContiguousUTF8()
268-
return try _wholeGuts.withFastUTF8(body)
283+
return try _wholeGuts.withFastUTF8(range: _offsetRange, body)
269284
}
270285
}

0 commit comments

Comments
 (0)