patternrustMajor
Why can I return a reference to a local literal but not a variable?
Viewed 0 times
literalreturnwhyvariablenotcanbutreferencelocal
Problem
Why does this code compile?
fn get_iter() -> impl Iterator {
[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.Solution
In your example,
Let's take a look at this code:
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
If we avoid using a literal array, we can see the expected error:
Here we get the "
This isn't limited to integers or arrays; it applies broadly to any literal that is composed solely of literals:
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
[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 {
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.Code Snippets
fn foo() -> &'static [i32] {
&[1, 2, 3]
}fn bar() -> impl Iterator<Item = i32> {
vec![1, 2, 3].iter().map(|&i| i)
}fn promote_integer() -> &'static i32 {
&42
}fn promote_float() -> &'static f64 {
&42.42
}fn promote_str() -> &'static str {
"Hello World!"
}Context
Stack Overflow Q#50345139, score: 68
Revisions (0)
No revisions yet.