Yet another lifetime weirdness (data from `x` flows into `x` here)

I don't understand the error, is it just me?

these two types are declared with different lifetimes...

But only one is highlighted

...but data from `builder` flows into `builder` here

I don't see the problem, and how can the same variable have different lifetime?

error[E0623]: lifetime mismatch
  --> src/commands.rs:95:30
   |
51 |   builder: &mut FlatBufferBuilder
   |            ----------------------
   |            |
   |            these two types are declared with different lifetimes...
...
95 |           let rows = builder.create_vector(&[row]);
   |                              ^^^^^^^^^^^^^ ...but data from `builder` flows into `builder` here

Can you post the code this is from? It's hard to tell what's going on without knowing the context (like, where row is coming from.)

it's not easy to fully reproduce, there are a ton of dependencies, I've tried to best to extract

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=16a5d713e1d122aa93b6ea9a26a3e27c

FlatBufferBuilder<'fbb> has an 'fbb lifetime, and the & borrow has another one. I think you'll be ok if you introduce a named lifetime 'a and link the lifetime of builder's borrow and and of the underlying FlatBufferBuilder: builder: &'a mut FlatBufferBuilder<'a>.

Now the error makes way more sense, thanks!
I should be able to solve the situation with a bit of patience :slight_smile:

error[E0499]: cannot borrow `*builder` as mutable more than once at a time
  --> src/commands.rs:91:33
   |
46 | pub fn exec<'a>(
   |             -- lifetime `'a` defined here
...
91 |         while iterator.has_next(builder) {
   |                                 ^^^^^^^ mutable borrow starts here in previous iteration of loop
...
95 |           let rows = builder.create_vector(&[row]);
   |                                            ------ cast requires that `*builder` is borrowed for `'a`

I don't have much time to look at this myself right now, but that's a rather surprising suggestion! Normally &'a mut Foo<'a> is a bad idea, because the invariance of &mut forces the value to be mutably borrowed for the rest of its existence.

2 Likes

I believe that when that happens rustc is way better at guiding the user in the right direction than in the original situation.