Rollup merge of #45927 - sinkuu:mir-borrowck-closure, r=estebank

MIR-borrowck: fix diagnostics for closures

Emit notes for captured variables in the same manner as AST borrowck.

```
error[E0499]: cannot borrow `x` as mutable more than once at a time (Ast)
  --> $DIR/borrowck-closures-two-mut.rs:24:24
   |
23 |     let c1 = to_fn_mut(|| x = 4);
   |                        -- - previous borrow occurs due to use of `x` in closure
   |                        |
   |                        first mutable borrow occurs here
24 |     let c2 = to_fn_mut(|| x = 5); //~ ERROR cannot borrow `x` as mutable more than once
   |                        ^^ - borrow occurs due to use of `x` in closure
   |                        |
   |                        second mutable borrow occurs here
25 | }
   | - first borrow ends here

error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir)
  --> $DIR/borrowck-closures-two-mut.rs:24:24
   |
23 |     let c1 = to_fn_mut(|| x = 4);
   |                        -- - previous borrow occurs due to use of `x` in closure
   |                        |
   |                        first mutable borrow occurs here
24 |     let c2 = to_fn_mut(|| x = 5); //~ ERROR cannot borrow `x` as mutable more than once
   |                        ^^ - borrow occurs due to use of `x` in closure
   |                        |
   |                        second mutable borrow occurs here
25 | }
   | - first borrow ends here
```

Fixes #45362.
This commit is contained in:
kennytm 2017-11-13 17:09:45 +08:00 committed by GitHub
commit 574dff9052
5 changed files with 303 additions and 9 deletions

View file

@ -1949,7 +1949,7 @@ impl ForeignItem_ {
}
/// A free variable referred to in a function.
#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
#[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable)]
pub struct Freevar {
/// The variable being accessed free.
pub def: Def,

View file

@ -267,10 +267,10 @@ impl<'tcx> Mir<'tcx> {
let block = &self[location.block];
let stmts = &block.statements;
let idx = location.statement_index;
if location.statement_index < stmts.len() {
if idx < stmts.len() {
&stmts[idx].source_info
} else {
assert!(location.statement_index == stmts.len());
assert!(idx == stmts.len());
&block.terminator().source_info
}
}