Mutable reference to owned value?

Can someone explain how this code is legal? It seems the &mut buffer is converted to io::Write instance (owned?) and not a reference here when passed from main to write_buffer. Does ownership with traits work differently? Also dropping the io::Write instance buffer in the method does not have any impact (seems logical as its just a mutable reference and not actually an owned value. But from syntax, it looks like an owned value. Is there a different syntax to move values and have trait bounds on such value?

#![allow(unused_variables)]

use std::io;

fn write_buffer<T>(buffer: T) where T: io::Write {
    // let data: Vec<u8> = vec![1, 2, 3];
    // buffer.write(data.as_slice());
    drop(buffer);
}

fn main() {
    let mut buffer: Vec<u8> = vec![1];
    println!("{:?}", buffer);
    write_buffer(&mut buffer);
    println!("{:?}", buffer);
}

(Playground)

Output:

[1]
[1]

This is incorrect, since io::Write is implemented for &mut W when W: Write. So, when you invoke write_buffer, it is invoked with T = &mut Vec<u8>.

2 Likes

Note: references are values too, thus they are subject too all the same ownership rules qs every other value.

2 Likes

What is getting dropped by the drop function then ? if drop does drop the buffer then the next println buffer should have a null value which is illegal in rust am i missing something ?

&mut Vec<u8> is dropped. References themselves are type, so the T here is &'a mut Vec<u8>. And unique references doesn't have drop glue, so it only ends the borrowing and does nothing on runtime.

Oh i see now so it does not deref the the value it receives just drops the variable which is then going through self drop implementation is that correct ?