Description
The following code fails to compile because the reference to the iterator trait object must be mutable, to enable advancing the iterator:
fn test(t: &Iterator<Item=&u64>) -> u64 {
*t.min().unwrap()
}
fn main() {
let array = [0u64];
test(&array.iter());
}
When the problem is fixed by declaring the trait object as mutable, the code compiles and runs just fine:
fn test(t: &mut Iterator<Item=&u64>) -> u64 {
*t.min().unwrap()
}
fn main() {
let array = [0u64];
test(&mut array.iter());
}
Understanding the problem, I would expect the error message for the first snippet to be something along the lines of "error: Iterator<Item=&u64>::next requires a mutable reference". Instead, the compilation failed with the following error:
error[E0277]: the trait bound `std::iter::Iterator<Item=&u64>: std::marker::Sized` is not satisfied
--> iter.rs:2:9
|
2 | *t.min().unwrap()
| ^^^ trait `std::iter::Iterator<Item=&u64>: std::marker::Sized` not satisfied
|
= note: `std::iter::Iterator<Item=&u64>` does not have a constant size known at compile-time
error: aborting due to previous error
Being a beginner in Rust, this error message threw me off. First, I couldn't understand why Rust was insisting that the object is unsized, when the object was declared to accept a reference (fat pointer) to a trait, or that was at least my intention. (I still don't understand this part.)
More importantly, there was no hint that the problem could be resolved simply by changing &
to &mut
in declaration and invocation. Once I realized that, the change was obvious and easy, but the compiler's error message did not help me understand the problem.