0
use std::io::Cursor;
use bytes::BytesMut;

struct Parser<'a> {
    stream: &'a mut Cursor<&'a [u8]>
}

fn parse<'a>(buf:&'a mut Cursor<&'a [u8]>) -> Option<(usize, &'a str)> {
    None
}

impl<'a> Iterator for Parser<'a> {
type Item = (usize, &'a str);
    fn next(&mut self) -> Option<Self::Item> {
        parse(self.stream)
    }

}

fn main() {
    let mut buf = BytesMut::with_capacity(1024);
    let mut cursor = Cursor::new(&buf[..]);
    let mut parser = Parser {stream: &mut cursor};
}

Playground link

Basically, I want to parse a buf without copy but failed to compile. Could anyone help? Much appreciated!

Error message:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'a in function call due to conflicting requirements
  --> src/main.rs:15:9
   |
15 |         parse(self.stream)
   |         ^^^^^^^^^^^^^^^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 14:5...
  --> src/main.rs:14:5
   |
14 |     fn next(&mut self) -> Option<Self::Item> {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...so that reference does not outlive borrowed content
  --> src/main.rs:15:15
   |
15 |         parse(self.stream)
   |               ^^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 12:6...
  --> src/main.rs:12:6
   |
12 | impl<'a> Iterator for Parser<'a> {
   |      ^^
note: ...so that the expression is assignable
  --> src/main.rs:15:15
   |
15 |         parse(self.stream)
   |               ^^^^^^^^^^^
   = note: expected `&mut std::io::Cursor<&[u8]>`
              found `&mut std::io::Cursor<&'a [u8]>`
Aplet123
  • 33,825
  • 1
  • 29
  • 55
  • Does this answer your question? [How do I write an iterator that returns references to itself?](https://stackoverflow.com/questions/30422177/how-do-i-write-an-iterator-that-returns-references-to-itself) – Aplet123 Apr 20 '21 at 23:17
  • 1
    Why is `stream` a reference? why not make it a `Cursor` directly? Binding a reference to mutable cursor and its contents to the same lifetime is likely to cause problems. – kmdreko Apr 21 '21 at 04:02
  • @kmdreko because a top struct creates a cursor based on BytesMut and it asks others to do the parsing work – Walk Anywhere Apr 23 '21 at 14:18
  • @Aplet123, thanks, but it does not... – Walk Anywhere Apr 23 '21 at 14:20

1 Answers1

0

You need a different lifetime for what is inside the cursor:

struct Parser<'a, 'b> {
    stream: &'a mut Cursor<&'b [u8]>,
}

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=0c36650015dc7fb4d425794fca934242

The reason is to do with the fact that your stream is a mutable reference. If you make it immutable, everything works.

I could not explain why better than Ryan Levick did in his video he made on lifetimes.

That video should be one of the recommended learning materials

Hadus
  • 1,551
  • 11
  • 22