Consider this example:
struct A;
impl A{
fn get_result(& mut self)->Result<(),&str>{
Ok(())
}
fn get_str(& mut self)->&str{
match self.get_result(){ // #0
Ok(_)=>{}
Err(s)=>return s // #1
}
let _s = &self; // #2
"abc"
}
}
fn main(){
}
The compiler emits an error for this example:
cannot borrow
self
as immutable because it is also borrowed as mutable
The error implies that the mutable borrowing borrowed at #0
is considered in the scope at #2
, such two actions are conflicting, according to 2094-nll - The Rust RFC Book.
However, I don't know why the loan at #0
should include the region at #2
. IMO, the code in get_str
could be transformed to
if self.get_result().is_ok(){
let Ok(_) = self.get_result() else{unreachable!()}; // #3
let _s = &self; // #4
return "abc"
}else{
let Err(v) = self.get_result()else{unreachable!()}; // #4
return v;
}
Since there is no value used after #3
, the lifetime of the borrowing at #3
should be ended at that statement, no alive mutable loan is alive at #4
.
That is, in the original example, the return
statement shouldn't be in the same control-flow graph as that of the following statements. What's the reason here?