Explicit typing is required to get a fat pointer

impl<T> ops::Deref for Vec<T> {
    type Target = [T];

    fn deref(&self) -> &[T] {
        unsafe {
            let p = self.buf.ptr();
            slice::from_raw_parts(p, self.len)

We know that Rust implicitly convert &Vec<T> to &[T] thanks to Deref trait.

But now here is a question. What is the type of the variable vp0 in the following code?

fn main() {
    let v: Vec<i32> = vec![1,2,3];
    let vp0 = &v; // Guess what type?

If your understanding is "Adding ampersand to Vec and we get slice!" you may answer "it's &[i32]". But the answer is &Vec<i32>.

We can see this from a simple experiment:

fn main() {
    let v: Vec<i32> = vec![1,2,3]; // Owned pointer
    let vp0 = &v; //  Owned pointer's address
    let vp1: &Vec<i32> = &v; // same as above
    let vs: &[i32] = &v; // Fat pointer

    println!("{:p}={:p}", vp0, vp1);

If vp0 equals to vp1 we can say vp0 is of type &Vec<i32> and the output is actually


and we know that vp0 is of type &Vec<i32>.