about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTheOddGarlic <umutinanerdogan@pm.me>2022-08-30 20:38:10 +0300
committermejrs <>2022-12-17 19:08:25 +0100
commite71a722fa69974102e220444523b824da7eaa522 (patch)
tree16891bc022d8a79938d7cef7a8f11e0375a73b70
parent3a9a06311d8d2445d47f087ef68f702b643bc4df (diff)
downloadrust-e71a722fa69974102e220444523b824da7eaa522.tar.gz
rust-e71a722fa69974102e220444523b824da7eaa522.zip
Migrate multiple mut borrows diagnostic
-rw-r--r--compiler/rustc_error_messages/locales/en-US/mir_build.ftl6
-rw-r--r--compiler/rustc_mir_build/src/errors.rs34
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs14
3 files changed, 47 insertions, 7 deletions
diff --git a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl
index 118ca985b87..94e061a2af6 100644
--- a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl
@@ -293,3 +293,9 @@ mir_build_borrow_of_moved_value = borrow of moved value
     .occurs_because_label = move occurs because `{$name}` has type `{$ty}` which does not implement the `Copy` trait
     .value_borrowed_label = value borrowed here after move
     .suggest_borrowing = borrow this binding in the pattern to avoid moving the value
+
+mir_build_multiple_mut_borrows = cannot borrow value as mutable more than once at a time
+    .label = first mutable borrow, by `{$name}`, occurs here
+    .mutable_borrow = another mutable borrow, by `{$name_mut}`, occurs here
+    .immutable_borrow = also borrowed as immutable, by `{$name_immut}`, here
+    .moved = also moved into `{$name_moved}` here
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index 639c07f4194..dd715fcfc6c 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -578,3 +578,37 @@ pub struct BorrowOfMovedValue<'tcx> {
     #[suggestion(code = "ref ", applicability = "machine-applicable")]
     pub suggest_borrowing: Option<Span>,
 }
+
+#[derive(SessionDiagnostic)]
+#[diag(mir_build::multiple_mut_borrows)]
+pub struct MultipleMutBorrows {
+    #[primary_span]
+    pub span: Span,
+    #[label]
+    pub binding_span: Span,
+    #[subdiagnostic]
+    pub occurences: Vec<MultipleMutBorrowOccurence>,
+    pub name: Ident,
+}
+
+#[derive(SessionSubdiagnostic)]
+pub enum MultipleMutBorrowOccurence {
+    #[label(mir_build::mutable_borrow)]
+    Mutable {
+        #[primary_span]
+        span: Span,
+        name_mut: Ident,
+    },
+    #[label(mir_build::immutable_borrow)]
+    Immutable {
+        #[primary_span]
+        span: Span,
+        name_immut: Ident,
+    },
+    #[label(mir_build::moved)]
+    Moved {
+        #[primary_span]
+        span: Span,
+        name_moved: Ident,
+    },
+}
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index 3b6b188bc6c..374942ee798 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -999,19 +999,19 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_, '_>, pat: &Pa
     // Report errors if any.
     if !conflicts_mut_mut.is_empty() {
         // Report mutability conflicts for e.g. `ref mut x @ Some(ref mut y)`.
-        let mut err = sess
-            .struct_span_err(pat.span, "cannot borrow value as mutable more than once at a time");
-        err.span_label(binding_span, format!("first mutable borrow, by `{}`, occurs here", name));
+        let mut occurences = vec![];
+
         for (span, name) in conflicts_mut_mut {
-            err.span_label(span, format!("another mutable borrow, by `{}`, occurs here", name));
+            occurences.push(MultipleMutBorrowOccurence::Mutable { span, name_mut: name });
         }
         for (span, name) in conflicts_mut_ref {
-            err.span_label(span, format!("also borrowed as immutable, by `{}`, here", name));
+            occurences.push(MultipleMutBorrowOccurence::Immutable { span, name_immut: name });
         }
         for (span, name) in conflicts_move {
-            err.span_label(span, format!("also moved into `{}` here", name));
+            occurences.push(MultipleMutBorrowOccurence::Moved { span, name_moved: name });
         }
-        err.emit();
+
+        sess.emit_err(MultipleMutBorrows { span: pat.span, binding_span, occurences, name });
     } else if !conflicts_mut_ref.is_empty() {
         // Report mutability conflicts for e.g. `ref x @ Some(ref mut y)` or the converse.
         let (primary, also) = match mut_outer {