I'm writing a lexer in Rust to learn, but I'm stuck with two "cannot move out of borrowed content [E0507]" errors.
I tried all the solutions out there, but nothing seems to work: RefCell
, clone()
, by_ref()
, changing the &mut self
to self
or &self
or mut self
, or dereferencing.
Here is my code:
struct Snapshot {
Index: u32,
}
struct Tokenizable<'a, T: 'a>
where T: Iterator
{
Index: u32,
Items: &'a T,
Snapshots: Vec<Snapshot>,
}
impl<'a, T> Tokenizable<'a, T>
where T: Iterator
{
fn new(items: &'a T) -> Tokenizable<'a, T> {
Tokenizable {
Index: 0,
Items: items,
Snapshots: Vec::new(),
}
}
fn end(&mut self) -> bool {
match self.Items.peekable().peek() {
Some(c) => false,
None => true,
}
}
fn peek(&mut self) -> Option<&T::Item> {
match self.Items.peekable().peek() {
Some(c) => Some(c),
None => None,
}
}
}
fn main() {}
error: cannot move out of borrowed content [E0507]
match self.Items.peekable().peek() {
^~~~~~~~~~
help: see the detailed explanation for E0507
error: borrowed value does not live long enough
match self.Items.peekable().peek() {
^~~~~~~~~~~~~~~~~~~~~
note: reference must be valid for the anonymous lifetime #1 defined on the block at 32:43...
fn peek(&mut self) -> Option<&T::Item> {
match self.Items.peekable().peek() {
Some(c) => Some(c),
None => None,
}
}
note: ...but borrowed value is only valid for the block at 32:43
fn peek(&mut self) -> Option<&T::Item> {
match self.Items.peekable().peek() {
Some(c) => Some(c),
None => None,
}
}
error: cannot move out of borrowed content [E0507]
match self.Items.peekable().peek() {
^~~~~~~~~~
help: see the detailed explanation for E0507
As you can see in the docs, the
peekable
function takes the iterator by value. Therefore it will only work if you own the iterator. However, in your code,Items
is a shared reference to the iterator.Solving this problem requires approaching it from a different angle. For instance, you could take the iterator by value in the constructor and adapt the struct to store the peekable iterator in the
Items
field.Basically, what is to be learned from here is the fact that over complicating things and over engineering things almost always does more harm than good.
Final fixed code: