Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit f59ee13

Browse files
authoredMar 27, 2019
Rollup merge of rust-lang#59429 - estebank:for-loop-move-nll, r=petrochenkov
When moving out of a for loop head, suggest borrowing it in nll mode Follow up to rust-lang#59195 for NLL.
2 parents 892c18b + 4bad56e commit f59ee13

File tree

6 files changed

+63
-38
lines changed

6 files changed

+63
-38
lines changed
 

‎src/librustc_mir/borrow_check/error_reporting.rs

+37-10
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use rustc_data_structures::indexed_vec::Idx;
1919
use rustc_data_structures::sync::Lrc;
2020
use rustc_errors::{Applicability, DiagnosticBuilder};
2121
use syntax_pos::Span;
22+
use syntax::source_map::CompilerDesugaringKind;
2223

2324
use super::borrow_set::BorrowData;
2425
use super::{Context, MirBorrowckCtxt};
@@ -154,6 +155,18 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
154155
span,
155156
format!("value moved{} here, in previous iteration of loop", move_msg),
156157
);
158+
if Some(CompilerDesugaringKind::ForLoop) == span.compiler_desugaring_kind() {
159+
if let Ok(snippet) = self.infcx.tcx.sess.source_map()
160+
.span_to_snippet(span)
161+
{
162+
err.span_suggestion(
163+
move_span,
164+
"consider borrowing this to avoid moving it into the for loop",
165+
format!("&{}", snippet),
166+
Applicability::MaybeIncorrect,
167+
);
168+
}
169+
}
157170
is_loop_move = true;
158171
} else if move_site.traversed_back_edge {
159172
err.span_label(
@@ -291,8 +304,11 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
291304
format!("move occurs due to use{}", move_spans.describe())
292305
);
293306

294-
self.explain_why_borrow_contains_point(context, borrow, None)
295-
.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "");
307+
self.explain_why_borrow_contains_point(
308+
context,
309+
borrow,
310+
None,
311+
).add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "", Some(borrow_span));
296312
err.buffer(&mut self.errors_buffer);
297313
}
298314

@@ -329,7 +345,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
329345
});
330346

331347
self.explain_why_borrow_contains_point(context, borrow, None)
332-
.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "");
348+
.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "", None);
333349
err.buffer(&mut self.errors_buffer);
334350
}
335351

@@ -542,8 +558,13 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
542558
));
543559
}
544560

545-
explanation
546-
.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, first_borrow_desc);
561+
explanation.add_explanation_to_diagnostic(
562+
self.infcx.tcx,
563+
self.mir,
564+
&mut err,
565+
first_borrow_desc,
566+
None,
567+
);
547568

548569
err.buffer(&mut self.errors_buffer);
549570
}
@@ -866,7 +887,13 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
866887

867888
if let BorrowExplanation::MustBeValidFor { .. } = explanation {
868889
} else {
869-
explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "");
890+
explanation.add_explanation_to_diagnostic(
891+
self.infcx.tcx,
892+
self.mir,
893+
&mut err,
894+
"",
895+
None,
896+
);
870897
}
871898
} else {
872899
err.span_label(borrow_span, "borrowed value does not live long enough");
@@ -886,7 +913,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
886913
format!("value captured here{}", within),
887914
);
888915

889-
explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "");
916+
explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "", None);
890917
}
891918

892919
err
@@ -946,7 +973,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
946973
_ => {}
947974
}
948975

949-
explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "");
976+
explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "", None);
950977

951978
err.buffer(&mut self.errors_buffer);
952979
}
@@ -1027,7 +1054,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
10271054
}
10281055
_ => {}
10291056
}
1030-
explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "");
1057+
explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "", None);
10311058

10321059
let within = if borrow_spans.for_generator() {
10331060
" by generator"
@@ -1367,7 +1394,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
13671394
);
13681395

13691396
self.explain_why_borrow_contains_point(context, loan, None)
1370-
.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "");
1397+
.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "", None);
13711398

13721399
err.buffer(&mut self.errors_buffer);
13731400
}

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

+12-6
Original file line numberDiff line numberDiff line change
@@ -56,17 +56,23 @@ impl BorrowExplanation {
5656
mir: &Mir<'tcx>,
5757
err: &mut DiagnosticBuilder<'_>,
5858
borrow_desc: &str,
59+
borrow_span: Option<Span>,
5960
) {
6061
match *self {
6162
BorrowExplanation::UsedLater(later_use_kind, var_or_use_span) => {
6263
let message = match later_use_kind {
63-
LaterUseKind::TraitCapture => "borrow later captured here by trait object",
64-
LaterUseKind::ClosureCapture => "borrow later captured here by closure",
65-
LaterUseKind::Call => "borrow later used by call",
66-
LaterUseKind::FakeLetRead => "borrow later stored here",
67-
LaterUseKind::Other => "borrow later used here",
64+
LaterUseKind::TraitCapture => "captured here by trait object",
65+
LaterUseKind::ClosureCapture => "captured here by closure",
66+
LaterUseKind::Call => "used by call",
67+
LaterUseKind::FakeLetRead => "stored here",
68+
LaterUseKind::Other => "used here",
6869
};
69-
err.span_label(var_or_use_span, format!("{}{}", borrow_desc, message));
70+
if !borrow_span.map(|sp| sp.overlaps(var_or_use_span)).unwrap_or(false) {
71+
err.span_label(
72+
var_or_use_span,
73+
format!("{}borrow later {}", borrow_desc, message),
74+
);
75+
}
7076
}
7177
BorrowExplanation::UsedLaterInLoop(later_use_kind, var_or_use_span) => {
7278
let message = match later_use_kind {

‎src/test/ui/augmented-assignments.nll.stderr

+5-12
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,11 @@
11
error[E0505]: cannot move out of `x` because it is borrowed
22
--> $DIR/augmented-assignments.rs:16:5
33
|
4-
LL | x
5-
| -
6-
| |
7-
| _____borrow of `x` occurs here
8-
| |
9-
LL | |
10-
LL | | +=
11-
LL | | x;
12-
| | ^
13-
| | |
14-
| |_____move out of `x` occurs here
15-
| borrow later used here
4+
LL | x
5+
| - borrow of `x` occurs here
6+
...
7+
LL | x;
8+
| ^ move out of `x` occurs here
169

1710
error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable
1811
--> $DIR/augmented-assignments.rs:21:5

‎src/test/ui/regions/region-bound-on-closure-outlives-call.nll.stderr

+4-5
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,10 @@ error[E0505]: cannot move out of `f` because it is borrowed
1414
--> $DIR/region-bound-on-closure-outlives-call.rs:3:25
1515
|
1616
LL | (|x| f(x))(call_rec(f))
17-
| ---------- ^ move out of `f` occurs here
18-
| || |
19-
| || borrow occurs due to use in closure
20-
| |borrow of `f` occurs here
21-
| borrow later used by call
17+
| --- - ^ move out of `f` occurs here
18+
| | |
19+
| | borrow occurs due to use in closure
20+
| borrow of `f` occurs here
2221

2322
error: aborting due to previous error
2423

‎src/test/ui/span/borrowck-call-is-borrow-issue-12224.nll.stderr

-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ LL | f(Box::new(|a| {
4242
| - ^^^ move out of `f` occurs here
4343
| |
4444
| borrow of `f` occurs here
45-
| borrow later used by call
4645
LL | foo(f);
4746
| - move occurs due to use in closure
4847

‎src/test/ui/suggestions/borrow-for-loop-head.nll.stderr

+5-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@ error[E0505]: cannot move out of `a` because it is borrowed
22
--> $DIR/borrow-for-loop-head.rs:4:18
33
|
44
LL | for i in &a {
5-
| --
6-
| |
7-
| borrow of `a` occurs here
8-
| borrow later used here
5+
| -- borrow of `a` occurs here
96
LL | for j in a {
107
| ^ move out of `a` occurs here
118

@@ -17,6 +14,10 @@ LL | let a = vec![1, 2, 3];
1714
LL | for i in &a {
1815
LL | for j in a {
1916
| ^ value moved here, in previous iteration of loop
17+
help: consider borrowing this to avoid moving it into the for loop
18+
|
19+
LL | for j in &a {
20+
| ^^
2021

2122
error: aborting due to 2 previous errors
2223

0 commit comments

Comments
 (0)
Please sign in to comment.