Why "return" binds variables?

52 points karasawa_jp
fn foo(v : &mut Vec<i32>) -> &mut i32{
    {
        if let Some(i) = v.get_mut(0){
            return i;
        }
    }
    v.get_mut(1).unwrap()
}

This isn't compiled. \[Playground\]

error[E0499]: cannot borrow `*v` as mutable more than once at a time
 --> src/lib.rs:7:5
  |
1 | fn foo(v : &mut Vec<i32>) -> &mut i32{
  |            - let's call the lifetime of this reference `'1`
2 |     {
3 |         if let Some(i) = v.get_mut(0){
  |                          ------------ first mutable borrow occurs here
4 |             return i;
  |                    - returning this value requires that `*v` is borrowed for `'1`
...
7 |     v.get_mut(1).unwrap()
  |     ^^^^^^^^^^^^ second mutable borrow occurs here

Of course this can be compiled:

fn foo(v : &mut Vec<i32>) -> &mut i32{
    {
        if let Some(i) = v.get_mut(0){
            *i += 1;
        }
    }
    v.get_mut(1).unwrap()
}

So I believe "return" binds the returned value for more than its scope.

When the code paths are clearly separated, it's compiled.

fn foo(v : &mut Vec<i32>) -> &mut i32{
    if v.len() < 100 {
        if let Some(i) = v.get_mut(0){
            return i;
        } else{
            panic!();
        }
    } else{
        v.get_mut(1).unwrap()
    }
}

So the binding doesn't last the entire function scope.

I want to know why the Rust compiler do this.