-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Description
In rust borrowed constants have static lifetimes, even if the constants are simple literals in the middle of a function. For example, this compiles:
fn assert_static(_r: &'static u32) {}
fn main() {
assert_static(&1); // compiles
}
This works even in more involved situations, such as when the "literal" is a macro-generated array of structs whose fields are literals. (That's my actual use case, but I'll refer to the simple case of just having a u32
for simplicity.)
The problem is that it no longer works if the value is returned by a const fn
:
const fn inc(n: u32) -> u32 {
n + 1
}
fn assert_static(_r: &'static u32) {}
fn main() {
assert_static(&1);
assert_static(&inc(1)) // doesn't compile
}
error[E0716]: temporary value dropped while borrowed
--> src/main.rs:9:20
|
9 | assert_static(&inc(1)) // doesn't compile
| ---------------^^^^^^-
| | |
| | creates a temporary which is freed while still in use
| argument requires that borrow lasts for `'static`
10 | }
I would expect (or rather wish) for the latter code to compile since the former did. Note that, since const
and static
are static
, it is possible to work around it by creating an explicit const
or static
inbetween. For example, all of these compile:
fn main() {
assert_static(&1);
{
const TMP: u32 = inc(1);
assert_static(&TMP);
}
{
static TMP: u32 = inc(1);
assert_static(&TMP);
}
assert_static({
const TMP: u32 = inc(1);
&TMP
});
assert_static({
static TMP: u32 = inc(1);
&TMP
});
}
While a workaround is available, it is not always obvious. Also it would be much nicer not to have to introduce all the temporary constants/statics, especially in code that calls several different const fns.