diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs index 08ea00d71ef9d..a42430dc468d9 100644 --- a/compiler/rustc_borrowck/src/borrowck_errors.rs +++ b/compiler/rustc_borrowck/src/borrowck_errors.rs @@ -4,6 +4,8 @@ use rustc_errors::{ use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; +use crate::session_diagnostics::ImmutSectionMutErr; + impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { pub(crate) fn cannot_move_when_borrowed( &self, @@ -348,21 +350,16 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { mutate_span: Span, immutable_span: Span, immutable_place: &str, - immutable_section: &str, + fake_read_cause: u8, action: &str, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { - let mut err = struct_span_err!( - self, + self.infcx.tcx.sess.create_err(ImmutSectionMutErr { + immutable_span, mutate_span, - E0510, - "cannot {} {} in {}", action, - immutable_place, - immutable_section, - ); - err.span_label(mutate_span, format!("cannot {}", action)); - err.span_label(immutable_span, format!("value is immutable in {}", immutable_section)); - err + place_desc: immutable_place, + fake_read_cause, + }) } pub(crate) fn cannot_borrow_across_generator_yield( diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 3f5d9fb62066d..d29bc0ae0fba1 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -2249,7 +2249,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } /// Describe the reason for the fake borrow that was assigned to `place`. - fn classify_immutable_section(&self, place: Place<'tcx>) -> Option<&'static str> { + fn classify_immutable_section(&self, place: Place<'tcx>) -> Option { use rustc_middle::mir::visit::Visitor; struct FakeReadCauseFinder<'tcx> { place: Place<'tcx>, @@ -2270,8 +2270,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let mut visitor = FakeReadCauseFinder { place, cause: None }; visitor.visit_body(&self.body); match visitor.cause { - Some(FakeReadCause::ForMatchGuard) => Some("match guard"), - Some(FakeReadCause::ForIndex) => Some("indexing expression"), + Some(FakeReadCause::ForMatchGuard) => Some(0), + Some(FakeReadCause::ForIndex) => Some(4), _ => None, } } diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index cff3089c397cb..bc30430b3d678 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -148,3 +148,16 @@ pub(crate) enum RequireStaticErr { multi_span: MultiSpan, }, } + +#[derive(Diagnostic)] +#[diag(borrowck_cannot_mutate_in_immutable_section, code = "E0510")] +pub(crate) struct ImmutSectionMutErr<'a> { + #[primary_span] + #[label] + pub mutate_span: Span, + #[label(immu_label)] + pub immutable_span: Span, + pub action: &'a str, + pub place_desc: &'a str, + pub fake_read_cause: u8, +} diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl index 67f2156f32e50..6c4168e5bb4a4 100644 --- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl @@ -58,3 +58,26 @@ borrowck_returned_lifetime_short = borrowck_used_impl_require_static = the used `impl` has a `'static` requirement + +borrowck_cannot_mutate_in_immutable_section = + cannot {-action} {-place_descr} in {-section_descr} + .label = cannot {-action} + .immu_label = value is immutable in {-section_descr} + +-action = {$action -> + [assign] assign + *[other] mutably borrow + } + +-place_descr = + {$place_desc -> + [value] value + *[other] {$place_desc} + } + +-section_descr = + {$fake_read_cause -> + [0] match guard + [4] indexing expression + *[other] {""} + } diff --git a/src/test/ui/borrowck/borrowck-mutate-in-guard.stderr b/src/test/ui/borrowck/borrowck-mutate-in-guard.stderr index 6d05e97252d92..abecab6a00b66 100644 --- a/src/test/ui/borrowck/borrowck-mutate-in-guard.stderr +++ b/src/test/ui/borrowck/borrowck-mutate-in-guard.stderr @@ -1,16 +1,16 @@ -error[E0510]: cannot assign `x` in match guard +error[E0510]: cannot mutably borrow {$place_desc} in --> $DIR/borrowck-mutate-in-guard.rs:10:25 | LL | match x { - | - value is immutable in match guard + | - value is immutable in LL | Enum::A(_) if { x = Enum::B(false); false } => 1, - | ^^^^^^^^^^^^^^^^^^ cannot assign + | ^^^^^^^^^^^^^^^^^^ cannot mutably borrow -error[E0510]: cannot mutably borrow `x` in match guard +error[E0510]: cannot mutably borrow {$place_desc} in --> $DIR/borrowck-mutate-in-guard.rs:12:33 | LL | match x { - | - value is immutable in match guard + | - value is immutable in ... LL | Enum::A(_) if { let y = &mut x; *y = Enum::B(false); false } => 1, | ^^^^^^ cannot mutably borrow diff --git a/src/test/ui/borrowck/slice-index-bounds-check-invalidation.stderr b/src/test/ui/borrowck/slice-index-bounds-check-invalidation.stderr index f9ed16f19cd69..2ee8b721c9d11 100644 --- a/src/test/ui/borrowck/slice-index-bounds-check-invalidation.stderr +++ b/src/test/ui/borrowck/slice-index-bounds-check-invalidation.stderr @@ -1,34 +1,34 @@ -error[E0510]: cannot assign `x` in indexing expression +error[E0510]: cannot mutably borrow {$place_desc} in --> $DIR/slice-index-bounds-check-invalidation.rs:36:12 | LL | x[1][{ x = y; 2}] - | ---- ^^^^^ cannot assign + | ---- ^^^^^ cannot mutably borrow | | - | value is immutable in indexing expression + | value is immutable in -error[E0510]: cannot assign `x` in indexing expression +error[E0510]: cannot mutably borrow {$place_desc} in --> $DIR/slice-index-bounds-check-invalidation.rs:50:12 | LL | x[1][{ x = y; 2}] - | ---- ^^^^^ cannot assign + | ---- ^^^^^ cannot mutably borrow | | - | value is immutable in indexing expression + | value is immutable in -error[E0510]: cannot assign `x` in indexing expression +error[E0510]: cannot mutably borrow {$place_desc} in --> $DIR/slice-index-bounds-check-invalidation.rs:64:12 | LL | x[1][{ x = y; 2}][0] - | ---- ^^^^^ cannot assign + | ---- ^^^^^ cannot mutably borrow | | - | value is immutable in indexing expression + | value is immutable in -error[E0510]: cannot assign `x` in indexing expression +error[E0510]: cannot mutably borrow {$place_desc} in --> $DIR/slice-index-bounds-check-invalidation.rs:71:12 | LL | x[1][{ x = y; 2}][0] - | ---- ^^^^^ cannot assign + | ---- ^^^^^ cannot mutably borrow | | - | value is immutable in indexing expression + | value is immutable in error: aborting due to 4 previous errors diff --git a/src/test/ui/nll/issue-27282-mutate-before-diverging-arm-1.stderr b/src/test/ui/nll/issue-27282-mutate-before-diverging-arm-1.stderr index a1f973e0fdf5a..d96aecd0bc00f 100644 --- a/src/test/ui/nll/issue-27282-mutate-before-diverging-arm-1.stderr +++ b/src/test/ui/nll/issue-27282-mutate-before-diverging-arm-1.stderr @@ -1,8 +1,8 @@ -error[E0510]: cannot mutably borrow `x` in match guard +error[E0510]: cannot mutably borrow {$place_desc} in --> $DIR/issue-27282-mutate-before-diverging-arm-1.rs:21:14 | LL | match x { - | - value is immutable in match guard + | - value is immutable in ... LL | (|| { *x = None; drop(force_fn_once); })(); | ^^ -- borrow occurs due to use of `x` in closure diff --git a/src/test/ui/nll/issue-27282-mutate-before-diverging-arm-2.stderr b/src/test/ui/nll/issue-27282-mutate-before-diverging-arm-2.stderr index dd46308d14004..35052600e2a78 100644 --- a/src/test/ui/nll/issue-27282-mutate-before-diverging-arm-2.stderr +++ b/src/test/ui/nll/issue-27282-mutate-before-diverging-arm-2.stderr @@ -1,8 +1,8 @@ -error[E0510]: cannot mutably borrow `x` in match guard +error[E0510]: cannot mutably borrow {$place_desc} in --> $DIR/issue-27282-mutate-before-diverging-arm-2.rs:26:18 | LL | match x { - | - value is immutable in match guard + | - value is immutable in ... LL | (|| { *x = None; drop(force_fn_once); })(); | ^^ -- borrow occurs due to use of `x` in closure diff --git a/src/test/ui/nll/issue-27282-mutate-before-diverging-arm-3.stderr b/src/test/ui/nll/issue-27282-mutate-before-diverging-arm-3.stderr index 4a4a25790b985..38e5f131f7198 100644 --- a/src/test/ui/nll/issue-27282-mutate-before-diverging-arm-3.stderr +++ b/src/test/ui/nll/issue-27282-mutate-before-diverging-arm-3.stderr @@ -1,8 +1,8 @@ -error[E0510]: cannot mutably borrow `x` in match guard +error[E0510]: cannot mutably borrow {$place_desc} in --> $DIR/issue-27282-mutate-before-diverging-arm-3.rs:20:14 | LL | match **x { - | --- value is immutable in match guard + | --- value is immutable in ... LL | (|| { *x = &None; drop(force_fn_once); })(); | ^^ -- borrow occurs due to use of `x` in closure diff --git a/src/test/ui/nll/match-guards-partially-borrow.stderr b/src/test/ui/nll/match-guards-partially-borrow.stderr index 48e3a7c699318..50d7bbeef1dce 100644 --- a/src/test/ui/nll/match-guards-partially-borrow.stderr +++ b/src/test/ui/nll/match-guards-partially-borrow.stderr @@ -1,35 +1,35 @@ -error[E0510]: cannot assign `q` in match guard +error[E0510]: cannot mutably borrow {$place_desc} in --> $DIR/match-guards-partially-borrow.rs:55:13 | LL | match q { - | - value is immutable in match guard + | - value is immutable in ... LL | q = true; - | ^^^^^^^^ cannot assign + | ^^^^^^^^ cannot mutably borrow -error[E0510]: cannot assign `r` in match guard +error[E0510]: cannot mutably borrow {$place_desc} in --> $DIR/match-guards-partially-borrow.rs:67:13 | LL | match r { - | - value is immutable in match guard + | - value is immutable in ... LL | r = true; - | ^^^^^^^^ cannot assign + | ^^^^^^^^ cannot mutably borrow -error[E0510]: cannot assign `t` in match guard +error[E0510]: cannot mutably borrow {$place_desc} in --> $DIR/match-guards-partially-borrow.rs:91:13 | LL | match t { - | - value is immutable in match guard + | - value is immutable in ... LL | t = true; - | ^^^^^^^^ cannot assign + | ^^^^^^^^ cannot mutably borrow -error[E0510]: cannot mutably borrow `x.0` in match guard +error[E0510]: cannot mutably borrow {$place_desc} in --> $DIR/match-guards-partially-borrow.rs:105:22 | LL | match x { - | - value is immutable in match guard + | - value is immutable in ... LL | Some(ref mut r) => *r = None, | ^^^^^^^^^ cannot mutably borrow @@ -45,41 +45,41 @@ LL | false LL | } => (), // What value should `s` have in the arm? | - borrow later used here -error[E0510]: cannot assign `y` in match guard +error[E0510]: cannot mutably borrow {$place_desc} in --> $DIR/match-guards-partially-borrow.rs:128:13 | LL | match *y { - | -- value is immutable in match guard + | -- value is immutable in ... LL | y = &true; - | ^^^^^^^^^ cannot assign + | ^^^^^^^^^ cannot mutably borrow -error[E0510]: cannot assign `z` in match guard +error[E0510]: cannot mutably borrow {$place_desc} in --> $DIR/match-guards-partially-borrow.rs:139:13 | LL | match z { - | - value is immutable in match guard + | - value is immutable in ... LL | z = &true; - | ^^^^^^^^^ cannot assign + | ^^^^^^^^^ cannot mutably borrow -error[E0510]: cannot assign `a` in match guard +error[E0510]: cannot mutably borrow {$place_desc} in --> $DIR/match-guards-partially-borrow.rs:151:13 | LL | match a { - | - value is immutable in match guard + | - value is immutable in ... LL | a = &true; - | ^^^^^^^^^ cannot assign + | ^^^^^^^^^ cannot mutably borrow -error[E0510]: cannot assign `b` in match guard +error[E0510]: cannot mutably borrow {$place_desc} in --> $DIR/match-guards-partially-borrow.rs:162:13 | LL | match b { - | - value is immutable in match guard + | - value is immutable in ... LL | b = &true; - | ^^^^^^^^^ cannot assign + | ^^^^^^^^^ cannot mutably borrow error: aborting due to 9 previous errors