Hi, I've been struggling with lifetimes for a while, I created the minimal code example that reproduces the issue I have in my real application. Please advise how to make this work.
struct OneString {
s: String,
}
trait TwoStrMaker<'a, 'b> {
fn make(&'a self, s: &'b str) -> TwoStr<'a, 'b>;
}
impl<'a, 'b> TwoStrMaker<'a, 'b> for OneString {
fn make(&'a self, s: &'b str) -> TwoStr<'a, 'b> {
TwoStr {
onestr: &self.s,
oneanotherstr: s,
}
}
}
type Boxed<'a, 'b> = Box<dyn TwoStrMaker<'a, 'b>>;
struct OneAnotherString {
s: String,
}
impl OneAnotherString {
fn combine<'a, 'b>(&'a self, twostrmaker: &'b Boxed<'b, 'a>) -> TwoStr<'b, 'a> {
twostrmaker.make(&self.s)
}
}
#[derive(Debug)]
#[allow(dead_code)]
struct TwoStr<'a, 'b> {
onestr: &'a str,
oneanotherstr: &'b str,
}
fn main() {
// this is important that `twostrmaker` is a boxed trait object
// in the real application I have a Vec of varios such objects
let twostrmaker: Boxed<'_, '_> = Box::new(OneString {
s: "foo".to_string(),
});
let oneanotherstring = OneAnotherString {
s: "bar".to_string(),
};
let twostr = oneanotherstring.combine(&twostrmaker);
dbg!(twostr);
}
wich gives an error
error[E0597]: `oneanotherstring` does not live long enough
--> src/main.rs:43:18
|
43 | let twostr = oneanotherstring.combine(&twostrmaker);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
...
46 | }
| -
| |
| `oneanotherstring` dropped here while still borrowed
| borrow might be used here, when `twostrmaker` is dropped and runs the destructor for type `Box<dyn TwoStrMaker<'_, '_>>`
|
= note: values in a scope are dropped in the opposite order they are defined
error[E0597]: `twostrmaker` does not live long enough
--> src/main.rs:43:43
|
43 | let twostr = oneanotherstring.combine(&twostrmaker);
| ^^^^^^^^^^^^ borrowed value does not live long enough
...
46 | }
| -
| |
| `twostrmaker` dropped here while still borrowed
| borrow might be used here, when `twostrmaker` is dropped and runs the destructor for type `Box<dyn TwoStrMaker<'_, '_>>`
I can't really understand what holds these borrows, if this is the twostr
why isn't it dropped before anything else? Please help
PS: for me this is important that the types remain as they are in this example. I hope this is possible to fix only by providing correct lifetimes and possibly changing the order in which objects are instantiated.