Skip to content

Commit f4cc024

Browse files
committed
[stdlib] spans over bridged Substring instances
1 parent 17a9ca4 commit f4cc024

File tree

1 file changed

+30
-9
lines changed

1 file changed

+30
-9
lines changed

stdlib/public/core/Substring.swift

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,31 @@ extension Substring.UTF8View {
756756
public var span: Span<UTF8.CodeUnit> {
757757
@lifetime(borrow self)
758758
borrowing get {
759+
#if _runtime(_ObjC)
760+
// handle non-UTF8 Objective-C bridging cases here
761+
if !_wholeGuts.isFastUTF8 && _wholeGuts._object.hasObjCBridgeableObject {
762+
let foreign = String(_wholeGuts)
763+
let dts = foreign.distance(from: foreign.startIndex, to: startIndex)
764+
let dte = foreign.distance(from: startIndex, to: endIndex)
765+
766+
let storage: __StringStorage
767+
if let associated = _wholeGuts.getAssociatedStorage() {
768+
storage = associated
769+
}
770+
else {
771+
storage = _wholeGuts.getOrAllocateAssociatedStorage()
772+
}
773+
let native = storage.asString
774+
let nativeStart = native.index(native.startIndex, offsetBy: dts)
775+
let startOffset = nativeStart._encodedOffset
776+
let endOffset = native.index(nativeStart, offsetBy: dte)._encodedOffset
777+
778+
let (start, count) = unsafe (storage.start, storage.count)
779+
var span = unsafe Span(_unsafeStart: start, count: count)
780+
span = unsafe span._extracting(unchecked: startOffset..<endOffset)
781+
return unsafe _overrideLifetime(span, borrowing: self)
782+
}
783+
#endif
759784
let start = _slice._startIndex._encodedOffset
760785
let end = _slice._endIndex._encodedOffset
761786
if _wholeGuts.isSmall {
@@ -765,15 +790,11 @@ extension Substring.UTF8View {
765790
let span = unsafe Span(_unsafeStart: address, count: end &- start)
766791
return unsafe _overrideLifetime(span, borrowing: self)
767792
}
768-
else if _wholeGuts.isFastUTF8 {
769-
let buffer = unsafe _wholeGuts._object.fastUTF8.extracting(start..<end)
770-
let count = end &- start
771-
_internalInvariant(count == buffer.count)
772-
let span = unsafe Span(_unsafeElements: buffer)
773-
return unsafe _overrideLifetime(span, borrowing: self)
774-
}
775-
// handle other Objective-C bridging cases here
776-
fatalError("Some bridged Strings are not supported at this time")
793+
_precondition(_wholeGuts.isFastUTF8)
794+
let buffer = unsafe _wholeGuts._object.fastUTF8.extracting(start..<end)
795+
_internalInvariant((end &- start) == buffer.count)
796+
let span = unsafe Span(_unsafeElements: buffer)
797+
return unsafe _overrideLifetime(span, borrowing: self)
777798
}
778799
}
779800
}

0 commit comments

Comments
 (0)