Search code examples
rustvectorslice

Does Vec<T> auto convert to [T]?


Consider this code:

fn funA() {
    let v1: Vec<i32> = vec![1, 2, 3];
    funB(&v1);   // question_A
    v1.iter();   // question_B
}

fn funB(slice: &[i32]) {
    // slice type is &[i32] by sure
}

I'm confused because funB requires type &[i32], while caller using type &Vec<i32>. Here is part of invoke stack, I can see there is kind of deref and as_ptr actions, but not sure how it works.

core::ptr::mut_ptr::<impl *mut T>::is_null (@core::ptr::mut_ptr::<impl *mut T>::is_null:42)
alloc::vec::Vec<T,A>::as_ptr (@<alloc::vec::Vec<T,A> as core::ops::deref::Deref>::deref:19)
<alloc::vec::Vec<T,A> as core::ops::deref::Deref>::deref (@<alloc::vec::Vec<T,A> as core::ops::deref::Deref>::deref:11)
hello_cargo::funA (/Users/path-to-hello_cargo/src/main.rs:15)
...
main (@main:12)
start (@start:639)

Does it auto-convert? Is it "optimized" by the compiler? What's the difference to Vec::as_slice()?


Solution

  • It is called Deref coercion

    /// Vec<T> implements Deref as follows
    impl Deref for Vec<T> {
        type Target = &[T];
        fn deref(&self) -> &Self::Target;
    }
    
    // meaning you can call
    let vector: Vec<T> = ...
    let slice: &[T] = vector.deref();
    
    // Rust can call .deref() automatically whenever needed (coercion)
    

    You can read about it more here

    https://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/share/doc/rust/html/book/first-edition/deref-coercions.html

    https://doc.rust-lang.org/std/ops/trait.Deref.html