Skip to content

Commit ae9677c

Browse files
spastorinomatthewjasper
authored andcommitted
Readjust const qualification to detect statics again
1 parent a1d04cc commit ae9677c

File tree

6 files changed

+46
-28
lines changed

6 files changed

+46
-28
lines changed

src/librustc/mir/mod.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use crate::hir::def::{CtorKind, Namespace};
88
use crate::hir::def_id::DefId;
99
use crate::hir;
10-
use crate::mir::interpret::{PanicInfo, Scalar};
10+
use crate::mir::interpret::{ConstValue, GlobalAlloc, PanicInfo, Scalar};
1111
use crate::mir::visit::MirVisitable;
1212
use crate::ty::adjustment::PointerCast;
1313
use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
@@ -2341,6 +2341,24 @@ pub struct Constant<'tcx> {
23412341
pub literal: &'tcx ty::Const<'tcx>,
23422342
}
23432343

2344+
impl Constant<'tcx> {
2345+
pub fn check_static_ptr(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
2346+
match self.literal.val {
2347+
ConstValue::Scalar(Scalar::Ptr(ptr)) => match tcx.alloc_map.lock().get(ptr.alloc_id) {
2348+
Some(GlobalAlloc::Static(def_id)) => Some(def_id),
2349+
Some(_) => None,
2350+
None => {
2351+
tcx.sess.delay_span_bug(
2352+
DUMMY_SP, "MIR cannot contain dangling const pointers",
2353+
);
2354+
None
2355+
},
2356+
},
2357+
_ => None,
2358+
}
2359+
}
2360+
}
2361+
23442362
/// A collection of projections into user types.
23452363
///
23462364
/// They are projections because a binding can occur a part of a

src/librustc_mir/transform/check_consts/qualifs.rs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
use rustc::mir::*;
44
use rustc::ty::{self, Ty};
5+
use rustc::hir::def_id::DefId;
56
use syntax_pos::DUMMY_SP;
67

78
use super::{ConstKind, Item as ConstCx};
@@ -32,7 +33,7 @@ pub trait Qualif {
3233
/// of the type.
3334
fn in_any_value_of_ty(_cx: &ConstCx<'_, 'tcx>, _ty: Ty<'tcx>) -> bool;
3435

35-
fn in_static(_cx: &ConstCx<'_, 'tcx>, _static: &Static<'tcx>) -> bool {
36+
fn in_static(_cx: &ConstCx<'_, 'tcx>, _def_id: DefId) -> bool {
3637
// FIXME(eddyb) should we do anything here for value properties?
3738
false
3839
}
@@ -86,18 +87,9 @@ pub trait Qualif {
8687
projection: [],
8788
} => per_local(*local),
8889
PlaceRef {
89-
base: PlaceBase::Static(box Static {
90-
kind: StaticKind::Promoted(..),
91-
..
92-
}),
90+
base: PlaceBase::Static(_),
9391
projection: [],
9492
} => bug!("qualifying already promoted MIR"),
95-
PlaceRef {
96-
base: PlaceBase::Static(static_),
97-
projection: [],
98-
} => {
99-
Self::in_static(cx, static_)
100-
},
10193
PlaceRef {
10294
base: _,
10395
projection: [.., _],
@@ -115,7 +107,9 @@ pub trait Qualif {
115107
Operand::Move(ref place) => Self::in_place(cx, per_local, place.as_ref()),
116108

117109
Operand::Constant(ref constant) => {
118-
if let ty::ConstKind::Unevaluated(def_id, _) = constant.literal.val {
110+
if let Some(static_) = constant.check_static_ptr(cx.tcx) {
111+
Self::in_static(cx, static_)
112+
} else if let ty::ConstKind::Unevaluated(def_id, _) = constant.literal.val {
119113
// Don't peek inside trait associated constants.
120114
if cx.tcx.trait_of_item(def_id).is_some() {
121115
Self::in_any_value_of_ty(cx, constant.literal.ty)

src/librustc_mir/transform/check_consts/validation.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -408,12 +408,21 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
408408

409409
match place_base {
410410
PlaceBase::Local(_) => {}
411-
PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_, _), .. }) => {
411+
PlaceBase::Static(_) => {
412412
bug!("Promotion must be run after const validation");
413413
}
414+
}
415+
}
414416

415-
PlaceBase::Static(box Static{ kind: StaticKind::Static, def_id, .. }) => {
416-
let is_thread_local = self.tcx.has_attr(*def_id, sym::thread_local);
417+
fn visit_operand(
418+
&mut self,
419+
op: &Operand<'tcx>,
420+
location: Location,
421+
) {
422+
self.super_operand(op, location);
423+
if let Operand::Constant(c) = op {
424+
if let Some(def_id) = c.check_static_ptr(self.tcx) {
425+
let is_thread_local = self.tcx.has_attr(def_id, sym::thread_local);
417426
if is_thread_local {
418427
self.check_op(ops::ThreadLocalAccess);
419428
} else if self.const_kind() != ConstKind::Static || !context.is_mutating_use() {

src/librustc_mir/transform/qualify_min_const_fn.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,10 @@ fn check_operand(
249249
Operand::Move(place) | Operand::Copy(place) => {
250250
check_place(tcx, place, span, def_id, body)
251251
}
252-
Operand::Constant(_) => Ok(()),
252+
Operand::Constant(c) => match c.check_static_ptr(tcx) {
253+
Some(_) => Err((span, "cannot access `static` items in const fn".into())),
254+
None => Ok(()),
255+
},
253256
}
254257
}
255258

@@ -285,13 +288,7 @@ fn check_place(
285288
}
286289
}
287290

288-
match place.base {
289-
PlaceBase::Static(box Static { kind: StaticKind::Static, .. }) => {
290-
Err((span, "cannot access `static` items in const fn".into()))
291-
}
292-
PlaceBase::Local(_)
293-
| PlaceBase::Static(box Static { kind: StaticKind::Promoted(_, _), .. }) => Ok(()),
294-
}
291+
Ok(())
295292
}
296293

297294
/// Returns whether `allow_internal_unstable(..., <feature_gate>, ...)` is present.

src/test/ui/consts/const-fn-not-safe-for-const.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ LL | Y
1111
| ^
1212

1313
error[E0013]: constant functions cannot refer to statics, use a constant instead
14-
--> $DIR/const-fn-not-safe-for-const.rs:25:5
14+
--> $DIR/const-fn-not-safe-for-const.rs:25:6
1515
|
1616
LL | &Y
17-
| ^^
17+
| ^
1818

1919
error: aborting due to 3 previous errors
2020

src/test/ui/consts/min_const_fn/min_const_fn.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,10 @@ LL | const fn foo25() -> u32 { BAR }
116116
= help: add `#![feature(const_fn)]` to the crate attributes to enable
117117

118118
error[E0723]: cannot access `static` items in const fn
119-
--> $DIR/min_const_fn.rs:91:36
119+
--> $DIR/min_const_fn.rs:91:37
120120
|
121121
LL | const fn foo26() -> &'static u32 { &BAR }
122-
| ^^^^
122+
| ^^^
123123
|
124124
= note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
125125
= help: add `#![feature(const_fn)]` to the crate attributes to enable

0 commit comments

Comments
 (0)