&'static str = "hello" -> the hello is stored in read only data section (rodata, inside the binary directly) and then the variable contains pointer and length that point to said rodata
&str = String::from("hello").as_str() -> the hello is stored in heap and the variable contains pointer and length that point to said heap
let a = [b"hello 1", b"hello 2"] &str = std::str::from_utf8(&buf) -> a is stored in stack, the str variable contains pointer and length that point to said stack
Now how about &'a str = "hello" ?
Aka it is a string literal but the lifetime is limited, the lifetime is a not static.
Is the actual data stored in read only data section (rodata) or stack? And then only the view (pointer and length) that has lifetime 'a?
Or both the actual data and the view (pointer and length) are stored in stack with lifetime 'a?
The syntactic lifetime marks like 'a in Rust don’t have any direct effects to program behavior. The compiler erases them after the borrow checker ran, their main purpose is to ensure memory safety, allowing API authors to express lifetime requirements, and then allowing the borrow checker to reject programs which might violate such requirements.
Another way to look at the concrete case in question would be as follows. If you consider literals such as "hello" to always be of type &'static str, then something like
fn foo<'a>() {
let variable: &'a str = "hello";
}
is really doing two things: (1) it takes "hello" of type &'static str, and then implicitly coerces it to the type &'a str via subtyping coercion, the result of which is still the same thing[1] at run-time (i.e. pointer & length, referring to rodata in the binary) [subtyping coercions are no-ops at runtime]; (2) it assigns the result of this coercion to the new variable.
For an introduction to subtyping with lifetimes in Rust, take a look at:
but now it has the new (slightly different) type &'a str in the eyes of the type checker and borrow checker ↩︎
@steffahn says it all, I just want to add, it's important to understand, the annotation specifiies the type of the variable, NOT the value: in a variable declaration, the type of the variable and the value need NOT be exactly the same, they can be coercible, subtyping coersion in this case, but there are other types of coercions in the language.
the type of a string literal value is always &'static str.
Generally true for literals like "hello" (though AFAIK it's not guaranteed that it won't put the data on the stack for a local variable, say). Note that you can also get a &'static str by leaking data, for example.
Probably the actual &str data is promoted and stored in the data section like a plain literal string. But you can put an array of bytes on the stack and end up with a &str pointing to the stack.
Note that Rust lifetimes like 'a generally correspond to the duration of a borrow, and not the entire liveness scope of the borrowed data or place.
That said, the liveness scope of a reference in particular usually corresponds to the lifetime of the borrow, due to how borrow checking works. But there are exceptions, and the compiler doesn't actually assign '_ lifetimes to liveness scopes.