1

I have some code that preprocesses some data; a part of it is truncating a mutable slice but the borrow checker doesn't seem to like it, for an odd reason. Here's a minimal example:

struct C<'a>(&'a mut [u8]);

impl<'a> C<'a> {
    fn f<'b>(&'b mut self) where 'a: 'b {
        self.0 = &mut self.0[..]
    }
}

Playground

Just to clarify the lifetimes situation: in the actual code I have some request data, and the code that handles requests calls the mentioned preprocessing function. The idea is that 'a is the lifetime of the request, and 'b is the tiny lifetime of the mut borrow into this function. So while flipping the bounds into 'b: 'a (or only having 'a) satisfies the borrow-checker here, it's not what I want (and makes the mut borrow longer than it should be, so it merely makes the borrow checker angry later at call-site).

The error message I'm getting from this is: "cannot infer an appropriate lifetime for borrow expression due to conflicting requirements", and one side of the conflict is what's tripping me: it complains that the borrow of &mut self.0 "cannot outlive the lifetime 'b [..] so that reference does not outlive borrowed content". But the borrowed content has lifetime 'a, so why shouldn't it be able to outlive 'b?

MasterMastic
  • 20,711
  • 12
  • 68
  • 90
  • 1
    Definitely a non-trivial solution to what seems a trivial problem. The application here looks like: `self.0 = &mut std::mem::replace(&mut self.0, &mut [])[..];` It's more complicated than it looks because indexing can *theoretically* panic (even though it can't in this case) and then it would be unclear whether `self.0` were invalidated or not. `mem::replace` fixes this by temporarily substituting a dummy value (an empty slice). This is sometimes called the Indiana Jones trick. – trent Mar 20 '21 at 13:55

0 Answers0