Skip to content

Commit e2d9380

Browse files
lzcuntmejrs
authored and
mejrs
committed
Migrate borrow of moved value diagnostic
1 parent 1a18ee8 commit e2d9380

File tree

3 files changed

+29
-17
lines changed

3 files changed

+29
-17
lines changed

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

+6
Original file line numberDiff line numberDiff line change
@@ -287,3 +287,9 @@ mir_build_irrefutable_let_patterns_while_let = irrefutable `while let` {$count -
287287
*[other] these patterns
288288
} will always match, so the loop will never exit
289289
.help = consider instead using a `loop {"{"} ... {"}"}` with a `let` inside it
290+
291+
mir_build_borrow_of_moved_value = borrow of moved value
292+
.label = value moved into `{$name}` here
293+
.occurs_because_label = move occurs because `{$name}` has type `{$ty}` which does not implement the `Copy` trait
294+
.value_borrowed_label = value borrowed here after move
295+
.suggest_borrowing = borrow this binding in the pattern to avoid moving the value

compiler/rustc_mir_build/src/errors.rs

+16
Original file line numberDiff line numberDiff line change
@@ -562,3 +562,19 @@ pub struct IrrefutableLetPatternsLetElse {
562562
pub struct IrrefutableLetPatternsWhileLet {
563563
pub count: usize,
564564
}
565+
566+
#[derive(SessionDiagnostic)]
567+
#[diag(mir_build::borrow_of_moved_value)]
568+
pub struct BorrowOfMovedValue<'tcx> {
569+
#[primary_span]
570+
pub span: Span,
571+
#[label]
572+
#[label(mir_build::occurs_because_label)]
573+
pub binding_span: Span,
574+
#[label(mir_build::value_borrowed_label)]
575+
pub conflicts_ref: Vec<Span>,
576+
pub name: Ident,
577+
pub ty: Ty<'tcx>,
578+
#[suggestion(code = "ref ", applicability = "machine-applicable")]
579+
pub suggest_borrowing: Option<Span>,
580+
}

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

+7-17
Original file line numberDiff line numberDiff line change
@@ -962,24 +962,14 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_, '_>, pat: &Pa
962962
}
963963
});
964964
if !conflicts_ref.is_empty() {
965-
let occurs_because = format!(
966-
"move occurs because `{}` has type `{}` which does not implement the `Copy` trait",
965+
sess.emit_err(BorrowOfMovedValue {
966+
span: pat.span,
967+
binding_span,
968+
conflicts_ref,
967969
name,
968-
typeck_results.node_type(pat.hir_id),
969-
);
970-
let mut err = sess.struct_span_err(pat.span, "borrow of moved value");
971-
err.span_label(binding_span, format!("value moved into `{}` here", name))
972-
.span_label(binding_span, occurs_because)
973-
.span_labels(conflicts_ref, "value borrowed here after move");
974-
if pat.span.contains(binding_span) {
975-
err.span_suggestion_verbose(
976-
binding_span.shrink_to_lo(),
977-
"borrow this binding in the pattern to avoid moving the value",
978-
"ref ".to_string(),
979-
Applicability::MachineApplicable,
980-
);
981-
}
982-
err.emit();
970+
ty: typeck_results.node_type(pat.hir_id),
971+
suggest_borrowing: pat.span.contains(binding_span).then(|| binding_span.shrink_to_lo()),
972+
});
983973
}
984974
return;
985975
}

0 commit comments

Comments
 (0)