Hatatister
Hatatister

Reputation: 1052

Rust Lifetime of reference should outlive function

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

Upvotes: 4

Views: 802

Answers (1)

Denys S&#233;guret
Denys S&#233;guret

Reputation: 382092

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)

Upvotes: 4

Related Questions