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>>
meansself
remains borrowed long return valuef1
in 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