- 
                Notifications
    You must be signed in to change notification settings 
- Fork 13.9k
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.