Rust Lifetime of reference should outlive function

Viewed 154

I have a little dummy parser, which uses the same &str during parsing:

struct Parser<'a>{
    r: &'a str,
    pos: usize
}

impl<'a, 'b: 'a> Parser<'a>{
    fn new(s: &'b str)->Parser<'a>{
        Parser{r: s, pos:0}
    }
    fn next(&'a self)->Parser<'a>{
        Parser{r: self.r, pos: self.pos + 1}
    }
    fn nnext(&'a self)->Parser<'a>{
        Parser{r: self.r, pos: self.pos + 2}
    }
    fn nnnext(&'a self)->Parser<'a>{
        return self.next().nnext()
    }
}

I would use it like this:

fn parse(s: &str){
    let parser = Parser::new(s);
    parser.nnnext();
}

I get the following error:

25 |         return self.next().nnext()
   |                -----------^^^^^^^^
   |                |
   |                returns a value referencing data owned by the current function
   |                temporary value created here

The reference is guaranteed to outlive all Parser methods. How must is annotate lifetimes to express this? Especially, why does nnnext not compile? It should be clear that the reference outlives self.next().nnext() call.

Thank you very much for any assistance. Hendrik

1 Answers

By using &'a self, you're conflating the lifetime of the parser with the lifetime of the string it refers to. There's no reason for that.

If you remove this constraint, there's no problem anymore:

struct Parser<'a>{
    r: &'a str,
    pos: usize
}

impl<'a> Parser<'a>{
    fn new(s: &'a str)->Parser<'a>{
        Parser{r: s, pos:0}
    }
    fn next(&self)->Parser<'a>{
        Parser{r: self.r, pos: self.pos + 1}
    }
    fn nnext(&self)->Parser<'a>{
        Parser{r: self.r, pos: self.pos + 2}
    }
    fn nnnext(&self)->Parser<'a>{
        return self.next().nnext()
    }
}

(I also removed the useless 'b)

Related