Follow up lifetime puzzle

Sorry to bother you again ,

This is a follow up of Lifetime puzzle (hidden type captures) where @alice defined a new 'b and put it on the self and the MutexGuard, meaning that both must have the same lifetime. What is 'a then?

I'm asking because adding a new field to the mix broke everything again:

EDIT: correct playground link

Did you post the wrong playground? Note that it seems you misunderstood my last comment in that thread — the <'b: 'a> thing seems like it solves the issue, but doesn't actually solve it because it does not allow 'b to be different from 'a.

Thank you again for you answer Alice :slight_smile:

Dumb me, yes I pasted the same again. Here is the correct one:

And I'm going to edit my first post

You left out the lifetime on the MyEndpoint type. The return type should be

MyEndpoint<'a, MutexGuard<'b, MyRegistrar<'a>>, MutexGuard<'b, MyIssuer<'a>>>

for this to compile. The issue is that the bounds on the MyEndpoint struct failed to type-check

struct MyEndpoint<'a, T: MyTrait<'a>, G: MyTrait<'a>>
//                    ^ this, and     ^ this

Since you had not specified the lifetime, it was elided to some other lifetime than 'a, and although T may implement MyTrait<'a>, it didn't implement MyTrait<'b>.

1 Like

So if I understand properly, by forgetting the lifetime for MyEndpoint, it has to verify both 'a and 'b hence the error?

Thank you very much again. I need to buy you a [beer|cookie|whatever-you-like-to-eat-or-drink] one day :slight_smile:

1 Like

Well, not both 'a and 'b. It's just that leaving it out was equivalent to picking 'b, which was the wrong choice.

1 Like

So there's room for improvement compiler side on this specific case?

No, there is a lot of value in having the compiler be consistent about what it does when it elides lifetimes.

I see :slight_smile: But I can't help but think that the error message didn't help me to understand the issue :-/

How was your analysis process to understand what was going on? (Yes, I'm trying to "steal" some of your tremendous knowledge :D)

My thought process was the following:

  1. It's complaining about "expected MyTrait<'b>, found MyTrait<'_>". This means that we have a lifetime mismatch, and the underscore means that we have not named the lifetime.
  2. What's MyTrait doing here? It doesn't show up on the method anywhere.
  3. Oh, it's because the MyEndpoint requires it.
  4. In particular, MyEndpoint requires MyTrait with the same lifetime as the one directly on the struct.
  5. What lifetime was used in that spot in our method? Ah, it's missing. Add 'a and see that it compiles.

With most of my time spent in step two.

1 Like

I think that knowing the code misled me but I was missing the "the underscore means that we have not named the lifetime" part. In my knowledge of the code, all the lifetimes were filled so it could have been ages before I realise that I forgot 2 chars… ^^'

Thank you very much!

1 Like