I have a lifetime/borrowing error from the Rust compiler that I can't get my head around. The problem seems to be that Rust assumes that when an argument is passed to a function that returns a reference to a static value, the argument reference must also be static.
#[derive(Debug)]
struct TestThingy<'a> {
label: &'a str,
}
const TEST_VALUES: [TestThingy; 3] = [
TestThingy { label: "one" },
TestThingy { label: "two" },
TestThingy { label: "three" },
];
pub fn value_for_num(num: &str) -> Option<&'static TestThingy> {
TEST_VALUES.iter().find(|value| value.label == num)
}
pub fn test_out_thingy() {
let tmp_val = String::from("two");
if let Some(test_thingy) = value_for_num(&tmp_val) {
println!("test_thingy: {:?}", test_thingy);
}
}
fn main() {
test_out_thingy();
}
Rust errors with: error[E0597]: `tmp_val` does not live long enough
- E0597 refers to when a value gets dropped whilst its still borrowed, which isn't happening here - I don't know how to convince Rust of that though.
The idea behind this code, for more context, is it's a lookup mechanism for compile-time/static config (in my codebase they are Syntax
values, matched on the basis of a provided filename &str
). So the provided argument genuinely does not live as long as the static config, but I don't understand why that's a problem. The returned value doesn't/can't contain the argument as a reference, so I'm super unclear why this borrowing error is happening.
The problem lies in the function signature of value_for_num
.
You indicate that you return a static reference to a TestThingy
but have no indication what kind of references that TestThingy<'x>
might hold. Thus the compiler assumes that the unspecified input reference lifetime may be tied to the unspecified output lifetime of references inside the TestThingy
.
i.e. the compiler sees this:
pub fn value_for_num<'a>(num: &'a str) -> Option<&'static TestThingy<'a>>
If you change the signature to specify that the contained references are also static then it compiles.
pub fn value_for_num(num: &str) -> Option<&'static TestThingy<'static>>
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