Why string literals does not make a variable (s1) invalidated when moved to another variable?

I am reading “what-is-ownership” part of The Rust Programming Language.

fn main() {
    let s1 = String::from("Hello, world!");
    let s2 = s1;

    println!("The value of a is {}", s1);
    println!("The value of a is {}", s2);
}

In order to prevent double free error, s1 is invalidated and its value has been moved to s2.
So the above code does not compile.
I can understand this.
But look at this code:

 fn main() {
    let s1 = "Hello, world!";
    let s2 = s1;

    println!("The value of a is {}", s1);
    println!("The value of a is {}", s2);
}

It compiles without any issue, and runs well.
Why string literals does not make a variable (s1) invalidated when moved to another variable?

When I continue to read, the answer seems to present itself.

Stack-Only Data: Copy

](https://doc.rust-lang.org/stable/book/ch04-01-what-is-ownership.html#stack-only-data-copy)

There’s another wrinkle we haven’t talked about yet. This code using integers, part of which was shown in Listing 4-2, works and is valid:

let x = 5;
let y = x;

println!("x = {}, y = {}", x, y);

But this code seems to contradict what we just learned: we don’t have a call to clone , but x is still valid and wasn’t moved into y .

The reason is that types such as integers that have a known size at compile time are stored entirely on the stack, so copies of the actual values are quick to make. That means there’s no reason we would want to prevent x from being valid after we create the variable y . In other words, there’s no difference between deep and shallow copying here, so calling clone wouldn’t do anything different from the usual shallow copying and we can leave it out.

Hi, your second example compiles because of a copy but not a deep one, just a pointer copy.
Everything is clear If you add types to your example:

fn main() {
    let s1: &str = "Hello, world!";
    let s2: &str = s1;

    println!("The value of a is {}", s1);
    println!("The value of a is {}", s2);
}

This is explained later in the chapter in 4.3.

Just in case you can always check the type of a variable using:

let _: () = variable;
1 Like