Why this fires¶
A for x in expr loop requires expr to produce a sequence of values. Zolo
knows how to iterate over built-in collections (arrays, maps, strings, numeric
ranges) and any type that implements the Iterator or IntoIterator trait.
When the type of expr is a concrete struct or enum that implements neither
trait, the compiler cannot determine what values the loop should produce.
struct Point { x: int, y: int }
fn main() {
let p = Point { x: 1, y: 2 }
for coord in p { print(coord) }
// ^ error[TE828]: type 'Point' is not iterable;
// implement `IntoIterator` or `Iterator`
}Fix it¶
1. Implement Iterator directly¶
If your type produces values one at a time, implement Iterator<T>. The
required method is next(self) -> T? — return nil to signal exhaustion:
struct Counter { n: int, limit: int }
impl Iterator<int> for Counter {
fn next(self) -> int? {
if self.n >= self.limit { return nil }
let val = self.n
self.n = self.n + 1
val
}
}
fn main() {
let c = Counter { n: 0, limit: 3 }
for x in c { print(x) } // prints 0, 1, 2
}2. Implement IntoIterator¶
If your type wraps a collection and you want to expose it as iterable,
implement IntoIterator. The required method is iter(self) -> Iter<T>:
struct NumberList { items: [int] }
impl IntoIterator<int> for NumberList {
fn iter(self) -> [int] { self.items }
}
fn main() {
let nl = NumberList { items: [10, 20, 30] }
for n in nl { print(n) }
}3. Iterate over the field directly¶
If you just want to loop over a field of the struct, access it directly:
struct Bag { values: [int] }
fn main() {
let b = Bag { values: [1, 2, 3] }
for v in b.values { print(v) } // iterate the array field
}Notes¶
- TE828 fires only when the type is a known named type (struct or enum).
If the type is
Any,Unknown, or a function/tuple, the loop is left permissive (no error) to avoid false positives on dynamically-typed code. - Arrays, maps, strings, and numeric range literals (
0..10) are always iterable without any impl. - The
Iteratortrait uses the element type from thenextreturn: forfn next(self) -> T?the loop variable is typed asT.
See also¶
TE825— incomplete trait implementation (missing required method).- /docs/data-structures#traits — trait declarations and implementations.