I'm having a hard time understanding this lifetime issue; This is a simplified version of what I'm working on. The compiler says that cave
is being dropped while still borrowed, but this is confusing - where is cave
still being borrowed? After each call to has_echo()
, shouldn't the borrows be dropped?
pub trait Echo {
fn id(&self) -> i32;
}
#[derive(Debug, Default)]
struct RealEcho {
id: i32,
}
impl Echo for RealEcho {
fn id(&self) -> i32 {
self.id
}
}
pub trait EchoManager<'e, T: Echo + 'e> {
fn echo(&'e self, id: i32) -> Option<&T>;
}
struct RealEchoManager {
echos: Vec<RealEcho>,
}
impl<'e> EchoManager<'e, RealEcho> for RealEchoManager {
fn echo(&'e self, id: i32) -> Option<&RealEcho> {
self.echos.iter().find(|e| e.id() == id)
}
}
struct Cave<'a, T: Echo> {
echo_manager: Box<dyn EchoManager<'a, T>>,
}
impl<'a, T: Echo> Cave<'a, T> {
pub fn new(echo_manager: Box<dyn EchoManager<'a, T>>) -> Self {
Self { echo_manager }
}
pub fn has_echo(&'a self, id: i32) -> bool {
self.echo_manager.echo(id).is_some()
}
}
fn main() {
let echos = vec![RealEcho { id: 1 }, RealEcho { id: 2 }];
let manager = RealEchoManager { echos };
let cave = Cave::new(Box::new(manager));
let has_echo = cave.has_echo(1);
assert_eq!(has_echo, true);
let has_echo = cave.has_echo(2);
assert_eq!(has_echo, true);
let has_echo = cave.has_echo(3);
assert_eq!(has_echo, false)
}
Errors:
Compiling playground v0.0.1 (/playground)
error[E0597]: `cave` does not live long enough
--> src/main.rs:49:20
|
47 | let cave = Cave::new(Box::new(manager));
| ---- binding `cave` declared here
48 |
49 | let has_echo = cave.has_echo(1);
| ^^^^ borrowed value does not live long enough
...
57 | }
| -
| |
| `cave` dropped here while still borrowed
| borrow might be used here, when `cave` is dropped and runs the destructor for type `Cave<'_, RealEcho>`
For more information about this error, try `rustc --explain E0597`.
error: could not compile `playground` (bin "playground") due to 1 previous error