Search code examples
enumsrustsignature

Specify lifetime for enum as return type


I can't figure out the correct way to specify the lifetime for the return type of get_best_slide which happens to be an Enum. This enum keeps reference to either one of best_h or best_v.

It looks a lot like the longest function example from the official doc except the return type is an Enum.

pub enum Image {
    Horizontal { image_id: usize },
    Vertical { image_id: usize },
}

pub enum Slide<'a> {
    H { h: &'a Image },
    V { v: &'a Image, other_v: &'a Image },
}

fn get_best_slide<'a>(
    best_score_h: usize,
    best_h: Option<&'a Image>,
    best_score_v: usize,
    best_v: Option<(&'a Image, &'a Image)>,
) -> &'a Option<Slide> {
    match (best_h, best_v) {
        (None, None) => None,
        (Some(h), None) => Some(Slide::H { h }),
        (None, Some((v0, v1))) => Some(Slide::V { v: v0, other_v: v1 }),
        (Some(h), Some((v0, v1))) => {
            if best_score_h >= best_score_v {
                Some(Slide::H { h })
            } else {
                Some(Slide::V { v: v0, other_v: v1 })
            }
        }
    }
}

compiler is not happy:

error[E0106]: missing lifetime specifier
  --> src/main.rs:16:17
   |
16 | ) -> &'a Option<Slide> {
   |                 ^^^^^ expected lifetime parameter
   |
   = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `best_h` or `best_v`

Maybe the lifetime parameter I specified is not at the right place?

  • &'a Option<Slide> looks wrong
  • I also tried Option<&'a Slide> (compiler complains all the same)

Solution

  • It expects lifetime parameter for Slide, you'll need to set it explicitly

     -> Option<Slide<'a>> 
    

    The difference is :

    • &'a Option<Slide> means that i'll borrow Option<Slide> for the lifetime 'a,
    • Option<Slide<'a>> means that i'll create Slide in lifetime 'a so the inner operations can use this lifetime explicitly.