SE-0447: Span: Safe Access to Contiguous Storage

Re: Indices, slice types

Span does not own its storage and there is no concern about leaking larger allocations. It would benefit from being its own slice type.

Note that this sentence is in the Appendix; it summarizes some of the (many, many) alternative designs @glessard implemented. This section serves as a rationale for the proposed design. It details options that we carefully evaluated and found unworkable; it does not present anything that we'd still want to explore in the future. (Certainly not in context of any span types -- including variants such as MutableSpan and OutputSpan.)

Indeed -- after exhaustively exploring the available options, we decided that there was no practical way to make self-slicing work.

The idea of Index wrapping an UnsafePointer was particularly attractive; unfortunately it generally allows indices to fall "in between" valid elements, and Span would need to perform expensive validation to rule those out, on every access. We went through several rounds of (increasingly desperate) refinements/compromises to make this idea work, but despite our efforts, to our surprise we ultimately had to conclude that the best option overall is to follow UnsafeBufferPointer's preexisting design.

I did not expect that we'd end up adopting UnsafeBufferPointer's indexing model as is, but I cannot argue with these results -- we tried pretty much every other alternative, and nothing came close.

(I still think UnsafePointer would have been a better choice for UnsafeBufferPointer.Index, but for a 100% safe container like Span, offsets from the start are the way to go.

And I find that the extracting methods in SE-0437 provide a good enough alternative to self-slicing for these non-owning, quasi/fully referential container types.)

7 Likes