Skip to content

[6.2, SE-0456, -0467] enable span properties for inline-storage types #80740

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion stdlib/public/core/CollectionOfOne.swift
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,22 @@ extension CollectionOfOne {
@lifetime(borrow self)
@_alwaysEmitIntoClient
get {
fatalError("Span over CollectionOfOne is not supported yet.")
let pointer = unsafe UnsafePointer<Element>(Builtin.addressOfBorrow(self))
let span = unsafe Span(_unsafeStart: pointer, count: 1)
return unsafe _overrideLifetime(span, borrowing: self)
}
}

@available(SwiftStdlib 6.2, *)
public var mutableSpan: MutableSpan<Element> {
@lifetime(&self)
@_alwaysEmitIntoClient
mutating get {
let pointer = unsafe UnsafeMutablePointer<Element>(
Builtin.addressOfBorrow(self)
)
let span = unsafe MutableSpan(_unsafeStart: pointer, count: 1)
return unsafe _overrideLifetime(span, mutating: &self)
}
}
}
Expand Down
15 changes: 14 additions & 1 deletion stdlib/public/core/InlineArray.swift
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,20 @@ extension InlineArray where Element: ~Copyable {
@lifetime(borrow self)
@_alwaysEmitIntoClient
borrowing get {
fatalError("Span over InlineArray is not supported yet.")
let pointer = unsafe _address
let span = unsafe Span(_unsafeStart: pointer, count: count)
return unsafe _overrideLifetime(span, borrowing: self)
}
}

@available(SwiftStdlib 6.2, *)
public var mutableSpan: MutableSpan<Element> {
@lifetime(&self)
@_alwaysEmitIntoClient
mutating get {
let pointer = unsafe _mutableAddress
let span = unsafe MutableSpan(_unsafeStart: pointer, count: count)
return unsafe _overrideLifetime(span, mutating: &self)
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions test/abi/macOS/arm64/stdlib.swift
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,8 @@ Added: _$sSs8UTF8ViewV4spans4SpanVys5UInt8VGvpMV
Added: _$sSa11mutableSpans07MutableB0VyxGvr
Added: _$ss10ArraySliceV11mutableSpans07MutableD0VyxGvr
Added: _$ss15ContiguousArrayV11mutableSpans07MutableD0VyxGvr
Added: _$ss11InlineArrayVsRi__rlE11mutableSpans07MutableD0Vyq_Gvr
Added: _$ss15CollectionOfOneV11mutableSpans07MutableE0VyxGvr

// _SwiftifyInfo enum for _SwiftifyImports macro
Added: _$ss13_SwiftifyExprO5paramyABSicABmFWC
Expand Down
2 changes: 2 additions & 0 deletions test/abi/macOS/x86_64/stdlib.swift
Original file line number Diff line number Diff line change
Expand Up @@ -847,6 +847,8 @@ Added: _$sSs8UTF8ViewV4spans4SpanVys5UInt8VGvpMV
Added: _$sSa11mutableSpans07MutableB0VyxGvr
Added: _$ss10ArraySliceV11mutableSpans07MutableD0VyxGvr
Added: _$ss15ContiguousArrayV11mutableSpans07MutableD0VyxGvr
Added: _$ss11InlineArrayVsRi__rlE11mutableSpans07MutableD0Vyq_Gvr
Added: _$ss15CollectionOfOneV11mutableSpans07MutableE0VyxGvr

// _SwiftifyInfo enum for _SwiftifyImports macro
Added: _$ss13_SwiftifyExprO5paramyABSicABmFWC
Expand Down
51 changes: 41 additions & 10 deletions test/stdlib/Span/InlineSpanProperties.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ var suite = TestSuite("Span properties backed by inline storage")
defer { runAllTests() }

suite.test("CollectionOfOne.span property")
.skip(.wasiAny(reason: "Trap tests aren't supported on WASI."))
.skip(.custom(
{ if #available(SwiftStdlib 6.2, *) { false } else { true } },
reason: "Requires Swift 6.2's standard library"
Expand All @@ -35,15 +34,13 @@ suite.test("CollectionOfOne.span property")
let u = Array(s.utf8)
let c = CollectionOfOne(consume s)
s = ""
expectCrashLater()
let span = c.span
expectEqual(span.count, 1)
let v = Array(span[0].utf8)
expectEqual(u, v)
}

suite.test("CollectionOfOne.span property (simple)")
.skip(.wasiAny(reason: "Trap tests aren't supported on WASI."))
.skip(.custom(
{ if #available(SwiftStdlib 6.2, *) { false } else { true } },
reason: "Requires Swift 6.2's standard library"
Expand All @@ -52,7 +49,6 @@ suite.test("CollectionOfOne.span property (simple)")
guard #available(SwiftStdlib 6.2, *) else { return }

let c = CollectionOfOne(Int.random(in: 0..<100000))
expectCrashLater()
let span = c.span
expectEqual(span.count, c.indices.count)
expectEqual(span[0], c[0])
Expand All @@ -63,7 +59,6 @@ struct Padded: BitwiseCopyable {
}

suite.test("CollectionOfOne.span stride test")
.skip(.wasiAny(reason: "Trap tests aren't supported on WASI."))
.skip(.custom(
{ if #available(SwiftStdlib 6.2, *) { false } else { true } },
reason: "Requires Swift 6.2's standard library"
Expand All @@ -72,14 +67,25 @@ suite.test("CollectionOfOne.span stride test")
guard #available(SwiftStdlib 6.2, *) else { return }

let c = CollectionOfOne(Padded(storage: (-1, 1)))
expectCrashLater()
let span = c.span
let bytes = span.bytes
expectEqual(bytes.byteCount, MemoryLayout.size(ofValue: c))
}

suite.test("CollectionOfOne.mutableSpan property (simple)")
.require(.stdlib_6_2).code {
guard #available(SwiftStdlib 6.2, *) else { return }

var c = CollectionOfOne(Int.random(in: 0..<100000))
expectEqual(c.count, 1)
var span = c.mutableSpan
expectEqual(span.count, 1)
span[0] = Int.random(in: .min..<0)
let r = span[0]
expectEqual(c[0], r)
}

suite.test("InlineArray.span property")
.skip(.wasiAny(reason: "Trap tests aren't supported on WASI."))
.skip(.custom(
{ if #available(SwiftStdlib 6.2, *) { false } else { true } },
reason: "Requires Swift 6.2's standard library"
Expand All @@ -89,7 +95,6 @@ suite.test("InlineArray.span property")

var s = InlineArray<5, Int>(repeating: 0)
s[3] = .random(in: 0..<1000)
expectCrashLater()
let span = s.span
expectEqual(span.count, s.count)
for i in s.indices {
Expand All @@ -98,7 +103,6 @@ suite.test("InlineArray.span property")
}

suite.test("InlineArray.span property (String)")
.skip(.wasiAny(reason: "Trap tests aren't supported on WASI."))
.skip(.custom(
{ if #available(SwiftStdlib 6.2, *) { false } else { true } },
reason: "Requires Swift 6.2's standard library"
Expand All @@ -108,10 +112,37 @@ suite.test("InlineArray.span property (String)")

var s = InlineArray<5, String>(repeating: "0")
s[3] = String(Int.random(in: 0..<1000))
expectCrashLater()
let span = s.span
expectEqual(span.count, s.count)
for i in s.indices {
expectEqual(span[i], s[i])
}
}

suite.test("InlineArray.mutableSpan property")
.require(.stdlib_6_2).code
{
guard #available(SwiftStdlib 6.2, *) else { return }

var v = InlineArray<5, Int>(repeating: 0)
let c = v.count
var span = v.mutableSpan
expectEqual(span.count, c)
span[3] = Int.random(in: .min..<0)
let r = span[3]
expectEqual(v[3], r)
}

suite.test("InlineArray.mutableSpan property (String)")
.require(.stdlib_6_2).code
{
guard #available(SwiftStdlib 6.2, *) else { return }

var v = InlineArray<5, String>(repeating: "0")
let c = v.count
var span = v.mutableSpan
expectEqual(span.count, c)
span[3] = String(repeating: "0", count: Int.random(in: 100..<500))
let s = span[3]
expectTrue(s._isIdentical(to: v[3]))
}