Skip to content

Commit 493e853

Browse files
authored
Merge pull request #80684 from glessard/rdar137710901-addressable-utf8view-span
[SE-0456] enable span properties for the small-String representation
2 parents 721944a + f349282 commit 493e853

6 files changed

+23
-23
lines changed

stdlib/public/core/StringUTF8View.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ extension String {
8989
/// print(String(s1.utf8.prefix(15))!)
9090
/// // Prints "They call me 'B"
9191
@frozen
92+
@_addressableForDependencies
9293
public struct UTF8View: Sendable {
9394
@usableFromInline
9495
internal var _guts: _StringGuts
@@ -336,7 +337,7 @@ extension String.UTF8View {
336337
borrowing get {
337338
#if _runtime(_ObjC)
338339
// handle non-UTF8 Objective-C bridging cases here
339-
if !_guts.isFastUTF8 && _guts._object.hasObjCBridgeableObject {
340+
if !_guts.isFastUTF8, _guts._object.hasObjCBridgeableObject {
340341
let storage = _guts._getOrAllocateAssociatedStorage()
341342
let (start, count) = unsafe (storage.start, storage.count)
342343
let span = unsafe Span(_unsafeStart: start, count: count)
@@ -345,15 +346,14 @@ extension String.UTF8View {
345346
#endif
346347
let count = _guts.count
347348
if _guts.isSmall {
348-
fatalError("Span over the small string form is not supported yet.")
349-
// let a = Builtin.addressOfBorrow(self)
350-
// let address = unsafe UnsafePointer<UTF8.CodeUnit>(a)
351-
// let span = unsafe Span(_unsafeStart: address, count: count)
352-
// return unsafe _overrideLifetime(span, borrowing: self)
349+
let a = Builtin.addressOfBorrow(self)
350+
let address = unsafe UnsafePointer<UTF8.CodeUnit>(a)
351+
let span = unsafe Span(_unsafeStart: address, count: count)
352+
return unsafe _overrideLifetime(span, borrowing: self)
353353
}
354-
_precondition(_guts.isFastUTF8)
354+
let isFastUTF8 = _guts.isFastUTF8
355+
_precondition(isFastUTF8, "String must be contiguous UTF8")
355356
let buffer = unsafe _guts._object.fastUTF8
356-
_internalInvariant(count == buffer.count)
357357
let span = unsafe Span(_unsafeElements: buffer)
358358
return unsafe _overrideLifetime(span, borrowing: self)
359359
}

stdlib/public/core/Substring.swift

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,7 @@ extension Substring: LosslessStringConvertible {
630630

631631
extension Substring {
632632
@frozen
633+
@_addressableForDependencies
633634
public struct UTF8View: Sendable {
634635
@usableFromInline
635636
internal var _slice: Slice<String.UTF8View>
@@ -778,7 +779,7 @@ extension Substring.UTF8View {
778779
borrowing get {
779780
#if _runtime(_ObjC)
780781
// handle non-UTF8 Objective-C bridging cases here
781-
if !_wholeGuts.isFastUTF8 && _wholeGuts._object.hasObjCBridgeableObject {
782+
if !_wholeGuts.isFastUTF8, _wholeGuts._object.hasObjCBridgeableObject {
782783
let base: String.UTF8View = self._base
783784
let first = base._foreignDistance(from: base.startIndex, to: startIndex)
784785
let count = base._foreignDistance(from: startIndex, to: endIndex)
@@ -789,14 +790,14 @@ extension Substring.UTF8View {
789790
let first = _slice._startIndex._encodedOffset
790791
let end = _slice._endIndex._encodedOffset
791792
if _wholeGuts.isSmall {
792-
fatalError("Span over the small string form is not supported yet.")
793-
// let a = Builtin.addressOfBorrow(self)
794-
// let offset = first &+ (2 &* MemoryLayout<String.Index>.stride)
795-
// let start = unsafe UnsafePointer<UTF8.CodeUnit>(a).advanced(by: offset)
796-
// let span = unsafe Span(_unsafeStart: start, count: end &- first)
797-
// return unsafe _overrideLifetime(span, borrowing: self)
793+
let a = Builtin.addressOfBorrow(self)
794+
let offset = first &+ (2 &* MemoryLayout<String.Index>.stride)
795+
let start = unsafe UnsafePointer<UTF8.CodeUnit>(a).advanced(by: offset)
796+
let span = unsafe Span(_unsafeStart: start, count: end &- first)
797+
return unsafe _overrideLifetime(span, borrowing: self)
798798
}
799-
_internalInvariant(_wholeGuts.isFastUTF8)
799+
let isFastUTF8 = _wholeGuts.isFastUTF8
800+
_precondition(isFastUTF8, "Substring must be contiguous UTF8")
800801
var span = unsafe Span(_unsafeElements: _wholeGuts._object.fastUTF8)
801802
span = span._extracting(first..<end)
802803
return unsafe _overrideLifetime(span, borrowing: self)

test/api-digester/Outputs/stability-stdlib-source-base.swift.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,8 @@ Func ContiguousArray.withUnsafeMutableBufferPointer(_:) is now without rethrows
363363

364364
// Adoption of @_addressableForDependencies
365365
Struct CollectionOfOne is now with @_addressableForDependencies
366+
Struct String.UTF8View is now with @_addressableForDependencies
367+
Struct Substring.UTF8View is now with @_addressableForDependencies
366368

367369
Protocol CodingKey has added inherited protocol SendableMetatype
368370
Protocol Error has added inherited protocol SendableMetatype

test/api-digester/stability-stdlib-abi-without-asserts.test

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,8 @@ Func _SliceBuffer.withUnsafeMutableBufferPointer(_:) has mangled name changing f
825825
Struct String.Index has added a conformance to an existing protocol CustomDebugStringConvertible
826826

827827
Struct CollectionOfOne is now with @_addressableForDependencies
828+
Struct String.UTF8View is now with @_addressableForDependencies
829+
Struct Substring.UTF8View is now with @_addressableForDependencies
828830

829831
Enum _SwiftifyInfo is a new API without @available attribute
830832
Enum _SwiftifyExpr is a new API without @available attribute

test/stdlib/Span/BridgedStringUTF8ViewSpanTests.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,8 @@ let strings = [
2828
"A long ASCII string exceeding 16 code units.",
2929
"🇯🇵",
3030
"🏂☃❅❆❄︎⛄️❄️",
31-
// Enable the following once the small native string form is supported
32-
// "z",
33-
// "",
31+
"z",
32+
"",
3433
]
3534

3635
strings.forEach { expected in

test/stdlib/Span/StringUTF8SpanProperty.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,11 @@ var suite = TestSuite("StringUTF8StorageProperty")
2222
defer { runAllTests() }
2323

2424
suite.test("Span from Small String")
25-
.skip(.wasiAny(reason: "Trap tests aren't supported on WASI."))
2625
.require(.stdlib_6_2).code {
2726
guard #available(SwiftStdlib 6.2, *) else { return }
2827

2928
let s = "A small string.".utf8
3029
let u = Array(s)
31-
expectCrashLater()
3230
let span = s.span
3331

3432
let count = span.count
@@ -56,13 +54,11 @@ suite.test("Span from Large Native String")
5654
}
5755

5856
suite.test("Span from Small String's Substring")
59-
.skip(.wasiAny(reason: "Trap tests aren't supported on WASI."))
6057
.require(.stdlib_6_2).code {
6158
guard #available(SwiftStdlib 6.2, *) else { return }
6259

6360
let s = "A small string.".dropFirst(8).utf8
6461
let u = Array("string.".utf8)
65-
expectCrashLater()
6662
let span = s.span
6763

6864
let count = span.count

0 commit comments

Comments
 (0)