Cannot use BufRead.consume()


I’m trying to use BufRead.fill_buf()/consume().

My idea is this: if buffer contains enough bytes, I can read from contiguous memory area which is very fast. Otherwize I have to deal with buffer refills.

(In this example I’m reading bytes until nonzero, but actually I need to read varint).

So, code should look like this:

// read byte-after-byte
fn read_slow(r: &mut BufRead) -> io::Result<u32> {
    let mut count = 0;
    loop {
        let mut buf = [0; 1];
        try!(r.read_exact(&mut buf));
        if buf[0] != 0 {
            return Ok((count));
        count += 1;

fn read(r: &mut BufRead) -> io::Result<u32> {
    let buf = try!(r.fill_buf());
    // fast path
    let mut count = 0;
    for &c in buf {
        if c != 0 {
            drop(buf); // does not help
            r.consume(count as usize); // does not work
            return Ok((count));
        count += 1;
    // does not work either

It does not work. Rust does not allow me to call consume because buf is borrowed. And there’s no easy was to just unborrow it even if I don’t need it anymore.

As far as I understand, the problem is with lexical borrowing. Is it going to fixed any time soon?

Or maybe I’m missing some obvious workaround?



Will something like this work?


@matklad thanks!


Thanks for rust-protobuf! Curiously enough, I’ve myself written the code to extract a leading varint from buffer (I was unable to fully reuse rust-protobuf implementation, because buffers were used in async context). It is ugly, slow and quite probably wrong, but here it is, just in case: