Skip to content

Commit

Permalink
Rollup merge of rust-lang#95807 - TaKO8Ki:suggest-local-var-for-vecto…
Browse files Browse the repository at this point in the history
…r, r=fee1-dead

Suggest adding a local for vector to fix borrowck errors

closes rust-lang#95574
  • Loading branch information
Dylan-DPC authored Apr 10, 2022
2 parents 68d5a18 + 71fea61 commit 66b2dcb
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 9 deletions.
40 changes: 31 additions & 9 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -785,13 +785,22 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
issued_borrow: &BorrowData<'tcx>,
explanation: BorrowExplanation,
) {
let used_in_call =
matches!(explanation, BorrowExplanation::UsedLater(LaterUseKind::Call, _call_span, _));
let used_in_call = matches!(
explanation,
BorrowExplanation::UsedLater(LaterUseKind::Call | LaterUseKind::Other, _call_span, _)
);
if !used_in_call {
debug!("not later used in call");
return;
}

let use_span =
if let BorrowExplanation::UsedLater(LaterUseKind::Other, use_span, _) = explanation {
Some(use_span)
} else {
None
};

let outer_call_loc =
if let TwoPhaseActivation::ActivatedAt(loc) = issued_borrow.activation_location {
loc
Expand Down Expand Up @@ -835,7 +844,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
debug!("===> outer_call_loc = {:?}, inner_call_loc = {:?}", outer_call_loc, inner_call_loc);

let inner_call_span = inner_call_term.source_info.span;
let outer_call_span = outer_call_stmt.either(|s| s.source_info, |t| t.source_info).span;
let outer_call_span = match use_span {
Some(span) => span,
None => outer_call_stmt.either(|s| s.source_info, |t| t.source_info).span,
};
if outer_call_span == inner_call_span || !outer_call_span.contains(inner_call_span) {
// FIXME: This stops the suggestion in some cases where it should be emitted.
// Fix the spans for those cases so it's emitted correctly.
Expand All @@ -845,8 +857,20 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
);
return;
}
err.span_help(inner_call_span, "try adding a local storing this argument...");
err.span_help(outer_call_span, "...and then using that local as the argument to this call");
err.span_help(
inner_call_span,
&format!(
"try adding a local storing this{}...",
if use_span.is_some() { "" } else { " argument" }
),
);
err.span_help(
outer_call_span,
&format!(
"...and then using that local {}",
if use_span.is_some() { "here" } else { "as the argument to this call" }
),
);
}

fn suggest_split_at_mut_if_applicable(
Expand Down Expand Up @@ -1912,10 +1936,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
} else {
"cannot assign twice to immutable variable"
};
if span != assigned_span {
if !from_arg {
err.span_label(assigned_span, format!("first assignment to {}", place_description));
}
if span != assigned_span && !from_arg {
err.span_label(assigned_span, format!("first assignment to {}", place_description));
}
if let Some(decl) = local_decl
&& let Some(name) = local_name
Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/borrowck/suggest-local-var-for-vector.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fn main() {
let mut vec = vec![0u32; 420];
vec[vec.len() - 1] = 123; //~ ERROR cannot borrow `vec` as immutable because it is also borrowed as mutable
}
24 changes: 24 additions & 0 deletions src/test/ui/borrowck/suggest-local-var-for-vector.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
error[E0502]: cannot borrow `vec` as immutable because it is also borrowed as mutable
--> $DIR/suggest-local-var-for-vector.rs:3:9
|
LL | vec[vec.len() - 1] = 123;
| ----^^^^^^^^^-----
| | |
| | immutable borrow occurs here
| mutable borrow occurs here
| mutable borrow later used here
|
help: try adding a local storing this...
--> $DIR/suggest-local-var-for-vector.rs:3:9
|
LL | vec[vec.len() - 1] = 123;
| ^^^^^^^^^
help: ...and then using that local here
--> $DIR/suggest-local-var-for-vector.rs:3:5
|
LL | vec[vec.len() - 1] = 123;
| ^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0502`.
4 changes: 4 additions & 0 deletions src/test/ui/borrowck/suggest-storing-local-var-for-vector.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fn main() {
let mut vec = vec![0u32; 420];
vec[vec.len() - 1] = 123; //~ ERROR cannot borrow `vec` as immutable because it is also borrowed as mutable
}
24 changes: 24 additions & 0 deletions src/test/ui/borrowck/suggest-storing-local-var-for-vector.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
error[E0502]: cannot borrow `vec` as immutable because it is also borrowed as mutable
--> $DIR/suggest-storing-local-var-for-vector.rs:3:9
|
LL | vec[vec.len() - 1] = 123;
| ----^^^^^^^^^-----
| | |
| | immutable borrow occurs here
| mutable borrow occurs here
| mutable borrow later used here
|
help: try adding a local storing this...
--> $DIR/suggest-storing-local-var-for-vector.rs:3:9
|
LL | vec[vec.len() - 1] = 123;
| ^^^^^^^^^
help: ...and then using that local here
--> $DIR/suggest-storing-local-var-for-vector.rs:3:5
|
LL | vec[vec.len() - 1] = 123;
| ^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0502`.
22 changes: 22 additions & 0 deletions src/test/ui/borrowck/two-phase-nonrecv-autoref.nll.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,17 @@ LL | i[i[3]] = 4;
| | immutable borrow occurs here
| mutable borrow occurs here
| mutable borrow later used here
|
help: try adding a local storing this...
--> $DIR/two-phase-nonrecv-autoref.rs:138:7
|
LL | i[i[3]] = 4;
| ^^^^
help: ...and then using that local here
--> $DIR/two-phase-nonrecv-autoref.rs:138:5
|
LL | i[i[3]] = 4;
| ^^^^^^^

error[E0502]: cannot borrow `i` as immutable because it is also borrowed as mutable
--> $DIR/two-phase-nonrecv-autoref.rs:143:7
Expand All @@ -64,6 +75,17 @@ LL | i[i[3]] = i[4];
| | immutable borrow occurs here
| mutable borrow occurs here
| mutable borrow later used here
|
help: try adding a local storing this...
--> $DIR/two-phase-nonrecv-autoref.rs:143:7
|
LL | i[i[3]] = i[4];
| ^^^^
help: ...and then using that local here
--> $DIR/two-phase-nonrecv-autoref.rs:143:5
|
LL | i[i[3]] = i[4];
| ^^^^^^^

error: aborting due to 7 previous errors

Expand Down

0 comments on commit 66b2dcb

Please sign in to comment.