It consumes self because you are calling the impl of IntoIterator for Vec<T>, and not the one for &Vec<T>. If you want the other one, you can use the .iter() method.
To actually use into_iter for this, you can call it like this:
To give the full picture, there are three implementations
impl IntoIterator for <Vec<T>> {
type Item = T;
type IntoIter = vec::IntoIter<T>;
fn into_iter(self: Vec<T>) -> vec::IntoIter<T>;
}
impl IntoIterator for <&Vec<T>> {
type Item = &T;
type IntoIter = vec::Iter<'_, T>;
fn into_iter(self: &Vec<T>) -> vec::Iter<'_, T>;
}
impl IntoIterator for <&mut Vec<T>> {
type Item = &mut T;
type IntoIter = vec::IterMut<'_, T>;
fn into_iter(self: &mut Vec<T>) -> vec::IterMut<'_, T>;
}
(ignoring lifetimes for these implementations).
Thus, calling (&vec).into_iter() is the same as vec.iter() and (&mut vec).into_iter() is the same as vec.iter_mut(). (On a variable vec: Vec<T>.)
As @Cerber-Ursi mentioned below, there’s a rule that an implementation on the type itself is preferred. So writing vec.into_iter() on a vec: Vec<T> will first try to use the IntoIterator for Vec<T> implementation before it would’ve tried adding a reference and using IntoIterator for &Vec<T>.
More details on the order of self-types that are tried/considered for a method called can be found here. For Vec<T>, the following receiver types are tried in order: Vec<T>, &Vec<T>, &mut Vec<T>, [T], &[T], &mut [T]. Since the first one, Vec<T> by-value already supports an into_iter method, that’s what‘s used. For your example with Foo, the order is Foo, &Foo and &mut Foo. There is no fn into_iter(self: Foo) method, but a fn into_iter(self: &Foo) method exists so that is chosen.