8

When I try to compile this code:

pub struct Context<'a> {
    pub outer: Option<&'a mut Context<'a>>,
}

impl<'a> Context<'a> {
    pub fn inside(outer: &'a mut Context) -> Context<'a> {
        Context { outer: Some(outer) }
    }
}

I'm getting this error:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
 --> src/main.rs:7:9
  |
7 |         Context { outer: Some(outer) }
  |         ^^^^^^^
  |
note: first, the lifetime cannot outlive the lifetime 'a as defined on the impl at 5:1...
 --> src/main.rs:5:1
  |
5 | / impl<'a> Context<'a> {
6 | |     pub fn inside(outer: &'a mut Context) -> Context<'a> {
7 | |         Context { outer: Some(outer) }
8 | |     }
9 | | }
  | |_^
note: ...so that expression is assignable (expected Context<'a>, found Context<'_>)
 --> src/main.rs:7:9
  |
7 |         Context { outer: Some(outer) }
  |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: but, the lifetime must be valid for the anonymous lifetime #1 defined on the method body at 6:5...
 --> src/main.rs:6:5
  |
6 | /     pub fn inside(outer: &'a mut Context) -> Context<'a> {
7 | |         Context { outer: Some(outer) }
8 | |     }
  | |_____^
note: ...so that expression is assignable (expected &mut Context<'_>, found &mut Context<'_>)
 --> src/main.rs:7:31
  |
7 |         Context { outer: Some(outer) }
  |                               ^^^^^

Why this is happening?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Zac
  • 813
  • 10
  • 22
  • 2
    *(I'll put them in the question if anyone wants to see them).* — **Always** provide a [MCVE] (no "oh this is defined elsewhere but I won't tell you what it is) and include the complete error message. – Shepmaster Nov 11 '17 at 15:12

1 Answers1

5

This is because you haven't met the obligations that you require.

Due to lifetime elision, your code is equivalent to:

pub fn inside<'b>(outer: &'a mut Context<'b>) -> Context<'a>

Change your code to

pub fn inside(outer: &'a mut Context<'a>) -> Context<'a>

And it will compile.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • Thanks, it worked! I completely forgot about the lifetime parameter on the `outer` parameter – Zac Nov 11 '17 at 15:26
  • 1
    Nice trick: when facing such issues, putting the implicit lifetimes into the declarations simplifies reasoning, as it makes the issue immediately visible! – Nawaz Oct 07 '18 at 11:18