rust - Why is a borrow still held in the else block of an if let? -
why call self.f2() in following code trip borrow checker? isn't else block in different scope? quite conundrum!
use std::str::chars; struct a; impl { fn f2(&mut self) {} fn f1(&mut self) -> option<chars> { none } fn f3(&mut self) { if let some(x) = self.f1() { } else { self.f2() } } } fn main() { let mut = a; } error[e0499]: cannot borrow `*self` mutable more once @ time --> src/main.rs:16:13 | 13 | if let some(x) = self.f1() { | ---- first mutable borrow occurs here ... 16 | self.f2() | ^^^^ second mutable borrow occurs here 17 | } | - first borrow ends here doesn't scope of borrow self begin , end self.f1() call? once call f1() has returned f1() not using self anymore hence borrow checker should not have problem second borrow. note following code fails too...
// ... if let some(x) = self.f1() { self.f2() } // ... i think second borrow should fine here since f1 , f3 not using self @ same time f2.
it's annoying, can work around introducing inner scope , changing control flow bit:
fn f3(&mut self) { { if let some(x) = self.f1() { // ... return; } } self.f2() } as pointed out in comments, works without braces. because if or if...let expression has implicit scope, , borrow lasts scope:
fn f3(&mut self) { if let some(x) = self.f1() { // ... return; } self.f2() } here's log of irc chat between sandeep datta , mbrubeck:
mbrubeck: std:tr::chars contains borrowed reference string created it. full type name
chars<'a>.f1(&mut self) -> option<chars>without elisionf1(&'a mut self) -> option<chars<'a>>meansselfremains borrowed long return valuef1in scope.sandeep datta: can use 'b self , 'a chars avoid problem?
mbrubeck: not if returning iterator on
self. though if can make function&self -> chars(instead of&mut self -> chars) fix issue.
Comments
Post a Comment