Deref is not called before IntoIterator

In the previous post

we left a question. And this post is the answer. I will share the interesting finding from a simple experiment.

The question

The Rust library has implementations that convert &Vec<T> into Iter<t> and &mut Vec<T> into IterMut<T> in Vec<T> but I thought the implementation can be removed and it's just a optimization to bypass the indirect conversions for frequent path because these two steps

  1. &Vec<T> is converted into &[T] by Deref.
  2. IntoIterator from &[T] to Iter<T> is found and applied.

should be executed.

Our task is to make an answer to this question by a simple experiment.


use std::ops::Deref;

struct MyVec<T> {
    inner: Vec<T>,

impl<T> Deref for MyVec<T> {
    type Target = Vec<T>;
    fn deref(&self) -> &Vec<T> {

fn main() {
    let v = MyVec {
        inner: vec![1,2,3,4]
    for e in &v {
        println!("{}", e);

The aim here is that

  1. &MyVec should be deref-ed into &Vec.
  2. The IntoIterator implementation of&Vec should be found and applied.


The result is however, it fails to compile. The error message tells us that the deref is ignored.

error[E0277]: `&MyVec<{integer}>` is not an iterator
18 |     for e in &v {
   |              ^^ `&MyVec<{integer}>` is not an iterator
   = help: the trait `std::iter::Iterator` is not implemented for `&MyVec<{integer}>`
   = note: required by `std::iter::IntoIterator::into_iter`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.


We may be able to understand this behavior as follows.

If we write a for-loop as function the type signature would be like

fn forloop<I, F>(it: I, f: F) where
    I: IntoIterator,
    F: FnMut(I::Item)

In the meantime, in Programming Rust from O'Reilly it says

The deref coercions come with a caveat that can cause some confusion: Rust applies them to resolve type conflicts, but not to satisfy bounds on type variables.

and we can reason about the behavior that Rust compiler doesn't apply Deref to resolve the boundary I: IntoIterator.