diff --git a/stdlib/public/core/StringUTF8View.swift b/stdlib/public/core/StringUTF8View.swift index 349c6a3137a6b..504ca5cd1665a 100644 --- a/stdlib/public/core/StringUTF8View.swift +++ b/stdlib/public/core/StringUTF8View.swift @@ -89,6 +89,7 @@ extension String { /// print(String(s1.utf8.prefix(15))!) /// // Prints "They call me 'B" @frozen + @_addressableForDependencies public struct UTF8View: Sendable { @usableFromInline internal var _guts: _StringGuts @@ -336,7 +337,7 @@ extension String.UTF8View { borrowing get { #if _runtime(_ObjC) // handle non-UTF8 Objective-C bridging cases here - if !_guts.isFastUTF8 && _guts._object.hasObjCBridgeableObject { + if !_guts.isFastUTF8, _guts._object.hasObjCBridgeableObject { let storage = _guts._getOrAllocateAssociatedStorage() let (start, count) = unsafe (storage.start, storage.count) let span = unsafe Span(_unsafeStart: start, count: count) @@ -345,15 +346,14 @@ extension String.UTF8View { #endif let count = _guts.count if _guts.isSmall { - fatalError("Span over the small string form is not supported yet.") -// let a = Builtin.addressOfBorrow(self) -// let address = unsafe UnsafePointer(a) -// let span = unsafe Span(_unsafeStart: address, count: count) -// return unsafe _overrideLifetime(span, borrowing: self) + let a = Builtin.addressOfBorrow(self) + let address = unsafe UnsafePointer(a) + let span = unsafe Span(_unsafeStart: address, count: count) + return unsafe _overrideLifetime(span, borrowing: self) } - _precondition(_guts.isFastUTF8) + let isFastUTF8 = _guts.isFastUTF8 + _precondition(isFastUTF8, "String must be contiguous UTF8") let buffer = unsafe _guts._object.fastUTF8 - _internalInvariant(count == buffer.count) let span = unsafe Span(_unsafeElements: buffer) return unsafe _overrideLifetime(span, borrowing: self) } diff --git a/stdlib/public/core/Substring.swift b/stdlib/public/core/Substring.swift index 845265c741f6c..769d1b6b35a29 100644 --- a/stdlib/public/core/Substring.swift +++ b/stdlib/public/core/Substring.swift @@ -630,6 +630,7 @@ extension Substring: LosslessStringConvertible { extension Substring { @frozen + @_addressableForDependencies public struct UTF8View: Sendable { @usableFromInline internal var _slice: Slice @@ -778,25 +779,25 @@ extension Substring.UTF8View { borrowing get { #if _runtime(_ObjC) // handle non-UTF8 Objective-C bridging cases here - if !_wholeGuts.isFastUTF8 && _wholeGuts._object.hasObjCBridgeableObject { + if !_wholeGuts.isFastUTF8, _wholeGuts._object.hasObjCBridgeableObject { let base: String.UTF8View = self._base let first = base._foreignDistance(from: base.startIndex, to: startIndex) let count = base._foreignDistance(from: startIndex, to: endIndex) - let span = base.span._extracting(first..<(first &+ count)) + let span = unsafe base.span._extracting(first..<(first &+ count)) return unsafe _overrideLifetime(span, borrowing: self) } #endif let first = _slice._startIndex._encodedOffset let end = _slice._endIndex._encodedOffset if _wholeGuts.isSmall { - fatalError("Span over the small string form is not supported yet.") -// let a = Builtin.addressOfBorrow(self) -// let offset = first &+ (2 &* MemoryLayout.stride) -// let start = unsafe UnsafePointer(a).advanced(by: offset) -// let span = unsafe Span(_unsafeStart: start, count: end &- first) -// return unsafe _overrideLifetime(span, borrowing: self) + let a = Builtin.addressOfBorrow(self) + let offset = first &+ (2 &* MemoryLayout.stride) + let start = unsafe UnsafePointer(a).advanced(by: offset) + let span = unsafe Span(_unsafeStart: start, count: end &- first) + return unsafe _overrideLifetime(span, borrowing: self) } - _internalInvariant(_wholeGuts.isFastUTF8) + let isFastUTF8 = _wholeGuts.isFastUTF8 + _precondition(isFastUTF8, "Substring must be contiguous UTF8") var span = unsafe Span(_unsafeElements: _wholeGuts._object.fastUTF8) span = span._extracting(first..