Skip to content

[NLL] Use smaller spans for errors involving closure captures #52959

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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