#cannot borrow `*self` as mutable because it is also borrowed as immutable
11 messages · Page 1 of 1 (latest)
you need to do the str.clone() before you call self.advance() so that the borrow taken by self.peek() can be released
TokenType::String(ref str) => {
let expr = Expr::Literal {
literal: LiteralType::String(str.clone()),
};
self.advance();
Ok(expr)
}
so the moment i do str.clone() the str's borrow is released?
wouldn't it be released after str goes out of scope?
No, this is “non-lexical lifetimes” in action. The borrow is released after its last use, not at end of scope.
This was implemented because it turned out that not having it was really inconvenient.
So basically the compiler will check its last usage and it will release the borrow there, right?
I think I understand now, thank you
Yes, but there isn't really a “release” step that happens at a specific time.
There are two constraints upon the lifetime:
let expr = Expr::Literal {
literal: LiteralType::String(
str.clone() // Lifetime must end AFTER this
),
};
self.advance(); // Lifetime must end BEFORE this
Ok(expr)
The lifetime must end somewhere in that space, but it can never matter exactly where it is considered to end. It is equally valid for you, and the implementation of the borrow checker, to think about it as any of:
self.advance()conflicts with it, so it stops herestr.clone()is the last use, so it stops here- there are two constraints which do not conflict, and that's all that matters
All give the same answer.