Do immutable references implement Copy?

In one of my online courses I demonstrate to students that move closures take ownership of the variables they capture, so they cannot be used outside the closure after the closure has been created, but an interesting typo uncovered a behavior I didn't expect:

let s = "🍓"; // oops, I meant to have .to_string() on that

let f = move || {
    println!("{}", s);

f(); // prints 🍓

println!("{}", s); // unexpectedly works 

Even though I forgot to create an actual String with .to_string(), I would have expected s (the reference variable itself, not the static value it's pointing to) to have been moved into the closure. Why was it (apparently) not moved?

I verified that this seems to be true of immutable references in general, since this also works fine:

struct Hello {}

fn main() {
    let hello = Hello {};
    let hello2 = &hello;

    let f = move || {
        println!("{:?}", hello2);


    println!("{:?}", hello2);

So...why does this work? Do immutable references implement Copy (ie so the wide pointer itself gets copied under the hood)? Or is there some other reason that I'm not understanding?

From Copy trait documentation

impl<'_, T> Copy for &'_ T where
    T: ?Sized, 

// Shared references can be copied, but mutable references cannot!


Of course shared references implement Copy. Not only that explicitly written in the documentation, it's hard to imagine using .clone() to copy them!

Move and copy do the exact same thing: memcpy. The only question is whether the old value is still usable or not. Shared references exist for, well, sharing thus it makes perfect sense for the old value to be usable.

1 Like

Excellent, thank you! I should have thought to look at the documentation for the Copy trait! :man_facepalming: :laughing: (I was searching for immutable references...and obviously that brought up way too much stuff).

It's also listed as the first implemented trait in the page for references.


I obviously need to avoid posting questions first thing after waking up! I should have been able to find this out by myself! :blush: