Reputation: 21
Compilation error when calling a function defined in trait that returns a reference type: borrowed value does not live long enough
Here is a sample reproduction of my problem:
use std::rc::Rc;
trait Bundle<'a> {
fn id(&'a self) -> &'a str;
}
struct Demo {
id: String,
}
impl<'a> Bundle<'a> for Demo {
fn id(&'a self) -> &'a str {
&self.id
}
}
fn x(bundle: Rc<dyn Bundle<'_>>, file: &str) -> String {
let id = bundle.id();
format!("bundle/{}/{}", id, file)
}
fn main() {
let demo = Rc::new(Demo {
id: String::from("demo"),
});
println!("{}", x(demo as Rc<dyn Bundle>, "hello.txt"));
}
The compiler gives the following error:
error[E0597]: `bundle` does not live long enough
--> src/main.rs:18:14
|
17 | fn x(bundle: Rc<dyn Bundle<'_>>, file: &str) -> String {
| ------ has type `Rc<dyn Bundle<'1>>`
18 | let id = bundle.id();
| ^^^^^^^^^^^
| |
| borrowed value does not live long enough
| argument requires that `bundle` is borrowed for `'1`
19 | format!("bundle/{}/{}", id, file)
20 | }
| - `bundle` dropped here while still borrowed
I'm a newbie and in my understanding, after the format!()
statement at line 19, I no longer borrow bundle
. So why rustc thinks it "still borrowed"?
Upvotes: 1
Views: 53
Reputation: 21
I made a stupid mistake. Thanks to the answer given by @jmb in the comments section, I now changed the code to the following to fixup it:
use std::rc::Rc;
trait Bundle {
fn id(&self) -> &str;
}
struct Demo {
id: String,
}
impl Bundle for Demo {
fn id(&self) -> &str {
&self.id
}
}
fn x(bundle: Rc<dyn Bundle>, file: &str) -> String {
let id = bundle.id();
format!("bundle/{}/{}", id, file)
}
fn main() {
let demo = Rc::new(Demo {
id: String::from("demo"),
});
println!("{}", x(demo as Rc<dyn Bundle>, "hello.txt"));
}
BTW, I have also tried to continue using the explicit lifecycle. The generic argument should be on the function and not on the trait.
trait Bundle {
fn id<'a>(&'a self) -> &'a str;
}
Upvotes: 1