1
Fork 0

Unify &mut and &raw mut const-checking errors

This commit is contained in:
Dylan MacKenzie 2020-10-01 11:03:16 -07:00
parent 2ad6187ce5
commit 77e6c56ab6
2 changed files with 15 additions and 29 deletions

View file

@ -235,7 +235,8 @@ impl NonConstOp for CellBorrow {
} }
#[derive(Debug)] #[derive(Debug)]
pub struct MutBorrow; pub struct MutBorrow(pub hir::BorrowKind);
impl NonConstOp for MutBorrow { impl NonConstOp for MutBorrow {
fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status { fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
// Forbid everywhere except in const fn with a feature gate // 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> { 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 { let mut err = if ccx.const_kind() == hir::ConstContext::ConstFn {
feature_err( feature_err(
&ccx.tcx.sess.parse_sess, &ccx.tcx.sess.parse_sess,
sym::const_mut_refs, sym::const_mut_refs,
span, 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 { } else {
let mut err = struct_span_err!( let mut err = struct_span_err!(
ccx.tcx.sess, ccx.tcx.sess,
span, span,
E0764, E0764,
"mutable references are not allowed in {}s", "{}mutable references are not allowed in {}s",
raw,
ccx.const_kind(), 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 err
}; };
if ccx.tcx.sess.teach(&err.get_code().unwrap()) { 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)] #[derive(Debug)]
pub struct MutDeref; pub struct MutDeref;
impl NonConstOp for MutDeref { impl NonConstOp for MutDeref {

View file

@ -522,14 +522,16 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
if !is_allowed { if !is_allowed {
if let BorrowKind::Mut { .. } = kind { if let BorrowKind::Mut { .. } = kind {
self.check_op(ops::MutBorrow); self.check_op(ops::MutBorrow(hir::BorrowKind::Ref));
} else { } else {
self.check_op(ops::CellBorrow); 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::Ref(_, BorrowKind::Shared | BorrowKind::Shallow, ref place)
| Rvalue::AddressOf(Mutability::Not, ref place) => { | Rvalue::AddressOf(Mutability::Not, ref place) => {