Skip to content

Commit 752544b

Browse files
author
Saleem Jaffer
committed
adding mir::StaticKind enum for static and promoted
1 parent cf2f1bb commit 752544b

File tree

19 files changed

+238
-166
lines changed

19 files changed

+238
-166
lines changed

src/librustc/mir/mod.rs

+26-21
Original file line numberDiff line numberDiff line change
@@ -1915,19 +1915,22 @@ pub enum PlaceBase<'tcx> {
19151915
Static(Box<Static<'tcx>>),
19161916
}
19171917

1918-
/// The `DefId` of a static, along with its normalized type (which is
1919-
/// stored to avoid requiring normalization when reading MIR).
1918+
/// We store the normalized type to avoid requiring normalization when reading MIR
19201919
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
19211920
pub struct Static<'tcx> {
1922-
pub def_id: DefId,
19231921
pub ty: Ty<'tcx>,
1924-
pub promoted: Option<Promoted>,
1922+
pub kind: StaticKind,
1923+
}
1924+
1925+
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable, RustcEncodable, RustcDecodable)]
1926+
pub enum StaticKind {
1927+
Promoted(Promoted),
1928+
Static(DefId),
19251929
}
19261930

19271931
impl_stable_hash_for!(struct Static<'tcx> {
1928-
def_id,
19291932
ty,
1930-
promoted
1933+
kind
19311934
});
19321935

19331936
/// The `Projection` data structure defines things of the form `B.x`
@@ -2058,21 +2061,23 @@ impl<'tcx> Debug for Place<'tcx> {
20582061

20592062
match *self {
20602063
Base(PlaceBase::Local(id)) => write!(fmt, "{:?}", id),
2061-
Base(PlaceBase::Static(box self::Static { def_id, ty, promoted })) => {
2062-
match promoted {
2063-
None => write!(
2064-
fmt,
2065-
"({}: {:?})",
2066-
ty::tls::with(|tcx| tcx.def_path_str(def_id)),
2067-
ty
2068-
),
2069-
Some(pr) => write!(
2070-
fmt,
2071-
"({:?}: {:?})",
2072-
pr,
2073-
ty
2074-
),
2075-
}
2064+
Base(PlaceBase::Static(box self::Static { ty, kind: StaticKind::Static(def_id) })) => {
2065+
write!(
2066+
fmt,
2067+
"({}: {:?})",
2068+
ty::tls::with(|tcx| tcx.def_path_str(def_id)),
2069+
ty
2070+
)
2071+
},
2072+
Base(PlaceBase::Static(
2073+
box self::Static { ty, kind: StaticKind::Promoted(promoted) })
2074+
) => {
2075+
write!(
2076+
fmt,
2077+
"({:?}: {:?})",
2078+
promoted,
2079+
ty
2080+
)
20762081
},
20772082
Projection(ref data) => match data.elem {
20782083
ProjectionElem::Downcast(ref adt_def, index) => {

src/librustc/mir/visit.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -725,15 +725,18 @@ macro_rules! make_mir_visitor {
725725
place: & $($mutability)? Place<'tcx>,
726726
context: PlaceContext<'tcx>,
727727
location: Location) {
728+
use crate::mir::{Static, StaticKind};
728729
match place {
729730
Place::Base(PlaceBase::Local(local)) => {
730731
self.visit_local(local, context, location);
731732
}
732-
Place::Base(PlaceBase::Static(static_)) => {
733-
if static_.promoted.is_none() {
734-
self.visit_def_id(& $($mutability)? static_.def_id, location);
735-
}
736-
self.visit_ty(& $($mutability)? static_.ty, TyContext::Location(location));
733+
Place::Base(
734+
PlaceBase::Static(box Static{kind: StaticKind::Static(def_id), ..})
735+
) => {
736+
self.visit_def_id(& $($mutability)? *def_id, location)
737+
}
738+
Place::Base(PlaceBase::Static(box Static{ty, ..})) => {
739+
self.visit_ty(& $($mutability)? *ty, TyContext::Location(location));
737740
}
738741
Place::Projection(proj) => {
739742
self.visit_projection(proj, context, location);

src/librustc_codegen_ssa/mir/block.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use rustc::middle::lang_items;
22
use rustc::ty::{self, Ty, TypeFoldable};
33
use rustc::ty::layout::{self, LayoutOf, HasTyCtxt};
4-
use rustc::mir::{self, Place, PlaceBase};
4+
use rustc::mir::{self, Place, PlaceBase, Static, StaticKind};
55
use rustc::mir::interpret::EvalErrorKind;
66
use rustc_target::abi::call::{ArgType, FnType, PassMode, IgnoreMode};
77
use rustc_target::spec::abi::Abi;
@@ -621,14 +621,18 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
621621
// but specified directly in the code. This means it gets promoted
622622
// and we can then extract the value by evaluating the promoted.
623623
mir::Operand::Copy(
624-
Place::Base(PlaceBase::Static(
625-
box mir::Static {promoted: Some(promoted), ty, ..}
626-
))
624+
Place::Base(
625+
PlaceBase::Static(
626+
box Static { kind: StaticKind::Promoted(promoted), ty }
627+
)
628+
)
627629
) |
628630
mir::Operand::Move(
629-
Place::Base(PlaceBase::Static(
630-
box mir::Static {promoted: Some(promoted), ty, ..}
631-
))
631+
Place::Base(
632+
PlaceBase::Static(
633+
box Static { kind: StaticKind::Promoted(promoted), ty }
634+
)
635+
)
632636
) => {
633637
let param_env = ty::ParamEnv::reveal_all();
634638
let cid = mir::interpret::GlobalId {

src/librustc_codegen_ssa/mir/place.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,9 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
409409
let result = match *place {
410410
mir::Place::Base(mir::PlaceBase::Local(_)) => bug!(), // handled above
411411
mir::Place::Base(
412-
mir::PlaceBase::Static(box mir::Static { def_id: _, ty, promoted: Some(promoted) })
412+
mir::PlaceBase::Static(
413+
box mir::Static { ty, kind: mir::StaticKind::Promoted(promoted) }
414+
)
413415
) => {
414416
let param_env = ty::ParamEnv::reveal_all();
415417
let cid = mir::interpret::GlobalId {
@@ -438,7 +440,9 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
438440
}
439441
}
440442
mir::Place::Base(
441-
mir::PlaceBase::Static(box mir::Static { def_id, ty, promoted: None })
443+
mir::PlaceBase::Static(
444+
box mir::Static { ty, kind: mir::StaticKind::Static(def_id) }
445+
)
442446
) => {
443447
// NB: The layout of a static may be unsized as is the case when working
444448
// with a static that is an extern_type.

src/librustc_mir/borrow_check/error_reporting.rs

+10-9
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc::mir::{
1010
self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, Constant,
1111
ConstraintCategory, Field, Local, LocalDecl, LocalKind, Location, Operand,
1212
Place, PlaceBase, PlaceProjection, ProjectionElem, Rvalue, Statement, StatementKind,
13-
TerminatorKind, VarBindingForm,
13+
Static, StaticKind, TerminatorKind, VarBindingForm,
1414
};
1515
use rustc::ty::{self, DefIdTree};
1616
use rustc::ty::print::Print;
@@ -1601,12 +1601,11 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
16011601
Place::Base(PlaceBase::Local(local)) => {
16021602
self.append_local_to_string(local, buf)?;
16031603
}
1604-
Place::Base(PlaceBase::Static(ref static_)) => {
1605-
if static_.promoted.is_some() {
1606-
buf.push_str("promoted");
1607-
} else {
1608-
buf.push_str(&self.infcx.tcx.item_name(static_.def_id).to_string());
1609-
}
1604+
Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. })) => {
1605+
buf.push_str("promoted");
1606+
}
1607+
Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. })) => {
1608+
buf.push_str(&self.infcx.tcx.item_name(def_id).to_string());
16101609
}
16111610
Place::Projection(ref proj) => {
16121611
match proj.elem {
@@ -1808,8 +1807,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
18081807

18091808
/// Checks if a place is a thread-local static.
18101809
pub fn is_place_thread_local(&self, place: &Place<'tcx>) -> bool {
1811-
if let Place::Base(PlaceBase::Static(statik)) = place {
1812-
let attrs = self.infcx.tcx.get_attrs(statik.def_id);
1810+
if let Place::Base(
1811+
PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. })
1812+
) = place {
1813+
let attrs = self.infcx.tcx.get_attrs(*def_id);
18131814
let is_thread_local = attrs.iter().any(|attr| attr.check_name("thread_local"));
18141815

18151816
debug!(

src/librustc_mir/borrow_check/mod.rs

+19-11
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ use rustc::infer::InferCtxt;
88
use rustc::lint::builtin::UNUSED_MUT;
99
use rustc::middle::borrowck::SignalledError;
1010
use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind};
11-
use rustc::mir::{ClearCrossCrate, Local, Location, Mir, Mutability, Operand, Place, PlaceBase};
11+
use rustc::mir::{
12+
ClearCrossCrate, Local, Location, Mir, Mutability, Operand, Place, PlaceBase, Static, StaticKind
13+
};
1214
use rustc::mir::{Field, Projection, ProjectionElem, Rvalue, Statement, StatementKind};
1315
use rustc::mir::{Terminator, TerminatorKind};
1416
use rustc::ty::query::Providers;
@@ -1308,8 +1310,13 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
13081310
//
13091311
// FIXME: allow thread-locals to borrow other thread locals?
13101312
let (might_be_alive, will_be_dropped) = match root_place {
1311-
Place::Base(PlaceBase::Static(st)) => {
1312-
(true, st.promoted.is_none() && self.is_place_thread_local(&root_place))
1313+
Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. })) => {
1314+
(true, false)
1315+
}
1316+
Place::Base(PlaceBase::Static(box Static{ kind: _, .. })) => {
1317+
// Thread-locals might be dropped after the function exits, but
1318+
// "true" statics will never be.
1319+
(true, self.is_place_thread_local(&root_place))
13131320
}
13141321
Place::Base(PlaceBase::Local(_)) => {
13151322
// Locals are always dropped at function exit, and if they
@@ -1982,18 +1989,19 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
19821989
}
19831990
// The rules for promotion are made by `qualify_consts`, there wouldn't even be a
19841991
// `Place::Promoted` if the promotion weren't 100% legal. So we just forward this
1985-
Place::Base(PlaceBase::Static(ref static_)) => {
1986-
if static_.promoted.is_some() ||
1987-
(static_.promoted.is_none() &&
1988-
self.infcx.tcx.is_static(static_.def_id)
1989-
== Some(hir::Mutability::MutMutable)
1990-
){
1992+
Place::Base(PlaceBase::Static(box Static{kind: StaticKind::Promoted(_), ..})) =>
1993+
Ok(RootPlace {
1994+
place,
1995+
is_local_mutation_allowed,
1996+
}),
1997+
Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. })) => {
1998+
if self.infcx.tcx.is_static(def_id) != Some(hir::Mutability::MutMutable) {
1999+
Err(place)
2000+
} else {
19912001
Ok(RootPlace {
19922002
place,
19932003
is_local_mutation_allowed,
19942004
})
1995-
} else {
1996-
Err(place)
19972005
}
19982006
}
19992007
Place::Projection(ref proj) => {

src/librustc_mir/borrow_check/mutability_errors.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use rustc::hir;
22
use rustc::hir::Node;
33
use rustc::mir::{self, BindingForm, Constant, ClearCrossCrate, Local, Location, Mir};
4-
use rustc::mir::{Mutability, Operand, Place, PlaceBase, Projection, ProjectionElem, Static};
4+
use rustc::mir::{
5+
Mutability, Operand, Place, PlaceBase, Projection, ProjectionElem, Static, StaticKind,
6+
};
57
use rustc::mir::{Terminator, TerminatorKind};
68
use rustc::ty::{self, Const, DefIdTree, TyS, TyKind, TyCtxt};
79
use rustc_data_structures::indexed_vec::Idx;
@@ -129,8 +131,10 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
129131
}
130132
}
131133

132-
Place::Base(PlaceBase::Static(box Static { def_id, ty: _, promoted })) => {
133-
assert!(promoted.is_none());
134+
Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. })) =>
135+
unreachable!(),
136+
137+
Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), .. })) => {
134138
if let Place::Base(PlaceBase::Static(_)) = access_place {
135139
item_msg = format!("immutable static item `{}`", access_place_desc.unwrap());
136140
reason = String::new();

src/librustc_mir/borrow_check/nll/type_check/mod.rs

+35-27
Original file line numberDiff line numberDiff line change
@@ -453,45 +453,53 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
453453
Place::Base(PlaceBase::Local(index)) => PlaceTy::Ty {
454454
ty: self.mir.local_decls[index].ty,
455455
},
456-
Place::Base(PlaceBase::Static(box Static { def_id, ty: sty, promoted })) => {
456+
Place::Base(
457+
PlaceBase::Static(box Static { kind: StaticKind::Promoted(promoted), ty: sty })
458+
) => {
457459
let sty = self.sanitize_type(place, sty);
458-
let check_err =
459-
|verifier: &mut TypeVerifier<'a, 'b, 'gcx, 'tcx> ,
460-
place: &Place<'tcx>,
461-
ty,
462-
sty| {
463-
if let Err(terr) = verifier.cx.eq_types(
460+
461+
if !self.errors_reported {
462+
let promoted_mir = &self.mir.promoted[promoted];
463+
self.sanitize_promoted(promoted_mir, location);
464+
465+
let promoted_ty = promoted_mir.return_ty();
466+
467+
if let Err(terr) = self.cx.eq_types(
464468
sty,
465-
ty,
469+
promoted_ty,
466470
location.to_locations(),
467471
ConstraintCategory::Boring,
468472
) {
469473
span_mirbug!(
470-
verifier,
474+
self,
471475
place,
472476
"bad promoted type ({:?}: {:?}): {:?}",
473-
ty,
477+
promoted_ty,
474478
sty,
475479
terr
476480
);
477481
};
478-
};
479-
match promoted {
480-
Some(pr) => {
481-
if !self.errors_reported {
482-
let promoted_mir = &self.mir.promoted[pr];
483-
self.sanitize_promoted(promoted_mir, location);
484-
485-
let promoted_ty = promoted_mir.return_ty();
486-
check_err(self, place, promoted_ty, sty);
487-
}
488-
}
489-
None => {
490-
let ty = self.tcx().type_of(def_id);
491-
let ty = self.cx.normalize(ty, location);
492-
493-
check_err(self, place, ty, sty);
494-
}
482+
}
483+
PlaceTy::Ty { ty: sty }
484+
}
485+
Place::Base(
486+
PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), ty: sty })
487+
) => {
488+
let sty = self.sanitize_type(place, sty);
489+
let ty = self.tcx().type_of(def_id);
490+
let ty = self.cx.normalize(ty, location);
491+
if let Err(terr) =
492+
self.cx
493+
.eq_types(ty, sty, location.to_locations(), ConstraintCategory::Boring)
494+
{
495+
span_mirbug!(
496+
self,
497+
place,
498+
"bad static type ({:?}: {:?}): {:?}",
499+
ty,
500+
sty,
501+
terr
502+
);
495503
}
496504
PlaceTy::Ty { ty: sty }
497505
}

src/librustc_mir/borrow_check/place_ext.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rustc::hir;
22
use rustc::mir::ProjectionElem;
3-
use rustc::mir::{Local, Mir, Place, PlaceBase, Mutability};
3+
use rustc::mir::{Local, Mir, Place, PlaceBase, Mutability, Static, StaticKind};
44
use rustc::ty::{self, TyCtxt};
55
use crate::borrow_check::borrow_set::LocalsStateAtExit;
66

@@ -49,9 +49,10 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
4949
}
5050
}
5151
}
52-
Place::Base(PlaceBase::Static(static_)) => {
53-
static_.promoted.is_none() &&
54-
(tcx.is_static(static_.def_id) == Some(hir::Mutability::MutMutable))
52+
Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. })) =>
53+
false,
54+
Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. })) => {
55+
tcx.is_static(*def_id) == Some(hir::Mutability::MutMutable)
5556
}
5657
Place::Projection(proj) => match proj.elem {
5758
ProjectionElem::Field(..)

0 commit comments

Comments
 (0)