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.