1
votes
pub struct FooStruct<'a> {
  pub bars: Vec<&'a str>,
}

pub trait FooTrait<'a> {
  fn getBars(&self) -> &'a Vec<&'a str>;
}

impl<'a> FooTrait<'a> for FooStruct<'a> {
  fn getBars(&self) -> &'a Vec<&'a str> {
    &self.bars // cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
  }
}

Run it: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=3211c32dd5b9244ff91777f1820ffed5

I do not understand where the requirement conflict comes from. Afaik there is no conflict since everything lives as long as the FooStruct lives.

1
'a might be longer than the lifetime of the FooStruct. Then it would be unsound to have a &'a Vec<_> because the Vec would not last for the entire 'a.trentcl

1 Answers

3
votes

Let's take it apart:

pub struct FooStruct<'a> {
  pub bars: Vec<&'a str>,
}

FooStruct holds a container containing string slices with lifetime 'a. The container's lifetime corresponds to the lifetime of FooStruct.

pub trait FooTrait<'a> {
  fn getBars(&self) -> &'a Vec<&'a str>;
}

FooTrait wants getBars to return a reference to a container holding string slices with lifetime 'a. The lifetime of the returned reference should be 'a, too.

impl<'a> FooTrait<'a> for FooStruct<'a> {
  fn getBars(&self) -> &'a Vec<&'a str> {
    &self.bars
  }
}

Here, getBars returns a reference to self.bars which is a container of string slices with lifetime 'a. So far, so good.

  • However, what is the lifetime of &self.bars? It corresponds to the lifetime of self (i.e. the respective FooStruct).
  • What is the lifetime of self? It is 'self (an implicit lifetime).

However, the FooTrait requires that the returned reference lifetime is 'a, so that does not match FooTrait's declaration.

One solution is to separate the lifetimes in FooTrait:

pub trait FooTrait<'a> {
  fn getBars<'s>(&'s self) -> &'s Vec<&'a str>;
}

impl<'a> FooTrait<'a> for FooStruct<'a> {
  fn getBars<'s>(&'s self) -> &'s Vec<&'a str> {
    &self.bars
  }
}