Skip to content

Commit 9f9ac89

Browse files
committed
Auto merge of #52959 - matthewjasper:closure-spans, r=pnkfelix
[NLL] Use smaller spans for errors involving closure captures Closes #51170 Closes #46599 Error messages involving closures now point to the captured variable/closure args. r? @pnkfelix
2 parents b47c314 + 12af36a commit 9f9ac89

37 files changed

+1253
-330
lines changed

src/librustc_mir/borrow_check/error_reporting.rs

+359-160
Large diffs are not rendered by default.

src/librustc_mir/borrow_check/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1542,7 +1542,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
15421542
if borrow_of_local_data(&borrow.borrowed_place) {
15431543
let err = self.tcx
15441544
.cannot_borrow_across_generator_yield(
1545-
self.retrieve_borrow_span(borrow),
1545+
self.retrieve_borrow_spans(borrow).var_or_use(),
15461546
yield_span,
15471547
Origin::Mir,
15481548
);

src/librustc_mir/borrow_check/mutability_errors.rs

+17-26
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,6 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
160160
let act;
161161
let acted_on;
162162

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

183-
let closure_span = self.find_closure_span(span, location);
184-
if let Some((args, var)) = closure_span {
185-
err = self.tcx.cannot_borrow_path_as_mutable_because(
186-
args,
187-
&item_msg,
188-
&reason,
189-
Origin::Mir,
190-
);
191-
err.span_label(
192-
var,
193-
format!(
194-
"mutable borrow occurs due to use of `{}` in closure",
195-
self.describe_place(access_place).unwrap(),
196-
),
197-
);
198-
args
199-
} else {
200-
err = self.tcx.cannot_borrow_path_as_mutable_because(
201-
span,
202-
&item_msg,
203-
&reason,
204-
Origin::Mir,
205-
);
206-
span
207-
}
182+
let borrow_spans = self.borrow_spans(span, location);
183+
let borrow_span = borrow_spans.args_or_use();
184+
err = self.tcx.cannot_borrow_path_as_mutable_because(
185+
borrow_span,
186+
&item_msg,
187+
&reason,
188+
Origin::Mir,
189+
);
190+
borrow_spans.var_span_label(
191+
&mut err,
192+
format!(
193+
"mutable borrow occurs due to use of `{}` in closure",
194+
// always Some() if the message is printed.
195+
self.describe_place(access_place).unwrap_or(String::new()),
196+
)
197+
);
198+
borrow_span
208199
}
209200
};
210201

src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs

+17-11
Original file line numberDiff line numberDiff line change
@@ -62,18 +62,24 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
6262
);
6363

6464
match find_use::find(mir, regioncx, tcx, region_sub, context.loc) {
65-
Some(Cause::LiveVar(_local, location)) => {
66-
if self.is_borrow_location_in_loop(context.loc) {
67-
err.span_label(
68-
mir.source_info(location).span,
69-
"borrow used here in later iteration of loop".to_string(),
70-
);
65+
Some(Cause::LiveVar(local, location)) => {
66+
let span = mir.source_info(location).span;
67+
let spans = self.move_spans(&Place::Local(local), location)
68+
.or_else(|| self.borrow_spans(span, location));
69+
let message = if self.is_borrow_location_in_loop(context.loc) {
70+
if spans.for_closure() {
71+
"borrow captured here by closure in later iteration of loop"
72+
} else {
73+
"borrow used here in later iteration of loop"
74+
}
7175
} else {
72-
err.span_label(
73-
mir.source_info(location).span,
74-
"borrow later used here".to_string(),
75-
);
76-
}
76+
if spans.for_closure() {
77+
"borrow later captured here by closure"
78+
} else {
79+
"borrow later used here"
80+
}
81+
};
82+
err.span_label(spans.var_or_use(), message);
7783
}
7884

7985
Some(Cause::DropVar(local, location)) => match &mir.local_decls[local].name {

src/librustc_mir/util/borrowck_errors.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,15 @@ pub trait BorrowckErrors<'cx>: Sized + Copy {
203203
desc,
204204
OGN = o
205205
);
206-
err.span_label(old_loan_span, "first closure is constructed here");
207-
err.span_label(new_loan_span, "second closure is constructed here");
206+
if old_loan_span == new_loan_span {
207+
err.span_label(
208+
old_loan_span,
209+
"closures are constructed here in different iterations of loop"
210+
);
211+
} else {
212+
err.span_label(old_loan_span, "first closure is constructed here");
213+
err.span_label(new_loan_span, "second closure is constructed here");
214+
}
208215
if let Some(old_load_end_span) = old_load_end_span {
209216
err.span_label(old_load_end_span, "borrow from first closure ends here");
210217
}

src/test/ui/borrowck/borrowck-closures-two-mut.stderr

+10-10
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,11 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir)
7777
--> $DIR/borrowck-closures-two-mut.rs:24:24
7878
|
7979
LL | let c1 = to_fn_mut(|| x = 4);
80-
| -- - previous borrow occurs due to use of `x` in closure
80+
| -- - first borrow occurs due to use of `x` in closure
8181
| |
8282
| first mutable borrow occurs here
8383
LL | let c2 = to_fn_mut(|| x = 5); //~ ERROR cannot borrow `x` as mutable more than once
84-
| ^^ - borrow occurs due to use of `x` in closure
84+
| ^^ - second borrow occurs due to use of `x` in closure
8585
| |
8686
| second mutable borrow occurs here
8787
LL | //~| ERROR cannot borrow `x` as mutable more than once
@@ -92,11 +92,11 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir)
9292
--> $DIR/borrowck-closures-two-mut.rs:36:24
9393
|
9494
LL | let c1 = to_fn_mut(|| set(&mut x));
95-
| -- - previous borrow occurs due to use of `x` in closure
95+
| -- - first borrow occurs due to use of `x` in closure
9696
| |
9797
| first mutable borrow occurs here
9898
LL | let c2 = to_fn_mut(|| set(&mut x)); //~ ERROR cannot borrow `x` as mutable more than once
99-
| ^^ - borrow occurs due to use of `x` in closure
99+
| ^^ - second borrow occurs due to use of `x` in closure
100100
| |
101101
| second mutable borrow occurs here
102102
LL | //~| ERROR cannot borrow `x` as mutable more than once
@@ -107,11 +107,11 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir)
107107
--> $DIR/borrowck-closures-two-mut.rs:44:24
108108
|
109109
LL | let c1 = to_fn_mut(|| x = 5);
110-
| -- - previous borrow occurs due to use of `x` in closure
110+
| -- - first borrow occurs due to use of `x` in closure
111111
| |
112112
| first mutable borrow occurs here
113113
LL | let c2 = to_fn_mut(|| set(&mut x)); //~ ERROR cannot borrow `x` as mutable more than once
114-
| ^^ - borrow occurs due to use of `x` in closure
114+
| ^^ - second borrow occurs due to use of `x` in closure
115115
| |
116116
| second mutable borrow occurs here
117117
LL | //~| ERROR cannot borrow `x` as mutable more than once
@@ -122,11 +122,11 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir)
122122
--> $DIR/borrowck-closures-two-mut.rs:52:24
123123
|
124124
LL | let c1 = to_fn_mut(|| x = 5);
125-
| -- - previous borrow occurs due to use of `x` in closure
125+
| -- - first borrow occurs due to use of `x` in closure
126126
| |
127127
| first mutable borrow occurs here
128128
LL | let c2 = to_fn_mut(|| { let _y = to_fn_mut(|| set(&mut x)); }); // (nested closure)
129-
| ^^ - borrow occurs due to use of `x` in closure
129+
| ^^ - second borrow occurs due to use of `x` in closure
130130
| |
131131
| second mutable borrow occurs here
132132
...
@@ -137,11 +137,11 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir)
137137
--> $DIR/borrowck-closures-two-mut.rs:65:24
138138
|
139139
LL | let c1 = to_fn_mut(|| set(&mut *x.f));
140-
| -- - previous borrow occurs due to use of `x` in closure
140+
| -- - first borrow occurs due to use of `x` in closure
141141
| |
142142
| first mutable borrow occurs here
143143
LL | let c2 = to_fn_mut(|| set(&mut *x.f));
144-
| ^^ - borrow occurs due to use of `x` in closure
144+
| ^^ - second borrow occurs due to use of `x` in closure
145145
| |
146146
| second mutable borrow occurs here
147147
...

src/test/ui/borrowck/borrowck-escaping-closure-error-1.nll.stderr

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
error[E0597]: `books` does not live long enough
2-
--> $DIR/borrowck-escaping-closure-error-1.rs:23:11
2+
--> $DIR/borrowck-escaping-closure-error-1.rs:23:14
33
|
44
LL | spawn(|| books.push(4));
5-
| ^^^^^^^^^^^^^^^^ borrowed value does not live long enough
5+
| -- ^^^^^ borrowed value does not live long enough
6+
| |
7+
| value captured here
68
LL | //~^ ERROR E0373
79
LL | }
810
| - `books` dropped here while still borrowed

src/test/ui/borrowck/borrowck-escaping-closure-error-2.nll.stderr

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
error[E0597]: `books` does not live long enough
2-
--> $DIR/borrowck-escaping-closure-error-2.rs:21:14
2+
--> $DIR/borrowck-escaping-closure-error-2.rs:21:17
33
|
44
LL | Box::new(|| books.push(4))
5-
| ^^^^^^^^^^^^^^^^ borrowed value does not live long enough
5+
| -- ^^^^^ borrowed value does not live long enough
6+
| |
7+
| value captured here
68
LL | //~^ ERROR E0373
79
LL | }
810
| - `books` dropped here while still borrowed

src/test/ui/error-codes/E0504.nll.stderr

+8-9
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
error[E0505]: cannot move out of `fancy_num` because it is borrowed
22
--> $DIR/E0504.rs:19:13
33
|
4-
LL | let fancy_ref = &fancy_num;
5-
| ---------- borrow of `fancy_num` occurs here
4+
LL | let fancy_ref = &fancy_num;
5+
| ---------- borrow of `fancy_num` occurs here
66
LL |
7-
LL | let x = move || {
8-
| _____________^
9-
LL | | println!("child function: {}", fancy_num.num); //~ ERROR E0504
10-
LL | | };
11-
| |_____^ move out of `fancy_num` occurs here
7+
LL | let x = move || {
8+
| ^^^^^^^ move out of `fancy_num` occurs here
9+
LL | println!("child function: {}", fancy_num.num); //~ ERROR E0504
10+
| --------- move occurs due to use in closure
1211
...
13-
LL | println!("main function: {}", fancy_ref.num);
14-
| ------------- borrow later used here
12+
LL | println!("main function: {}", fancy_ref.num);
13+
| ------------- borrow later used here
1514

1615
error: aborting due to previous error
1716

src/test/ui/issue-11192.nll.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | let mut test = |foo: &Foo| {
55
| ----------- mutable borrow occurs here
66
LL | println!("access {}", foo.x);
77
LL | ptr = box Foo { x: ptr.x + 1 };
8-
| --- previous borrow occurs due to use of `ptr` in closure
8+
| --- first borrow occurs due to use of `ptr` in closure
99
...
1010
LL | test(&*ptr);
1111
| -----^^^^^-

src/test/ui/issue-11873.nll.stderr

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ error[E0505]: cannot move out of `v` because it is borrowed
22
--> $DIR/issue-11873.rs:14:14
33
|
44
LL | let mut f = || v.push(2);
5-
| ------------ borrow of `v` occurs here
5+
| -- - borrow occurs due to use in closure
6+
| |
7+
| borrow of `v` occurs here
68
LL | let _w = v; //~ ERROR: cannot move out of `v`
79
| ^ move out of `v` occurs here
810
LL |

src/test/ui/issue-18783.nll.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ error[E0499]: cannot borrow `y` as mutable more than once at a time
22
--> $DIR/issue-18783.rs:17:21
33
|
44
LL | c.push(Box::new(|| y = 0));
5-
| -- - previous borrow occurs due to use of `y` in closure
5+
| -- - first borrow occurs due to use of `y` in closure
66
| |
77
| first mutable borrow occurs here
88
LL | c.push(Box::new(|| y = 0));
9-
| ^^ - borrow occurs due to use of `y` in closure
9+
| ^^ - second borrow occurs due to use of `y` in closure
1010
| |
1111
| second mutable borrow occurs here
1212
LL | //~^ ERROR cannot borrow `y` as mutable more than once at a time
@@ -17,11 +17,11 @@ error[E0499]: cannot borrow `y` as mutable more than once at a time
1717
--> $DIR/issue-18783.rs:26:29
1818
|
1919
LL | Push::push(&c, Box::new(|| y = 0));
20-
| -- - previous borrow occurs due to use of `y` in closure
20+
| -- - first borrow occurs due to use of `y` in closure
2121
| |
2222
| first mutable borrow occurs here
2323
LL | Push::push(&c, Box::new(|| y = 0));
24-
| ^^ - borrow occurs due to use of `y` in closure
24+
| ^^ - second borrow occurs due to use of `y` in closure
2525
| |
2626
| second mutable borrow occurs here
2727
LL | //~^ ERROR cannot borrow `y` as mutable more than once at a time

src/test/ui/issue-24357.nll.stderr

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ error[E0382]: use of moved value: `x`
22
--> $DIR/issue-24357.rs:16:12
33
|
44
LL | let f = move || { let y = x; };
5-
| ---------------------- value moved here
5+
| ------- - variable moved due to use in closure
6+
| |
7+
| value moved into closure here
68
LL | //~^ NOTE value moved (into closure) here
79
LL | let z = x;
810
| ^ value used here after move

src/test/ui/issue-27282-move-match-input-into-guard.stderr

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
error[E0505]: cannot move out of `b` because it is borrowed
2-
--> $DIR/issue-27282-move-match-input-into-guard.rs:26:16
2+
--> $DIR/issue-27282-move-match-input-into-guard.rs:26:17
33
|
44
LL | match b {
55
| - borrow of `b` occurs here
66
LL | &mut false => {},
77
LL | _ if { (|| { let bar = b; *bar = false; })();
8-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move out of `b` occurs here
8+
| ^^ - move occurs due to use in closure
9+
| |
10+
| move out of `b` occurs here
911
...
1012
LL | &mut true => { println!("You might think we should get here"); },
1113
| --------- borrow later used here
@@ -14,7 +16,9 @@ error[E0382]: use of moved value: `*b`
1416
--> $DIR/issue-27282-move-match-input-into-guard.rs:29:14
1517
|
1618
LL | _ if { (|| { let bar = b; *bar = false; })();
17-
| ----------------------------------- value moved here
19+
| -- - variable moved due to use in closure
20+
| |
21+
| value moved into closure here
1822
...
1923
LL | &mut true => { println!("You might think we should get here"); },
2024
| ^^^^ value used here after move

src/test/ui/issue-27282-mutate-before-diverging-arm-1.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | match x {
55
| - borrow occurs here
66
...
77
LL | (|| { *x = None; drop(force_fn_once); })();
8-
| ^^ - borrow occurs due to use of `x` in closure
8+
| ^^ - second borrow occurs due to use of `x` in closure
99
| |
1010
| closure construction occurs here
1111
...

src/test/ui/issue-27282-mutate-before-diverging-arm-2.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | match x {
55
| - borrow occurs here
66
...
77
LL | (|| { *x = None; drop(force_fn_once); })();
8-
| ^^ - borrow occurs due to use of `x` in closure
8+
| ^^ - second borrow occurs due to use of `x` in closure
99
| |
1010
| closure construction occurs here
1111
...

src/test/ui/issue-4335.nll.stderr

+4-2
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ LL | id(Box::new(|| *v))
55
| ^^ cannot move out of captured variable in an `FnMut` closure
66

77
error[E0597]: `v` does not live long enough
8-
--> $DIR/issue-4335.rs:16:17
8+
--> $DIR/issue-4335.rs:16:21
99
|
1010
LL | id(Box::new(|| *v))
11-
| ^^^^^ borrowed value does not live long enough
11+
| -- ^ borrowed value does not live long enough
12+
| |
13+
| value captured here
1214
...
1315
LL | }
1416
| - `v` dropped here while still borrowed

src/test/ui/issue-6801.nll.stderr

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ error[E0505]: cannot move out of `x` because it is borrowed
22
--> $DIR/issue-6801.rs:29:13
33
|
44
LL | let sq = || { *x * *x };
5-
| -------------- borrow of `x` occurs here
5+
| -- - borrow occurs due to use in closure
6+
| |
7+
| borrow of `x` occurs here
68
LL |
79
LL | twice(x); //~ ERROR: cannot move out of
810
| ^ move out of `x` occurs here

0 commit comments

Comments
 (0)