about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs40
-rw-r--r--src/test/ui/borrowck/suggest-local-var-for-vector.rs4
-rw-r--r--src/test/ui/borrowck/suggest-local-var-for-vector.stderr24
-rw-r--r--src/test/ui/borrowck/suggest-storing-local-var-for-vector.rs4
-rw-r--r--src/test/ui/borrowck/suggest-storing-local-var-for-vector.stderr24
-rw-r--r--src/test/ui/borrowck/two-phase-nonrecv-autoref.nll.stderr22
6 files changed, 109 insertions, 9 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index b945d687043..9e5fb674772 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -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
@@ -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.
@@ -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(
@@ -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
diff --git a/src/test/ui/borrowck/suggest-local-var-for-vector.rs b/src/test/ui/borrowck/suggest-local-var-for-vector.rs
new file mode 100644
index 00000000000..40f013f6a78
--- /dev/null
+++ b/src/test/ui/borrowck/suggest-local-var-for-vector.rs
@@ -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
+}
diff --git a/src/test/ui/borrowck/suggest-local-var-for-vector.stderr b/src/test/ui/borrowck/suggest-local-var-for-vector.stderr
new file mode 100644
index 00000000000..615fffcd578
--- /dev/null
+++ b/src/test/ui/borrowck/suggest-local-var-for-vector.stderr
@@ -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`.
diff --git a/src/test/ui/borrowck/suggest-storing-local-var-for-vector.rs b/src/test/ui/borrowck/suggest-storing-local-var-for-vector.rs
new file mode 100644
index 00000000000..40f013f6a78
--- /dev/null
+++ b/src/test/ui/borrowck/suggest-storing-local-var-for-vector.rs
@@ -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
+}
diff --git a/src/test/ui/borrowck/suggest-storing-local-var-for-vector.stderr b/src/test/ui/borrowck/suggest-storing-local-var-for-vector.stderr
new file mode 100644
index 00000000000..e3a16eddfd5
--- /dev/null
+++ b/src/test/ui/borrowck/suggest-storing-local-var-for-vector.stderr
@@ -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`.
diff --git a/src/test/ui/borrowck/two-phase-nonrecv-autoref.nll.stderr b/src/test/ui/borrowck/two-phase-nonrecv-autoref.nll.stderr
index 50d277a12f7..0f2daaf99d9 100644
--- a/src/test/ui/borrowck/two-phase-nonrecv-autoref.nll.stderr
+++ b/src/test/ui/borrowck/two-phase-nonrecv-autoref.nll.stderr
@@ -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
@@ -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