Skip to content

Commit 3e527aa

Browse files
committed
Migrate multiple mut borrows diagnostic
1 parent 4f5fdac commit 3e527aa

File tree

3 files changed

+47
-7
lines changed

3 files changed

+47
-7
lines changed

compiler/rustc_error_messages/locales/en-US/mir_build.ftl

+6
Original file line numberDiff line numberDiff line change
@@ -292,3 +292,9 @@ mir_build_borrow_of_moved_value = borrow of moved value
292292
.label = value moved into `{$name}` here
293293
.occurs_because_label = move occurs because `{$name}` has type `{$ty}` which does not implement the `Copy` trait
294294
.value_borrowed_label = value borrowed here after move
295+
296+
mir_build_multiple_mut_borrows = cannot borrow value as mutable more than once at a time
297+
.label = first mutable borrow, by `{$name}`, occurs here
298+
.mutable_borrow = another mutable borrow, by `{$name_mut}`, occurs here
299+
.immutable_borrow = also borrowed as immutable, by `{$name_immut}`, here
300+
.moved = also moved into `{$name_moved}` here

compiler/rustc_mir_build/src/errors.rs

+34
Original file line numberDiff line numberDiff line change
@@ -576,3 +576,37 @@ pub struct BorrowOfMovedValue<'tcx> {
576576
pub name: Ident,
577577
pub ty: Ty<'tcx>,
578578
}
579+
580+
#[derive(SessionDiagnostic)]
581+
#[diag(mir_build::multiple_mut_borrows)]
582+
pub struct MultipleMutBorrows {
583+
#[primary_span]
584+
pub span: Span,
585+
#[label]
586+
pub binding_span: Span,
587+
#[subdiagnostic]
588+
pub occurences: Vec<MultipleMutBorrowOccurence>,
589+
pub name: Ident,
590+
}
591+
592+
#[derive(SessionSubdiagnostic)]
593+
pub enum MultipleMutBorrowOccurence {
594+
#[label(mir_build::mutable_borrow)]
595+
Mutable {
596+
#[primary_span]
597+
span: Span,
598+
name_mut: Ident,
599+
},
600+
#[label(mir_build::immutable_borrow)]
601+
Immutable {
602+
#[primary_span]
603+
span: Span,
604+
name_immut: Ident,
605+
},
606+
#[label(mir_build::moved)]
607+
Moved {
608+
#[primary_span]
609+
span: Span,
610+
name_moved: Ident,
611+
},
612+
}

compiler/rustc_mir_build/src/thir/pattern/check_match.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -991,19 +991,19 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_, '_>, pat: &Pa
991991
// Report errors if any.
992992
if !conflicts_mut_mut.is_empty() {
993993
// Report mutability conflicts for e.g. `ref mut x @ Some(ref mut y)`.
994-
let mut err = sess
995-
.struct_span_err(pat.span, "cannot borrow value as mutable more than once at a time");
996-
err.span_label(binding_span, format!("first mutable borrow, by `{}`, occurs here", name));
994+
let mut occurences = vec![];
995+
997996
for (span, name) in conflicts_mut_mut {
998-
err.span_label(span, format!("another mutable borrow, by `{}`, occurs here", name));
997+
occurences.push(MultipleMutBorrowOccurence::Mutable { span, name_mut: name });
999998
}
1000999
for (span, name) in conflicts_mut_ref {
1001-
err.span_label(span, format!("also borrowed as immutable, by `{}`, here", name));
1000+
occurences.push(MultipleMutBorrowOccurence::Immutable { span, name_immut: name });
10021001
}
10031002
for (span, name) in conflicts_move {
1004-
err.span_label(span, format!("also moved into `{}` here", name));
1003+
occurences.push(MultipleMutBorrowOccurence::Moved { span, name_moved: name });
10051004
}
1006-
err.emit();
1005+
1006+
sess.emit_err(MultipleMutBorrows { span: pat.span, binding_span, occurences, name });
10071007
} else if !conflicts_mut_ref.is_empty() {
10081008
// Report mutability conflicts for e.g. `ref x @ Some(ref mut y)` or the converse.
10091009
let (primary, also) = match mut_outer {

0 commit comments

Comments
 (0)