Strange? type deduced by collect


let v:Vec<_>= [0..10_i32].iter().collect();

is not Vec < i32>.
I really do not understand how it could not be.

You're using the wrong syntax here. Square brackets around a range expression, [0..10_i32], will produce a one-element array of ranges [Range<i32>; 1], not an array of scalars [i32; 10].

To get the value you expect, use (0..10_i32).collect(). You don't need .iter() because 0..10_i32 is already an iterator. The parentheses are just there to enforce the correct precedence, 0..10_i32 is a valid expression on its own.

1 Like

This is almost too subtle for my liking...
Really appreciate the explanation.
Best regards

Looks like a good candidate for a clippy lint.

The reason your original line of code compiles is

  • [0..10_i32] is a value of type [Range<i32>; 1]
  • arrays of length 1 [T; 1] deref coerce to slices [T], so you can call slice methods on them
  • [T] has the iter method that returns an iterator over shared references to each element of the slice
  • collect works on any iterator

So you end up with a value of type Vec<&Range<i32>>, like vec![&(0..10_i32)].