1

With reference to this question, I tried to compile it with some changes:

pub trait GetIter<'a> {
    type IntoIter: IntoIterator<Item = usize>;
    fn get_iter(&'a self) -> Self::IntoIter;
}

pub struct NoRef<T> {
    inner: T,
}

impl<'a, T: 'a> GetIter<'a> for NoRef<T>
where
    &'a T: GetIter<'a>,
{
    type IntoIter = Vec<usize>;
    fn get_iter(&'a self) -> Vec<usize> {
        (&self.inner).get_iter();
        vec![]
    }
}

It gives the following error:

error[E0716]: temporary value dropped while borrowed
  --> src/lib.rs:16:9
   |
10 | impl<'a, T: 'a> GetIter<'a> for NoRef<T>
   |      -- lifetime `'a` defined here
...
16 |         (&self.inner).get_iter();
   |         ^^^^^^^^^^^^^------------ temporary value is freed at the end of this statement
   |         |
   |         creates a temporary value which is freed while still in use
   |         argument requires that borrow lasts for `'a`

I am not getting what "temporary value" it is referring to here?

soupybionics
  • 4,200
  • 6
  • 31
  • 43
  • Not sure where you got confused but the compiler tells you exactly what temporary value it's talking about, `(&self.inner)`, indicated by the `^` below it – cafce25 Apr 15 '23 at 06:08
  • As you've written your mre it's a bit unclear why one would ever implement `GetIter` for `&T` instead of `T` since all methods take `T` by reference anyways, so just `impl GetIter for T` with the bound `T: GetIter` should be enough as far as I can tell. – cafce25 Apr 15 '23 at 06:10
  • https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=0eb11b24e970d289ad20281a29eb55b8 – Stargateur Apr 15 '23 at 06:20

1 Answers1

0

The problem is that you are merging all the logically different lifetimes into a single one. But let's go step by step.

In the statement (&self.inner).get_inner(), you are creating a temporary expression (self.inner), and then take its borrow. As per the documentation, the borrow will only last up to the end of the current statement, that is, to the end of (&self.inner).get_inner(). On the other hand, get_inner requires a borrow &'a self, where 'a is the same lifetime as basically everything else in your example, including for how much time you borrowed &self in the get_inner implementation. This means that enforce 'a to be at most that statement or, to put it otherwise (as the Rust compiler), the actual lifetime or the borrow of your temporary should be at least 'a, but that's not possible.

jthulhu
  • 7,223
  • 2
  • 16
  • 33