Skip to content

Commit 683f5c9

Browse files
committed
Disallow cell borrowing
1 parent e31a136 commit 683f5c9

File tree

2 files changed

+36
-27
lines changed

2 files changed

+36
-27
lines changed

src/librustc_mir/transform/check_consts/ops.rs

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! Concrete error types for all operations which may be invalid in a certain const context.
22
33
use rustc::hir::def_id::DefId;
4-
use rustc::mir::BorrowKind;
54
use rustc::session::config::nightly_options;
65
use rustc::ty::TyCtxt;
76
use syntax::feature_gate::feature_err;
@@ -181,36 +180,39 @@ impl NonConstOp for Loop {
181180
}
182181

183182
#[derive(Debug)]
184-
pub struct MutBorrow(pub BorrowKind);
183+
pub struct CellBorrow;
184+
impl NonConstOp for CellBorrow {
185+
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
186+
span_err!(item.tcx.sess, span, E0492,
187+
"cannot borrow a constant which may contain \
188+
interior mutability, create a static instead");
189+
}
190+
}
191+
192+
#[derive(Debug)]
193+
pub struct MutBorrow;
185194
impl NonConstOp for MutBorrow {
186195
fn feature_gate(tcx: TyCtxt<'_>) -> Option<bool> {
187196
Some(tcx.features().const_mut_refs)
188197
}
189198

190199
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
191-
let kind = self.0;
192-
if let BorrowKind::Mut { .. } = kind {
193-
let mut err = struct_span_err!(item.tcx.sess, span, E0017,
194-
"references in {}s may only refer \
195-
to immutable values", item.const_kind());
196-
err.span_label(span, format!("{}s require immutable values",
197-
item.const_kind()));
198-
if item.tcx.sess.teach(&err.get_code().unwrap()) {
199-
err.note("References in statics and constants may only refer \
200-
to immutable values.\n\n\
201-
Statics are shared everywhere, and if they refer to \
202-
mutable data one might violate memory safety since \
203-
holding multiple mutable references to shared data \
204-
is not allowed.\n\n\
205-
If you really want global mutable state, try using \
206-
static mut or a global UnsafeCell.");
207-
}
208-
err.emit();
209-
} else {
210-
span_err!(item.tcx.sess, span, E0492,
211-
"cannot borrow a constant which may contain \
212-
interior mutability, create a static instead");
200+
let mut err = struct_span_err!(item.tcx.sess, span, E0017,
201+
"references in {}s may only refer \
202+
to immutable values", item.const_kind());
203+
err.span_label(span, format!("{}s require immutable values",
204+
item.const_kind()));
205+
if item.tcx.sess.teach(&err.get_code().unwrap()) {
206+
err.note("References in statics and constants may only refer \
207+
to immutable values.\n\n\
208+
Statics are shared everywhere, and if they refer to \
209+
mutable data one might violate memory safety since \
210+
holding multiple mutable references to shared data \
211+
is not allowed.\n\n\
212+
If you really want global mutable state, try using \
213+
static mut or a global UnsafeCell.");
213214
}
215+
err.emit();
214216
}
215217
}
216218

src/librustc_mir/transform/check_consts/validation.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,11 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
360360
};
361361

362362
if !is_allowed {
363-
self.check_op(ops::MutBorrow(kind));
363+
if let BorrowKind::Mut{ .. } = kind {
364+
self.check_op(ops::MutBorrow);
365+
} else {
366+
self.check_op(ops::CellBorrow);
367+
}
364368
}
365369
}
366370

@@ -385,7 +389,11 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
385389
);
386390

387391
if borrowed_place_has_mut_interior {
388-
self.check_op(ops::MutBorrow(kind));
392+
if let BorrowKind::Mut{ .. } = kind {
393+
self.check_op(ops::MutBorrow);
394+
} else {
395+
self.check_op(ops::CellBorrow);
396+
}
389397
}
390398
}
391399

@@ -452,7 +460,6 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
452460
}
453461
}
454462
}
455-
456463
fn visit_projection_elem(
457464
&mut self,
458465
place_base: &PlaceBase<'tcx>,

0 commit comments

Comments
 (0)