About clone of Box::<&mut u8>

In the following code , line A works , it is unexpected , because &mut u8 is not Clone. For the cloned one

  1. It has different semantic : it seems a Box::<u8>
  2. Seems an violation of the signature of fn clone(&self) -> Self;

How to explain this?

fn main() {
  let mut a = 0u8;
  let b = Box::new(&mut a);
  let c = b.clone();                  // A compile , unexpected
  println!("{}",size_of_val(&b));     // output is 8
  println!("{}",size_of_val(&c));     // output is 1
}

You're observing auto deref in action. You're actually cloning the u8, not the &mut u8.

The code desugars to the following:

fn main() {
    let mut a: u8 = 0u8;
    let b: Box<&'_ mut u8> = Box::new(&mut a);
    let c: u8 = <u8 as Clone>::clone(&b);
    println!("{}", size_of_val(&b));
    println!("{}", size_of_val(&c));
}

However, note that &b tells the compiler it can now insert however many & and * it wants until it finds something which compiles.

In this case, it does &**b.

Note that you can observe this fact in an isolated example:

struct Bar<'a>(&'a usize);

impl<'a> Deref for Bar<'a> {
    type Target = usize;
    fn deref(&self) -> &Self::Target {
        self.0
    }
}

fn foo(_: &usize) {}

let x = 0usize;
let val = Bar(&x);
// Fails:
// foo(val);
// Succeeds:
foo(&val);
// Succeeds:
foo(&*val);

[Playground]

3 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.