Rust lifetime mismatch - 'a does not necessarily outlive lifetime as defined here
I'm running into lifetime issues when trying to move borrowed data between structs. At a high level I'd like to do something like:
- read a yml file into a string buffer
- deserialize that into a struct using
from_str - create a different struct from that same borrowed data
- write that out to a file
Here's a sample implementation of what I built that gives the lifetime error:
use serde::{Serialize, Deserialize};
#[derive(Deserialize, Debug, Serialize)]
pub struct Foo<'a> {
name: &'a str
}
impl<'a> Foo<'a> {
pub fn new(name: &'a str) -> Self {
Self { name }
}
}
#[derive(Deserialize, Debug, Serialize)]
pub struct Bar<'a> {
name: &'a str
}
impl<'a> Bar<'a> {
pub fn new(name: &'a str) -> Self {
Self { name }
}
}
pub trait Visitor {
type Value;
fn visit_table_borrowed<'a>(&mut self, t: &'a Foo<'a>) {
let _ = t;
}
}
pub trait DataBorrowed {
fn accept(&self, visitor: &mut V);
}
impl<'a> DataBorrowed for Foo<'a> {
fn accept(&self, visitor: &mut V) {
visitor.visit_table_borrowed(self)
}
}
impl<'a> Visitor for Bar<'a> {
type Value = Bar<'a>;
fn visit_table_borrowed(&mut self, t: &'a Foo<'a>) {
self.name = t.name;
}
}
impl<'a> From> for Bar<'a> {
fn from(dt: Foo<'a>) -> Self {
let mut table = Bar::new("bar");
dt.accept(&mut table);
table
}
}
fn main() {
let f = Foo::new("foo");
let b: Bar = Bar::from(f);
}
The error:
error[E0308]: method not compatible with trait
--> src/main.rs:49:5
|
49 | fn visit_table_borrowed(&mut self, t: &'a Foo<'a>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
|
= note: expected signature `fn(&mut Bar<'a>, &'a Foo<'a>)`
found signature `fn(&mut Bar<'a>, &'a Foo<'a>)`
note: the lifetime `'a` as defined here...
--> src/main.rs:49:5
|
49 | fn visit_table_borrowed(&mut self, t: &'a Foo<'a>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...does not necessarily outlive the lifetime `'a` as defined here
--> src/main.rs:47:6
|
47 | impl<'a> Visitor for Bar<'a> {
| ^^
For more information about this error, try `rustc --explain E0308`.