Skip to content

Commit

Permalink
Rollup merge of #77420 - ecstatic-morse:const-checking-raw-mut-ref, r…
Browse files Browse the repository at this point in the history
…=davidtwco

Unify const-checking structured errors for `&mut` and `&raw mut`

Resolves #77414 as well as a FIXME.
  • Loading branch information
JohnTitor committed Oct 22, 2020
2 parents 1eaadeb + c1494d6 commit 6245b95
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 54 deletions.
38 changes: 11 additions & 27 deletions compiler/rustc_mir/src/transform/check_consts/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,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
Expand All @@ -236,22 +237,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()) {
Expand All @@ -270,29 +277,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 {
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_mir/src/transform/check_consts/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -525,14 +525,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) => {
Expand Down
8 changes: 4 additions & 4 deletions src/test/ui/consts/const-address-of-mut.rs
Original file line number Diff line number Diff line change
@@ -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() {}
26 changes: 9 additions & 17 deletions src/test/ui/consts/const-address-of-mut.stderr
Original file line number Diff line number Diff line change
@@ -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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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;
Expand All @@ -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`.
4 changes: 2 additions & 2 deletions src/test/ui/consts/min_const_fn/address_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

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;

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
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/consts/min_const_fn/address_of.stderr
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -7,7 +7,7 @@ LL | let b = &raw mut a;
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/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;
Expand Down

0 comments on commit 6245b95

Please sign in to comment.