diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs index 25ed7859d2187..8eaa8fb7e1db0 100644 --- a/compiler/rustc_mir/src/transform/check_consts/ops.rs +++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs @@ -235,7 +235,8 @@ impl NonConstOp for CellBorrow { } #[derive(Debug)] -pub struct MutBorrow; +pub struct MutBorrow(pub hir::BorrowKind); + impl NonConstOp for MutBorrow { fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status { // Forbid everywhere except in const fn with a feature gate @@ -247,22 +248,28 @@ impl NonConstOp for MutBorrow { } fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + let raw = match self.0 { + hir::BorrowKind::Raw => "raw ", + hir::BorrowKind::Ref => "", + }; + let mut err = if ccx.const_kind() == hir::ConstContext::ConstFn { feature_err( &ccx.tcx.sess.parse_sess, sym::const_mut_refs, span, - &format!("mutable references are not allowed in {}s", ccx.const_kind()), + &format!("{}mutable references are not allowed in {}s", raw, ccx.const_kind()), ) } else { let mut err = struct_span_err!( ccx.tcx.sess, span, E0764, - "mutable references are not allowed in {}s", + "{}mutable references are not allowed in {}s", + raw, ccx.const_kind(), ); - err.span_label(span, format!("`&mut` is only allowed in `const fn`")); + err.span_label(span, format!("`&{}mut` is only allowed in `const fn`", raw)); err }; if ccx.tcx.sess.teach(&err.get_code().unwrap()) { @@ -281,29 +288,6 @@ impl NonConstOp for MutBorrow { } } -// FIXME(ecstaticmorse): Unify this with `MutBorrow`. It has basically the same issues. -#[derive(Debug)] -pub struct MutAddressOf; -impl NonConstOp for MutAddressOf { - fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status { - // Forbid everywhere except in const fn with a feature gate - if ccx.const_kind() == hir::ConstContext::ConstFn { - Status::Unstable(sym::const_mut_refs) - } else { - Status::Forbidden - } - } - - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { - feature_err( - &ccx.tcx.sess.parse_sess, - sym::const_mut_refs, - span, - &format!("`&raw mut` is not allowed in {}s", ccx.const_kind()), - ) - } -} - #[derive(Debug)] pub struct MutDeref; impl NonConstOp for MutDeref { diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs index ab63fd03a336e..462fafcf1b58c 100644 --- a/compiler/rustc_mir/src/transform/check_consts/validation.rs +++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs @@ -522,14 +522,16 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> { if !is_allowed { if let BorrowKind::Mut { .. } = kind { - self.check_op(ops::MutBorrow); + self.check_op(ops::MutBorrow(hir::BorrowKind::Ref)); } else { self.check_op(ops::CellBorrow); } } } - Rvalue::AddressOf(Mutability::Mut, _) => self.check_op(ops::MutAddressOf), + Rvalue::AddressOf(Mutability::Mut, _) => { + self.check_op(ops::MutBorrow(hir::BorrowKind::Raw)) + } Rvalue::Ref(_, BorrowKind::Shared | BorrowKind::Shallow, ref place) | Rvalue::AddressOf(Mutability::Not, ref place) => { diff --git a/src/test/ui/consts/const-address-of-mut.rs b/src/test/ui/consts/const-address-of-mut.rs index fe9188cb4904c..3788088b810b9 100644 --- a/src/test/ui/consts/const-address-of-mut.rs +++ b/src/test/ui/consts/const-address-of-mut.rs @@ -1,14 +1,14 @@ #![feature(raw_ref_op)] -const A: () = { let mut x = 2; &raw mut x; }; //~ ERROR `&raw mut` is not allowed +const A: () = { let mut x = 2; &raw mut x; }; //~ mutable reference -static B: () = { let mut x = 2; &raw mut x; }; //~ ERROR `&raw mut` is not allowed +static B: () = { let mut x = 2; &raw mut x; }; //~ mutable reference -static mut C: () = { let mut x = 2; &raw mut x; }; //~ ERROR `&raw mut` is not allowed +static mut C: () = { let mut x = 2; &raw mut x; }; //~ mutable reference const fn foo() { let mut x = 0; - let y = &raw mut x; //~ ERROR `&raw mut` is not allowed + let y = &raw mut x; //~ mutable reference } fn main() {} diff --git a/src/test/ui/consts/const-address-of-mut.stderr b/src/test/ui/consts/const-address-of-mut.stderr index 1d9a325b0c2a0..ec2dac5a7d16f 100644 --- a/src/test/ui/consts/const-address-of-mut.stderr +++ b/src/test/ui/consts/const-address-of-mut.stderr @@ -1,31 +1,22 @@ -error[E0658]: `&raw mut` is not allowed in constants +error[E0764]: raw mutable references are not allowed in constants --> $DIR/const-address-of-mut.rs:3:32 | LL | const A: () = { let mut x = 2; &raw mut x; }; - | ^^^^^^^^^^ - | - = note: see issue #57349 for more information - = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable + | ^^^^^^^^^^ `&raw mut` is only allowed in `const fn` -error[E0658]: `&raw mut` is not allowed in statics +error[E0764]: raw mutable references are not allowed in statics --> $DIR/const-address-of-mut.rs:5:33 | LL | static B: () = { let mut x = 2; &raw mut x; }; - | ^^^^^^^^^^ - | - = note: see issue #57349 for more information - = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable + | ^^^^^^^^^^ `&raw mut` is only allowed in `const fn` -error[E0658]: `&raw mut` is not allowed in statics +error[E0764]: raw mutable references are not allowed in statics --> $DIR/const-address-of-mut.rs:7:37 | LL | static mut C: () = { let mut x = 2; &raw mut x; }; - | ^^^^^^^^^^ - | - = note: see issue #57349 for more information - = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable + | ^^^^^^^^^^ `&raw mut` is only allowed in `const fn` -error[E0658]: `&raw mut` is not allowed in constant functions +error[E0658]: raw mutable references are not allowed in constant functions --> $DIR/const-address-of-mut.rs:11:13 | LL | let y = &raw mut x; @@ -36,4 +27,5 @@ LL | let y = &raw mut x; error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0658`. +Some errors have detailed explanations: E0658, E0764. +For more information about an error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/min_const_fn/address_of.rs b/src/test/ui/consts/min_const_fn/address_of.rs index f8506d70b2498..40d1882d7d2ad 100644 --- a/src/test/ui/consts/min_const_fn/address_of.rs +++ b/src/test/ui/consts/min_const_fn/address_of.rs @@ -2,7 +2,7 @@ const fn mutable_address_of_in_const() { let mut a = 0; - let b = &raw mut a; //~ ERROR `&raw mut` is not allowed + let b = &raw mut a; //~ ERROR mutable reference } struct X; @@ -10,7 +10,7 @@ struct X; impl X { const fn inherent_mutable_address_of_in_const() { let mut a = 0; - let b = &raw mut a; //~ ERROR `&raw mut` is not allowed + let b = &raw mut a; //~ ERROR mutable reference } } diff --git a/src/test/ui/consts/min_const_fn/address_of.stderr b/src/test/ui/consts/min_const_fn/address_of.stderr index 4d9d1d79284a8..facc566513c28 100644 --- a/src/test/ui/consts/min_const_fn/address_of.stderr +++ b/src/test/ui/consts/min_const_fn/address_of.stderr @@ -1,4 +1,4 @@ -error[E0658]: `&raw mut` is not allowed in constant functions +error[E0658]: raw mutable references are not allowed in constant functions --> $DIR/address_of.rs:5:13 | LL | let b = &raw mut a; @@ -7,7 +7,7 @@ LL | let b = &raw mut a; = note: see issue #57349 for more information = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable -error[E0658]: `&raw mut` is not allowed in constant functions +error[E0658]: raw mutable references are not allowed in constant functions --> $DIR/address_of.rs:13:17 | LL | let b = &raw mut a;