Skip to content

Commit 03128ba

Browse files
lzcuntmejrs
authored and
mejrs
committed
Migrate multiple mut borrows diagnostic
1 parent e2d9380 commit 03128ba

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
@@ -293,3 +293,9 @@ mir_build_borrow_of_moved_value = borrow of moved value
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
295295
.suggest_borrowing = borrow this binding in the pattern to avoid moving the value
296+
297+
mir_build_multiple_mut_borrows = cannot borrow value as mutable more than once at a time
298+
.label = first mutable borrow, by `{$name}`, occurs here
299+
.mutable_borrow = another mutable borrow, by `{$name_mut}`, occurs here
300+
.immutable_borrow = also borrowed as immutable, by `{$name_immut}`, here
301+
.moved = also moved into `{$name_moved}` here

compiler/rustc_mir_build/src/errors.rs

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

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

+7-7
Original file line numberDiff line numberDiff line change
@@ -999,19 +999,19 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_, '_>, pat: &Pa
999999
// Report errors if any.
10001000
if !conflicts_mut_mut.is_empty() {
10011001
// Report mutability conflicts for e.g. `ref mut x @ Some(ref mut y)`.
1002-
let mut err = sess
1003-
.struct_span_err(pat.span, "cannot borrow value as mutable more than once at a time");
1004-
err.span_label(binding_span, format!("first mutable borrow, by `{}`, occurs here", name));
1002+
let mut occurences = vec![];
1003+
10051004
for (span, name) in conflicts_mut_mut {
1006-
err.span_label(span, format!("another mutable borrow, by `{}`, occurs here", name));
1005+
occurences.push(MultipleMutBorrowOccurence::Mutable { span, name_mut: name });
10071006
}
10081007
for (span, name) in conflicts_mut_ref {
1009-
err.span_label(span, format!("also borrowed as immutable, by `{}`, here", name));
1008+
occurences.push(MultipleMutBorrowOccurence::Immutable { span, name_immut: name });
10101009
}
10111010
for (span, name) in conflicts_move {
1012-
err.span_label(span, format!("also moved into `{}` here", name));
1011+
occurences.push(MultipleMutBorrowOccurence::Moved { span, name_moved: name });
10131012
}
1014-
err.emit();
1013+
1014+
sess.emit_err(MultipleMutBorrows { span: pat.span, binding_span, occurences, name });
10151015
} else if !conflicts_mut_ref.is_empty() {
10161016
// Report mutability conflicts for e.g. `ref x @ Some(ref mut y)` or the converse.
10171017
let (primary, also) = match mut_outer {

0 commit comments

Comments
 (0)