Skip to content

Commit

Permalink
Auto merge of rust-lang#52959 - matthewjasper:closure-spans, r=pnkfelix
Browse files Browse the repository at this point in the history
[NLL] Use smaller spans for errors involving closure captures

Closes rust-lang#51170
Closes rust-lang#46599

Error messages involving closures now point to the captured variable/closure args.

r? @pnkfelix
  • Loading branch information
bors committed Aug 5, 2018
2 parents b47c314 + 12af36a commit 9f9ac89
Show file tree
Hide file tree
Showing 37 changed files with 1,253 additions and 330 deletions.
519 changes: 359 additions & 160 deletions src/librustc_mir/borrow_check/error_reporting.rs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/librustc_mir/borrow_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1542,7 +1542,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
if borrow_of_local_data(&borrow.borrowed_place) {
let err = self.tcx
.cannot_borrow_across_generator_yield(
self.retrieve_borrow_span(borrow),
self.retrieve_borrow_spans(borrow).var_or_use(),
yield_span,
Origin::Mir,
);
Expand Down
43 changes: 17 additions & 26 deletions src/librustc_mir/borrow_check/mutability_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,6 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
let act;
let acted_on;


let span = match error_access {
AccessKind::Move => {
err = self.tcx
Expand All @@ -180,31 +179,23 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
act = "borrow as mutable";
acted_on = "borrowed as mutable";

let closure_span = self.find_closure_span(span, location);
if let Some((args, var)) = closure_span {
err = self.tcx.cannot_borrow_path_as_mutable_because(
args,
&item_msg,
&reason,
Origin::Mir,
);
err.span_label(
var,
format!(
"mutable borrow occurs due to use of `{}` in closure",
self.describe_place(access_place).unwrap(),
),
);
args
} else {
err = self.tcx.cannot_borrow_path_as_mutable_because(
span,
&item_msg,
&reason,
Origin::Mir,
);
span
}
let borrow_spans = self.borrow_spans(span, location);
let borrow_span = borrow_spans.args_or_use();
err = self.tcx.cannot_borrow_path_as_mutable_because(
borrow_span,
&item_msg,
&reason,
Origin::Mir,
);
borrow_spans.var_span_label(
&mut err,
format!(
"mutable borrow occurs due to use of `{}` in closure",
// always Some() if the message is printed.
self.describe_place(access_place).unwrap_or(String::new()),
)
);
borrow_span
}
};

Expand Down
28 changes: 17 additions & 11 deletions src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,18 +62,24 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
);

match find_use::find(mir, regioncx, tcx, region_sub, context.loc) {
Some(Cause::LiveVar(_local, location)) => {
if self.is_borrow_location_in_loop(context.loc) {
err.span_label(
mir.source_info(location).span,
"borrow used here in later iteration of loop".to_string(),
);
Some(Cause::LiveVar(local, location)) => {
let span = mir.source_info(location).span;
let spans = self.move_spans(&Place::Local(local), location)
.or_else(|| self.borrow_spans(span, location));
let message = if self.is_borrow_location_in_loop(context.loc) {
if spans.for_closure() {
"borrow captured here by closure in later iteration of loop"
} else {
"borrow used here in later iteration of loop"
}
} else {
err.span_label(
mir.source_info(location).span,
"borrow later used here".to_string(),
);
}
if spans.for_closure() {
"borrow later captured here by closure"
} else {
"borrow later used here"
}
};
err.span_label(spans.var_or_use(), message);
}

Some(Cause::DropVar(local, location)) => match &mir.local_decls[local].name {
Expand Down
11 changes: 9 additions & 2 deletions src/librustc_mir/util/borrowck_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,15 @@ pub trait BorrowckErrors<'cx>: Sized + Copy {
desc,
OGN = o
);
err.span_label(old_loan_span, "first closure is constructed here");
err.span_label(new_loan_span, "second closure is constructed here");
if old_loan_span == new_loan_span {
err.span_label(
old_loan_span,
"closures are constructed here in different iterations of loop"
);
} else {
err.span_label(old_loan_span, "first closure is constructed here");
err.span_label(new_loan_span, "second closure is constructed here");
}
if let Some(old_load_end_span) = old_load_end_span {
err.span_label(old_load_end_span, "borrow from first closure ends here");
}
Expand Down
20 changes: 10 additions & 10 deletions src/test/ui/borrowck/borrowck-closures-two-mut.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,11 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir)
--> $DIR/borrowck-closures-two-mut.rs:24:24
|
LL | let c1 = to_fn_mut(|| x = 4);
| -- - previous borrow occurs due to use of `x` in closure
| -- - first borrow occurs due to use of `x` in closure
| |
| first mutable borrow occurs here
LL | 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 borrow occurs due to use of `x` in closure
| |
| second mutable borrow occurs here
LL | //~| ERROR cannot borrow `x` as mutable more than once
Expand All @@ -92,11 +92,11 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir)
--> $DIR/borrowck-closures-two-mut.rs:36:24
|
LL | let c1 = to_fn_mut(|| set(&mut x));
| -- - previous borrow occurs due to use of `x` in closure
| -- - first borrow occurs due to use of `x` in closure
| |
| first mutable borrow occurs here
LL | let c2 = to_fn_mut(|| set(&mut x)); //~ ERROR cannot borrow `x` as mutable more than once
| ^^ - borrow occurs due to use of `x` in closure
| ^^ - second borrow occurs due to use of `x` in closure
| |
| second mutable borrow occurs here
LL | //~| ERROR cannot borrow `x` as mutable more than once
Expand All @@ -107,11 +107,11 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir)
--> $DIR/borrowck-closures-two-mut.rs:44:24
|
LL | let c1 = to_fn_mut(|| x = 5);
| -- - previous borrow occurs due to use of `x` in closure
| -- - first borrow occurs due to use of `x` in closure
| |
| first mutable borrow occurs here
LL | let c2 = to_fn_mut(|| set(&mut x)); //~ ERROR cannot borrow `x` as mutable more than once
| ^^ - borrow occurs due to use of `x` in closure
| ^^ - second borrow occurs due to use of `x` in closure
| |
| second mutable borrow occurs here
LL | //~| ERROR cannot borrow `x` as mutable more than once
Expand All @@ -122,11 +122,11 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir)
--> $DIR/borrowck-closures-two-mut.rs:52:24
|
LL | let c1 = to_fn_mut(|| x = 5);
| -- - previous borrow occurs due to use of `x` in closure
| -- - first borrow occurs due to use of `x` in closure
| |
| first mutable borrow occurs here
LL | let c2 = to_fn_mut(|| { let _y = to_fn_mut(|| set(&mut x)); }); // (nested closure)
| ^^ - borrow occurs due to use of `x` in closure
| ^^ - second borrow occurs due to use of `x` in closure
| |
| second mutable borrow occurs here
...
Expand All @@ -137,11 +137,11 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir)
--> $DIR/borrowck-closures-two-mut.rs:65:24
|
LL | let c1 = to_fn_mut(|| set(&mut *x.f));
| -- - previous borrow occurs due to use of `x` in closure
| -- - first borrow occurs due to use of `x` in closure
| |
| first mutable borrow occurs here
LL | let c2 = to_fn_mut(|| set(&mut *x.f));
| ^^ - borrow occurs due to use of `x` in closure
| ^^ - second borrow occurs due to use of `x` in closure
| |
| second mutable borrow occurs here
...
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
error[E0597]: `books` does not live long enough
--> $DIR/borrowck-escaping-closure-error-1.rs:23:11
--> $DIR/borrowck-escaping-closure-error-1.rs:23:14
|
LL | spawn(|| books.push(4));
| ^^^^^^^^^^^^^^^^ borrowed value does not live long enough
| -- ^^^^^ borrowed value does not live long enough
| |
| value captured here
LL | //~^ ERROR E0373
LL | }
| - `books` dropped here while still borrowed
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
error[E0597]: `books` does not live long enough
--> $DIR/borrowck-escaping-closure-error-2.rs:21:14
--> $DIR/borrowck-escaping-closure-error-2.rs:21:17
|
LL | Box::new(|| books.push(4))
| ^^^^^^^^^^^^^^^^ borrowed value does not live long enough
| -- ^^^^^ borrowed value does not live long enough
| |
| value captured here
LL | //~^ ERROR E0373
LL | }
| - `books` dropped here while still borrowed
Expand Down
17 changes: 8 additions & 9 deletions src/test/ui/error-codes/E0504.nll.stderr
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
error[E0505]: cannot move out of `fancy_num` because it is borrowed
--> $DIR/E0504.rs:19:13
|
LL | let fancy_ref = &fancy_num;
| ---------- borrow of `fancy_num` occurs here
LL | let fancy_ref = &fancy_num;
| ---------- borrow of `fancy_num` occurs here
LL |
LL | let x = move || {
| _____________^
LL | | println!("child function: {}", fancy_num.num); //~ ERROR E0504
LL | | };
| |_____^ move out of `fancy_num` occurs here
LL | let x = move || {
| ^^^^^^^ move out of `fancy_num` occurs here
LL | println!("child function: {}", fancy_num.num); //~ ERROR E0504
| --------- move occurs due to use in closure
...
LL | println!("main function: {}", fancy_ref.num);
| ------------- borrow later used here
LL | println!("main function: {}", fancy_ref.num);
| ------------- borrow later used here

error: aborting due to previous error

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/issue-11192.nll.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ LL | let mut test = |foo: &Foo| {
| ----------- mutable borrow occurs here
LL | println!("access {}", foo.x);
LL | ptr = box Foo { x: ptr.x + 1 };
| --- previous borrow occurs due to use of `ptr` in closure
| --- first borrow occurs due to use of `ptr` in closure
...
LL | test(&*ptr);
| -----^^^^^-
Expand Down
4 changes: 3 additions & 1 deletion src/test/ui/issue-11873.nll.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ error[E0505]: cannot move out of `v` because it is borrowed
--> $DIR/issue-11873.rs:14:14
|
LL | let mut f = || v.push(2);
| ------------ borrow of `v` occurs here
| -- - borrow occurs due to use in closure
| |
| borrow of `v` occurs here
LL | let _w = v; //~ ERROR: cannot move out of `v`
| ^ move out of `v` occurs here
LL |
Expand Down
8 changes: 4 additions & 4 deletions src/test/ui/issue-18783.nll.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ error[E0499]: cannot borrow `y` as mutable more than once at a time
--> $DIR/issue-18783.rs:17:21
|
LL | c.push(Box::new(|| y = 0));
| -- - previous borrow occurs due to use of `y` in closure
| -- - first borrow occurs due to use of `y` in closure
| |
| first mutable borrow occurs here
LL | c.push(Box::new(|| y = 0));
| ^^ - borrow occurs due to use of `y` in closure
| ^^ - second borrow occurs due to use of `y` in closure
| |
| second mutable borrow occurs here
LL | //~^ ERROR cannot borrow `y` as mutable more than once at a time
Expand All @@ -17,11 +17,11 @@ error[E0499]: cannot borrow `y` as mutable more than once at a time
--> $DIR/issue-18783.rs:26:29
|
LL | Push::push(&c, Box::new(|| y = 0));
| -- - previous borrow occurs due to use of `y` in closure
| -- - first borrow occurs due to use of `y` in closure
| |
| first mutable borrow occurs here
LL | Push::push(&c, Box::new(|| y = 0));
| ^^ - borrow occurs due to use of `y` in closure
| ^^ - second borrow occurs due to use of `y` in closure
| |
| second mutable borrow occurs here
LL | //~^ ERROR cannot borrow `y` as mutable more than once at a time
Expand Down
4 changes: 3 additions & 1 deletion src/test/ui/issue-24357.nll.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ error[E0382]: use of moved value: `x`
--> $DIR/issue-24357.rs:16:12
|
LL | let f = move || { let y = x; };
| ---------------------- value moved here
| ------- - variable moved due to use in closure
| |
| value moved into closure here
LL | //~^ NOTE value moved (into closure) here
LL | let z = x;
| ^ value used here after move
Expand Down
10 changes: 7 additions & 3 deletions src/test/ui/issue-27282-move-match-input-into-guard.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
error[E0505]: cannot move out of `b` because it is borrowed
--> $DIR/issue-27282-move-match-input-into-guard.rs:26:16
--> $DIR/issue-27282-move-match-input-into-guard.rs:26:17
|
LL | match b {
| - borrow of `b` occurs here
LL | &mut false => {},
LL | _ if { (|| { let bar = b; *bar = false; })();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move out of `b` occurs here
| ^^ - move occurs due to use in closure
| |
| move out of `b` occurs here
...
LL | &mut true => { println!("You might think we should get here"); },
| --------- borrow later used here
Expand All @@ -14,7 +16,9 @@ error[E0382]: use of moved value: `*b`
--> $DIR/issue-27282-move-match-input-into-guard.rs:29:14
|
LL | _ if { (|| { let bar = b; *bar = false; })();
| ----------------------------------- value moved here
| -- - variable moved due to use in closure
| |
| value moved into closure here
...
LL | &mut true => { println!("You might think we should get here"); },
| ^^^^ value used here after move
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ LL | match x {
| - borrow occurs here
...
LL | (|| { *x = None; drop(force_fn_once); })();
| ^^ - borrow occurs due to use of `x` in closure
| ^^ - second borrow occurs due to use of `x` in closure
| |
| closure construction occurs here
...
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ LL | match x {
| - borrow occurs here
...
LL | (|| { *x = None; drop(force_fn_once); })();
| ^^ - borrow occurs due to use of `x` in closure
| ^^ - second borrow occurs due to use of `x` in closure
| |
| closure construction occurs here
...
Expand Down
6 changes: 4 additions & 2 deletions src/test/ui/issue-4335.nll.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ LL | id(Box::new(|| *v))
| ^^ cannot move out of captured variable in an `FnMut` closure

error[E0597]: `v` does not live long enough
--> $DIR/issue-4335.rs:16:17
--> $DIR/issue-4335.rs:16:21
|
LL | id(Box::new(|| *v))
| ^^^^^ borrowed value does not live long enough
| -- ^ borrowed value does not live long enough
| |
| value captured here
...
LL | }
| - `v` dropped here while still borrowed
Expand Down
4 changes: 3 additions & 1 deletion src/test/ui/issue-6801.nll.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ error[E0505]: cannot move out of `x` because it is borrowed
--> $DIR/issue-6801.rs:29:13
|
LL | let sq = || { *x * *x };
| -------------- borrow of `x` occurs here
| -- - borrow occurs due to use in closure
| |
| borrow of `x` occurs here
LL |
LL | twice(x); //~ ERROR: cannot move out of
| ^ move out of `x` occurs here
Expand Down
Loading

0 comments on commit 9f9ac89

Please sign in to comment.