Expansion Operators
Expansion operators let a type define how its readonly, readwrite, and owned values become iterators. Collection for and sequence spread use the same operator declarations. Expansion is not an interface conformance and does not depend on a method named iter or into_iter.
Declarations
Expansion operators belong in an instance declaration:
instance Buffer<T> {
pub operator (...&self): BufferIter<T> {
return BufferIter.from_view(self.view())
}
pub operator (...&+self): BufferIterMut<T> {
return BufferIterMut.from_view(self.view_mut())
}
pub operator (...self): BufferIntoIter<T> {
return BufferIntoIter.from_buffer(move self)
}
}
The receiver capability is part of the operator identity:
...&selfexpands a readonly borrow without transferring the source....&+selfexpands an exclusive readwrite borrow without transferring the source....selfconsumes the source.
An expansion operator takes no ordinary parameters and its return type must conform to Iterator. Its body, visibility, generic declaration pattern, result provenance, and source-module rules are the same as those of other instance members. A type may declare any subset of the three forms.
Expansion syntax is selected only by collection iteration and typed-sequence spread. ...value is not a general expression and cannot be called explicitly. An ordinary named method may expose the same implementation when direct iterator construction is useful.
Generic Requirements
A generic function states expansion and iterator behavior separately:
func visit<C, I>(source: &C): void
where (...&C): I, I: Iterator {
for item in &source {
inspect(item)
}
return
}
The available requirement shapes are:
where (...&C): I
where (...&+C): I
where (...C): I
The result type is exact. The compiler may infer I by selecting the concrete source operator at a call site. I: Iterator and associated-type equalities remain separate requirements because the expansion predicate proves only the conversion result.
Collection Iteration
Source syntax selects one capability:
for item in &values { inspect(item) }
for item in &+values { update(item) }
for item in move values { consume(move item) }
for item in iterator { consume(move item) }
The first three forms select the corresponding expansion operator. The last form requires the source type itself to conform to Iterator; it performs no expansion. A bare collection is rejected rather than guessed as readonly or consuming.
The source expression is evaluated once. The resulting iterator is advanced through its selected Iterator.next declaration. Absence ends the loop without initializing an item. Cleanup for normal completion, continue, break, return, and propagation follows the ordinary ownership and drop rules.
Readwrite expansion holds the exclusive source loan for the iterator lifetime. A typical iterator has Item = &+T. Each loop body receives one element loan, and that loan must end before the next step. The source cannot be accessed independently while the iterator remains live. A yielded borrow may escape only when the ordinary provenance and region rules permit it.
Sequence Spread
Typed sequences select the same operators:
let copied = Vec [0, ...source, 4]
let borrowed: Vec<&T> = Vec [...&source]
let owned = Vec [...move source]
...sourceand...&sourceselect readonly expansion....move sourceselects owned expansion, or accepts a direct owning iterator.- Every spread iterator must also conform to
ExactSizeIterator. - Bare spread copies readonly yielded referents and therefore requires
copyelements. ...&sourcecontributes the yielded readonly references themselves....&+sourceis rejected.
Mutable spread is intentionally unsupported. A literal pack may retain every resulting element at once, which requires a stronger disjointness proof than the one-at-a-time mutable loan used by a collection loop.
Tooling Contract
Diagnostics, hover, completion, definition, references, semantic tokens, formatting, and AST JSON present the authored operator (...receiver): IteratorType form and its exact operator span. Compiler-private callable identities are never source API and must not appear in editor output.