Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unify const-checking structured errors for &mut and &raw mut #77420

Merged
merged 2 commits into from
Oct 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -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
Expand All @@ -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()) {
Expand All @@ -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 {
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 @@ -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) => {
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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this test's annotations still have ERROR in them?

Suggested change
const A: () = { let mut x = 2; &raw mut x; }; //~ mutable reference
const A: () = { let mut x = 2; &raw mut x; }; //~ ERROR mutable reference

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was under the impression that it was required for the annotation.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's good to have but not a necessity iirc.


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