Slices
Slices are scope-bound, non-owning views over a contiguous run of values of the same type. See ADR-0064.
This chapter is incomplete — it is filled in as the slices preview feature is implemented. Until ADR-0064 is stabilized, slice surface forms require --preview slices.
Types
A slice type is one of Slice(T) (immutable view) or MutSlice(T) (mutable view), where T is any non-comptime element type.
A slice value is a fat pointer { ptr, len } consisting of a pointer to the first element and a length in elements.
Range Subscripts
range = expression ".." expression (* a..b *)
| expression ".." (* a.. *)
| ".." expression (* ..b *)
| ".." (* .. *)
;
subscript = "[" ( expression | range ) "]" ;
Ranges are recognized only in subscript position. They are not yet a general-purpose expression form: let r = 0..10; and for i in 0..n are not valid uses of a bare range expression.
A range subscript arr[lo..hi] is a place expression naming a sub-place of arr. The endpoints are half-open: the resulting view covers indices [lo, hi). When lo is omitted it defaults to 0; when hi is omitted it defaults to the array length.
For a range subscript on an array of length N, the program MUST satisfy lo <= hi <= N. When both endpoints are constant the check is performed at compile time; otherwise it is performed at runtime.
When lo > hi or hi > N at runtime, the program panics.
Slice Construction via Borrow
&arr[range] produces a Slice(T) view of the indexed sub-range. &mut arr[range] produces a MutSlice(T) view; the receiver MUST be a mutable place.
Range subscripts are valid only as the place under & / &mut. A range subscript used as an rvalue (e.g. let s = arr[1..3];) is rejected; there is no slice value without a borrow.
Indexing
For a slice s and index i: usize, the expression s[i] evaluates to the element at position i.
When i >= s.len() at runtime, s[i] causes the program to panic.
s[i] for a slice whose element type is not Copy is rejected — it would move out of indexed position. (Mirrors the array rule from 7.1:28.)
s[i] = v is an assignment to the element at position i. It is valid only when s has type MutSlice(T). Bounds-check semantics follow 7.2:11.
checked-block Operations
The methods s.ptr() (on any slice) and s.ptr_mut() (on MutSlice(T) only) extract the underlying data pointer. Both MUST appear inside a checked block.
The intrinsics @parts_to_slice(p, n) and @parts_to_mut_slice(p, n) build a slice from a raw pointer and a length. They MUST appear inside a checked block. @parts_to_slice accepts Ptr(T) and produces Slice(T); @parts_to_mut_slice accepts MutPtr(T) and produces MutSlice(T).
Iteration
for x in s over a slice s: Slice(T) (T: Copy) yields each element by value. The loop body sees x: T. The mutable form (over MutSlice(T)) depends on a deref-assignment operator and is currently not supported.