Why can I return a reference to a local literal but not a variable?

  • A+
Category:Languages

Why does this code compile?

fn get_iter() -> impl Iterator<Item = i32> {     [1, 2, 3].iter().map(|&i| i) }  fn main() {     let _it = get_iter(); } 

[1, 2, 3] is a local variable and iter() borrows it. This code should not compile because the returned value holds a reference to a local variable.


In your example, [1, 2, 3] is not treated as local variable, but as static one!

Let's take a look at this code:

fn foo() -> &'static [i32] {     &[1, 2, 3] } 

This works!

Some time ago, RFC 1414: Rvalue Static Promotion was merged: "Promote constexpr rvalues to values in static memory instead of stack slots". This means that basically all literals you write can live forever. Thus, things like let _: &'static i32 = &42; also work!

If we avoid using a literal array, we can see the expected error:

fn bar() -> impl Iterator<Item = i32> {     vec![1, 2, 3].iter().map(|&i| i) } 

Here we get the "v does not live long enough" error.

This isn't limited to integers or arrays; it applies broadly:

fn promote_integer() -> &'static i32 {     &42 }  fn promote_float() -> &'static f64 {     &42.42 }  fn promote_char() -> &'static char {     &'c' } 

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: