I'm puzzled by this error. According to my code, bytes is either returned, so the problematic code is not reached, or it's dropped, so it shouldn't matter. Why doesn't the borrow checker accept this code, and how might I modify it so it would compile?
Compiling playground v0.0.1 (/playground)
error[E0502]: cannot borrow `*data` as mutable because it is also borrowed as immutable
--> src/main.rs:51:5
|
41 | fn read_helper<'a>(data: &'a mut BufList, temp: &'a mut Vec<u8>, len: usize) -> Result<&'a [u8], Error> {
| -- lifetime `'a` defined here
42 | {
43 | let bytes = data.peek_bytes().ok_or(Error::EOF)?;
| ----------------- immutable borrow occurs here
...
46 | return Ok(&bytes[..len]);
| ----------------- returning this value requires that `*data` is borrowed for `'a`
...
51 | data.read_bytes(temp, len)?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
For more information about this error, try `rustc --explain E0502`.
error: could not compile `playground` due to previous error
use std::cell::Cell;
#[derive(Debug)]
pub struct BufList {
buffer: Vec<u8>,
pos: Cell<usize>,
}
// This is contrived, just to make this a self-contained example
impl BufList {
pub fn new() -> Self {
BufList { buffer: Vec::new(), pos: Cell::new(0) }
}
pub fn peek_bytes(&self) -> Option<&[u8]> {
if self.pos.get() < self.buffer.len() {
Some(&self.buffer[self.pos.get()..])
} else {
None
}
}
pub fn advance(&self, len: usize) {
self.pos.set(self.pos.get() + len);
}
pub fn read_bytes(&mut self, vec: &mut Vec<u8>, len: usize) -> Result<(), Error> {
if self.pos.get() + len <= self.buffer.len() {
vec.extend_from_slice(&self.buffer[self.pos.get()..self.pos.get() + len]);
Ok(())
} else {
Err(Error::EOF)
}
}
}
#[derive(Debug)]
pub enum Error {
EOF,
}
fn read_helper<'a>(data: &'a mut BufList, temp: &'a mut Vec<u8>, len: usize) -> Result<&'a [u8], Error> {
{
let bytes = data.peek_bytes().ok_or(Error::EOF)?;
if len <= bytes.len() {
data.advance(len);
return Ok(&bytes[..len]);
}
}
temp.clear();
data.read_bytes(temp, len)?;
Ok(&temp[..])
}
fn main() {
let mut buf_list = BufList::new();
buf_list.buffer = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let mut temp = Vec::new();
let len = 5;
match read_helper(&mut buf_list, &mut temp, len) {
Ok(data) => println!("Data: {:?}", data),
Err(e) => println!("Error: {:?}", e),
}
}