diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 46c0bbac2f1..60860f93daa 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -715,22 +715,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { borrow_span, &self.describe_any_place(borrow.borrowed_place.as_ref()), ); - borrow_spans.var_subdiag( - &mut err, - |var_span| { - use crate::session_diagnostics::CaptureVarCause::*; - let place = &borrow.borrowed_place; - let desc_place = self.describe_any_place(place.as_ref()); - match borrow_spans { - UseSpans::ClosureUse { generator_kind, .. } => match generator_kind { - Some(_) => BorrowUsePlaceGenerator { place: desc_place, var_span }, - None => BorrowUsePlaceClosure { place: desc_place, var_span }, - }, - _ => BorrowUsePlace { place: desc_place, var_span }, - } - }, - "mutable", - ); + borrow_spans.var_subdiag(&mut err, Some(borrow.kind), |kind, var_span| { + use crate::session_diagnostics::CaptureVarCause::*; + let place = &borrow.borrowed_place; + let desc_place = self.describe_any_place(place.as_ref()); + match kind { + Some(_) => BorrowUsePlaceGenerator { place: desc_place, var_span }, + None => BorrowUsePlaceClosure { place: desc_place, var_span }, + } + }); self.explain_why_borrow_contains_point(location, borrow, None) .add_explanation_to_diagnostic( diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index c7b9f617d5a..7f26af67c71 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -650,19 +650,28 @@ impl UseSpans<'_> { pub(super) fn var_subdiag( self, err: &mut Diagnostic, - f: impl Fn(Span) -> crate::session_diagnostics::CaptureVarCause, - kind_desc: impl Into<String>, + kind: Option<rustc_middle::mir::BorrowKind>, + f: impl Fn(Option<GeneratorKind>, Span) -> crate::session_diagnostics::CaptureVarCause, ) { - if let UseSpans::ClosureUse { capture_kind_span, path_span, .. } = self { - if capture_kind_span == path_span { - err.subdiagnostic(f(capture_kind_span)); - } else { - err.subdiagnostic(crate::session_diagnostics::CaptureVarKind { - kind_desc: kind_desc.into(), - kind_span: capture_kind_span, + use crate::session_diagnostics::CaptureVarKind::*; + if let UseSpans::ClosureUse { generator_kind, capture_kind_span, path_span, .. } = self { + if capture_kind_span != path_span { + err.subdiagnostic(match kind { + Some(kd) => match kd { + rustc_middle::mir::BorrowKind::Shared + | rustc_middle::mir::BorrowKind::Shallow + | rustc_middle::mir::BorrowKind::Unique => { + Immute { kind_span: capture_kind_span } + } + + rustc_middle::mir::BorrowKind::Mut { .. } => { + Mut { kind_span: capture_kind_span } + } + }, + None => Move { kind_span: capture_kind_span }, }); - err.subdiagnostic(f(path_span)); - } + }; + err.subdiagnostic(f(generator_kind, path_span)); } } diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index 62c11e303b8..3f9bfc5373a 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -149,36 +149,6 @@ pub(crate) enum RequireStaticErr { }, } -#[derive(Subdiagnostic)] -#[label(borrowck_capture_kind_label)] -pub(crate) struct CaptureVarKind { - pub kind_desc: String, - #[primary_span] - pub kind_span: Span, -} - -#[derive(Subdiagnostic)] -pub(crate) enum CaptureVarCause { - #[label(borrowck_var_borrow_by_use_place)] - BorrowUsePlace { - place: String, - #[primary_span] - var_span: Span, - }, - #[label(borrowck_var_borrow_by_use_place_in_generator)] - BorrowUsePlaceGenerator { - place: String, - #[primary_span] - var_span: Span, - }, - #[label(borrowck_var_borrow_by_use_place_in_closure)] - BorrowUsePlaceClosure { - place: String, - #[primary_span] - var_span: Span, - }, -} - #[derive(Subdiagnostic)] pub(crate) enum CaptureVarPathUseCause { #[label(borrowck_borrow_due_to_use_generator)] @@ -222,3 +192,38 @@ pub(crate) enum CaptureVarPathUseCause { path_span: Span, }, } + +#[derive(Subdiagnostic)] +pub(crate) enum CaptureVarKind { + #[label(borrowck_capture_immute)] + Immute { + #[primary_span] + kind_span: Span, + }, + #[label(borrowck_capture_mut)] + Mut { + #[primary_span] + kind_span: Span, + }, + #[label(borrowck_capture_move)] + Move { + #[primary_span] + kind_span: Span, + }, +} + +#[derive(Subdiagnostic)] +pub(crate) enum CaptureVarCause { + #[label(borrowck_var_borrow_by_use_place_in_generator)] + BorrowUsePlaceGenerator { + place: String, + #[primary_span] + var_span: Span, + }, + #[label(borrowck_var_borrow_by_use_place_in_closure)] + BorrowUsePlaceClosure { + place: String, + #[primary_span] + var_span: Span, + }, +} diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl index 5d6617d5bcc..e3174360c90 100644 --- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl @@ -94,3 +94,18 @@ borrowck_assign_due_to_use_closure = borrowck_assign_part_due_to_use_closure = assign to part occurs due to use in closure + +borrowck_capture_immute = + capture is immutable because of use here + +borrowck_capture_mut = + capture is mutable because of use here + +borrowck_capture_move = + capture is moved because of use here + +borrowck_var_move_by_use_place_in_generator = + move occurs due to use of {$place} in generator + +borrowck_var_move_by_use_place_in_closure = + move occurs due to use of {$place} in closure diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 0a96d23e354..35675313b48 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1898,6 +1898,7 @@ impl BorrowKind { } } + // FIXME: won't be used after diagnostic migration pub fn describe_mutability(&self) -> &str { match *self { BorrowKind::Shared | BorrowKind::Shallow | BorrowKind::Unique => "immutable",