Hi Everyone,
In the following code, a borrow in "expect_a_or_b()" lasts much longer than it seems it should be. Could anyone help interpreting why? Thanks.
type Result<T> = std::result::Result<T, &'static str>;
struct Parser<'a> {
s: &'a str,
}
impl<'a> Parser<'a> {
fn expect_a(&'a mut self) -> Result<()> {
if let Some(ch) = self.s.chars().nth(0) {
if (ch == 'a') { return Ok(()) }
}
return Err("Not found a.")
}
fn expect_b(&'a mut self) -> Result<()> {
if let Some(ch) = self.s.chars().nth(0) {
if (ch == 'b') { return Ok(()) }
}
return Err("Not found b.")
}
fn expect_a_or_b(&'a mut self) -> Result<()> {
if let Ok(_) = self.expect_a() { // "self" is mutably borrowed.
return Ok(())
} else if let Ok(_) = self.expect_b() { // This borrow failed.
return Ok(())
} else {
return Err("Not found.")
}
}
}
fn main() {
}
The compiler (both 1.0 stable and 1.1 nightly) tells me that the commented line in expect_a_or_b() is a mutable borrow that lasts until the end of the function, which makes the next "else if" failed because "self" is already borrowed.
Compile-error message of nightly:
test.rs:25:31: 25:35 error: cannot borrow `*self` as mutable more than once at a time
test.rs:25 } else if let Ok(_) = self.expect_b() {
^~~~
note: in expansion of if let expansion
test.rs:25:16: 29:10 note: expansion site
note: in expansion of if let expansion
test.rs:23:9: 29:10 note: expansion site
test.rs:23:24: 23:28 note: previous borrow of `*self` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `*self` until the borrow ends
test.rs:23 if let Ok(_) = self.expect_a() {
^~~~
note: in expansion of if let expansion
test.rs:23:9: 29:10 note: expansion site
test.rs:30:6: 30:6 note: previous borrow ends here
test.rs:22 fn expect_a_or_b(&'a mut self) -> Result<()> {
...
test.rs:30 }
^
error: aborting due to previous error
I also tried to make the borrowing code in braces, but it does not help. Specifically, I made "expect_a_or_b()" look like:
fn expect_a_or_b(&'a mut self) -> Result<()> {
{
if let Ok(_) = self.expect_a() {
return Ok(())
}
}
if let Ok(_) = self.expect_b() {
return Ok(())
} else {
return Err("Not found.")
}
}
The compiler complains the same way.