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.
Local variables cannot be returned by reference.
The return statement should not return a pointer that has the address of a local variable ( sum ) because, as soon as the function exits, all local variables are destroyed and your pointer will be pointing to someplace in the memory that you no longer own.
C++ How to return a local variable from a function? But there is a way to access the local variables of a function using pointers, by creating another pointer variable that points to the variable to be returned and returning the pointer variable itself.
Functions can be declared to return a reference type. There are two reasons to make such a declaration: The information being returned is a large enough object that returning a reference is more efficient than returning a copy. The type of the function must be an l-value.
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 to any literal that is composed solely of literals:
fn promote_integer() -> &'static i32 { &42 }
fn promote_float() -> &'static f64 { &42.42 }
fn promote_str() -> &'static str { "Hello World!" }
struct Foo(char); fn promote_struct() -> &'static Foo { &Foo('x') }
Beyond literals, this also works for a tiny number of functions in the standard library, but these were likely a mistake. Deciding on if the result of arbitrary const
functions can be automatically promoted to static
is still an open topic.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With