[Accepted] SE-0447: Span: Safe Access to Contiguous Storage

Hello Swift Community,

The review of SE-0447: Span: Safe Access to Contiguous Storage concluded on October 15, 2024. The Language Steering Group has accepted the proposal as amended during the review period.

There were some concerns raised about the name Span. It was noted that the name Span is already used by the Swift Distributed Tracing library for a region of code within a task. This is a terminology issue, not a source-compatibility one: Swift's existing name-shadowing rules make it unlikely that existing programs using Swift Distributed Tracing would break with the addition of Span to the standard library. Additionally, the Standard Library uses the name UnsafeBufferPointer for what is effective the "unsafe" counterpart to Span, and this proposal introduces a completely new term. On the other hand, there is strong precedent for the term "span" from other languages (e.g., C++, C#), and it is expected that Span will become a common type throughout the Swift ecosystem that benefits from a short name. The Language Steering Group agrees with the authors that this type should be named Span, and notes that the newly-introduced naming inconsistency with UnsafeBufferPointer could be rectified at a later time.

The other naming concern raised was whether the "unchecked" subscript, which accesses a value within a Span without performing bounds checking, should instead use the label "unsafe". The Language Steering Group felt that "unchecked" more accurately expresses the nature of this subscript: the labeled argument is unchecked, but is still subject to the same precondition as the checked subscript, which coincides with other uses of "unchecked" in the language (e.g., @unchecked Sendable).

The review discussion resulted in some changes to the API surface area regarding indices into spans. The Span type now provides an Index typealias for Int and an indices property, while Raw provides a byteOffsets property. The span-specific index validation operations (boundsContain, isWithin) have been removed in favor of the existing Range operations on the indices.

The Language Steering Group acknowledges that this proposal in isolation is not sufficient to make Span a useful type. This proposal is one of a series of proposals to introduce lifetime dependencies and supporting types into the language and standard library. A follow-up proposal will introduce the ability to form Span instances.

Thank you to everyone who participated in the pitches and review for this important standard library feature and the language features it rests on.

Doug Gregor
Review Manager

22 Likes

If I recall correctly, one of the main reasons @unchecked Sendable was chosen instead of @unsafe Sendable was that an @unchecked Sendable type is (or should be) just as safe to use as a regular Sendable type. However, that is not the case here. The unchecked subscript is definitely unsafe to use.

The use of ‘unchecked’ here is quite clear, so I don’t have a major issue with it. However, I do think it blurs the distinction between how ‘unchecked’ and ‘unsafe’ have been used.

If the caller has (correctly) checked the bounds, then the subscript is safe to use.

In both cases, the person who writes unchecked promises to check something so as to make the use of the feature in question safe.

7 Likes

That’s another way of looking at it, which is certainly valid. I still think it’s used in a slightly different way, but as I mentioned earlier, I don’t have a major issue with it.