I have a simple parser that can be distilled to something like this:
use std::str::Chars;
use std::iter::Peekable;
struct Parser<'a> {
input: Peekable<Chars<'a>>,
}
impl<'a> Parser<'a> {
fn new(input: &'a str) -> Self {
Parser {
input: input.chars().peekable(),
}
}
fn consume(&mut self, check: char) -> bool {
// see below
}
}
My original implementation of consume
, which should take a look at the next character in the input and return true (and advance the Peekable
) if it matches the passed character, was this:
fn consume(&mut self, check: char) -> bool {
match self.input.peek() {
Some(c) if *c == check => {
self.input.next();
true
},
_ => false
}
}
The compiler informed me that I can't mutably borrow self.input
for the call to next
because I've already borrowed it in the call to peek
:
error[E0499]: cannot borrow `self.input` as mutable more than once at a time
--> src/main.rs:18:17
|
16 | match self.input.peek() {
| ---------- first mutable borrow occurs here
17 | Some(c) if *c == check => {
18 | self.input.next();
| ^^^^^^^^^^ second mutable borrow occurs here
...
22 | }
| - first borrow ends here
I don't understand why adding a &
to the Some
match expression (and dropping the *
from *c
) makes the code compile:
fn consume(&mut self, check: char) -> bool {
match self.input.peek() {
Some(&c) if c == check => {
self.input.next();
true
},
_ => false
}
}
Based on Boiethios' comment, what would the proper solution be if c
wasn't Copy
?