Skip to content

Commit 7491676

Browse files
committed
replace monomorphic-const-eval with discriminants
This query applies to get an enum def-id and yields a vector of discriminants.
1 parent c58c928 commit 7491676

File tree

14 files changed

+127
-112
lines changed

14 files changed

+127
-112
lines changed

src/librustc/dep_graph/dep_node.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ pub enum DepNode<D: Clone + Debug> {
119119
TypeckBodiesKrate,
120120
TypeckTables(D),
121121
UsedTraitImports(D),
122-
MonomorphicConstEval(D),
122+
Discriminants(D),
123123

124124
// The set of impls for a given trait. Ultimately, it would be
125125
// nice to get more fine-grained here (e.g., to include a
@@ -278,7 +278,7 @@ impl<D: Clone + Debug> DepNode<D> {
278278
InherentImpls(ref d) => op(d).map(InherentImpls),
279279
TypeckTables(ref d) => op(d).map(TypeckTables),
280280
UsedTraitImports(ref d) => op(d).map(UsedTraitImports),
281-
MonomorphicConstEval(ref d) => op(d).map(MonomorphicConstEval),
281+
Discriminants(ref d) => op(d).map(Discriminants),
282282
TraitImpls(ref d) => op(d).map(TraitImpls),
283283
TraitItems(ref d) => op(d).map(TraitItems),
284284
ReprHints(ref d) => op(d).map(ReprHints),

src/librustc/ty/layout.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1217,7 +1217,7 @@ impl<'a, 'gcx, 'tcx> Layout {
12171217
let (mut min, mut max, mut non_zero) = (i64::max_value(),
12181218
i64::min_value(),
12191219
true);
1220-
for discr in def.discriminants(tcx) {
1220+
for &discr in &def.discriminants(tcx)[..] {
12211221
let x = discr.to_u128_unchecked() as i64;
12221222
if x == 0 { non_zero = false; }
12231223
if x < min { min = x; }

src/librustc/ty/maps.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
use dep_graph::{DepGraph, DepNode, DepTrackingMap, DepTrackingMapConfig};
1212
use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
13-
use middle::const_val::ConstVal;
13+
use middle::const_val::ConstInt;
1414
use middle::privacy::AccessLevels;
1515
use mir;
1616
use session::CompileResult;
@@ -439,9 +439,8 @@ define_maps! { <'tcx>
439439
/// (Defined only for LOCAL_CRATE)
440440
pub crate_inherent_impls_overlap_check: crate_inherent_impls_dep_node(CrateNum) -> (),
441441

442-
/// Results of evaluating monomorphic constants embedded in
443-
/// other items, such as enum variant explicit discriminants.
444-
pub monomorphic_const_eval: MonomorphicConstEval(DefId) -> Result<ConstVal<'tcx>, ()>,
442+
/// Computes the final discriminant for each variant of an enum.
443+
pub discriminants: Discriminants(DefId) -> Rc<Vec<ConstInt>>,
445444

446445
/// Performs the privacy check and computes "access levels".
447446
pub privacy_access_levels: PrivacyAccessLevels(CrateNum) -> Rc<AccessLevels>,

src/librustc/ty/mod.rs

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ use hir::{map as hir_map, FreevarMap, TraitMap};
2020
use hir::def::{Def, CtorKind, ExportMap};
2121
use hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
2222
use ich::StableHashingContext;
23-
use middle::const_val::ConstVal;
2423
use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
2524
use middle::privacy::AccessLevels;
2625
use middle::region::{CodeExtent, ROOT_CODE_EXTENT};
@@ -29,7 +28,6 @@ use mir::Mir;
2928
use traits;
3029
use ty;
3130
use ty::subst::{Subst, Substs};
32-
use ty::util::IntTypeExt;
3331
use ty::walk::TypeWalker;
3432
use util::common::MemoizationMap;
3533
use util::nodemap::{NodeSet, DefIdMap, FxHashMap};
@@ -1612,25 +1610,9 @@ impl<'a, 'gcx, 'tcx> AdtDef {
16121610
}
16131611
}
16141612

1615-
pub fn discriminants(&'a self, tcx: TyCtxt<'a, 'gcx, 'tcx>)
1616-
-> impl Iterator<Item=ConstInt> + 'a {
1617-
let repr_type = self.repr.discr_type();
1618-
let initial = repr_type.initial_discriminant(tcx.global_tcx());
1619-
let mut prev_discr = None::<ConstInt>;
1620-
self.variants.iter().map(move |v| {
1621-
let mut discr = prev_discr.map_or(initial, |d| d.wrap_incr());
1622-
if let VariantDiscr::Explicit(expr_did) = v.discr {
1623-
match tcx.maps.monomorphic_const_eval.borrow()[&expr_did] {
1624-
Ok(ConstVal::Integral(v)) => {
1625-
discr = v;
1626-
}
1627-
_ => {}
1628-
}
1629-
}
1630-
prev_discr = Some(discr);
1631-
1632-
discr
1633-
})
1613+
pub fn discriminants(&'a self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Rc<Vec<ConstInt>> {
1614+
assert!(self.is_enum(), "should not call `discriminants` except for enums");
1615+
queries::discriminants::get(tcx, DUMMY_SP, self.did)
16341616
}
16351617

16361618
pub fn destructor(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Destructor> {

src/librustc_metadata/cstore_impl.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ provide! { <'tcx> tcx, def_id, cdata
7676
tcx.alloc_trait_def(cdata.get_trait_def(def_id.index))
7777
}
7878
adt_def => { cdata.get_adt_def(def_id.index, tcx) }
79+
discriminants => { Rc::new(cdata.get_discriminants(def_id.index)) }
7980
adt_destructor => {
8081
let _ = cdata;
8182
tcx.calculate_dtor(def_id, &mut |_,_| Ok(()))

src/librustc_metadata/decoder.rs

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use schema::*;
1616
use rustc::hir::map::{DefKey, DefPath, DefPathData};
1717
use rustc::hir;
1818

19+
use rustc::middle::const_val::ConstInt;
1920
use rustc::middle::cstore::LinkagePreference;
2021
use rustc::hir::def::{self, Def, CtorKind};
2122
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
@@ -512,8 +513,7 @@ impl<'a, 'tcx> CrateMetadata {
512513

513514
fn get_variant(&self,
514515
item: &Entry<'tcx>,
515-
index: DefIndex,
516-
tcx: TyCtxt<'a, 'tcx, 'tcx>)
516+
index: DefIndex)
517517
-> (ty::VariantDef, Option<DefIndex>) {
518518
let data = match item.kind {
519519
EntryKind::Variant(data) |
@@ -522,13 +522,10 @@ impl<'a, 'tcx> CrateMetadata {
522522
_ => bug!(),
523523
};
524524

525-
if let ty::VariantDiscr::Explicit(def_id) = data.discr {
526-
let result = data.evaluated_discr.map_or(Err(()), Ok);
527-
tcx.maps.monomorphic_const_eval.borrow_mut().insert(def_id, result);
528-
}
525+
let variant_did = self.local_def_id(data.struct_ctor.unwrap_or(index));
529526

530527
(ty::VariantDef {
531-
did: self.local_def_id(data.struct_ctor.unwrap_or(index)),
528+
did: variant_did,
532529
name: self.item_name(index),
533530
fields: item.children.decode(self).map(|index| {
534531
let f = self.entry(index);
@@ -560,13 +557,13 @@ impl<'a, 'tcx> CrateMetadata {
560557
.decode(self)
561558
.map(|index| {
562559
let (variant, struct_ctor) =
563-
self.get_variant(&self.entry(index), index, tcx);
560+
self.get_variant(&self.entry(index), index);
564561
assert_eq!(struct_ctor, None);
565562
variant
566563
})
567564
.collect()
568565
} else {
569-
let (variant, _struct_ctor) = self.get_variant(&item, item_id, tcx);
566+
let (variant, _struct_ctor) = self.get_variant(&item, item_id);
570567
vec![variant]
571568
};
572569
let (kind, repr) = match item.kind {
@@ -579,6 +576,31 @@ impl<'a, 'tcx> CrateMetadata {
579576
tcx.alloc_adt_def(did, kind, variants, repr)
580577
}
581578

579+
pub fn get_discriminants(&self,
580+
item_id: DefIndex)
581+
-> Vec<ConstInt>
582+
{
583+
let item = self.entry(item_id);
584+
let did = self.local_def_id(item_id);
585+
match item.kind {
586+
EntryKind::Enum(_) => (),
587+
_ => bug!("get_discriminants called on a non-enum {:?}", did),
588+
}
589+
let discriminants =
590+
item.children
591+
.decode(self)
592+
.map(|variant_index| {
593+
let variant_entry = self.entry(variant_index);
594+
let variant_data = match variant_entry.kind {
595+
EntryKind::Variant(data) => data.decode(self),
596+
_ => bug!("expected variant as child of enum {:?}", did),
597+
};
598+
variant_data.evaluated_discr
599+
})
600+
.collect();
601+
discriminants
602+
}
603+
582604
pub fn get_predicates(&self,
583605
item_id: DefIndex,
584606
tcx: TyCtxt<'a, 'tcx, 'tcx>)

src/librustc_metadata/encoder.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use rustc::middle::lang_items;
2020
use rustc::mir;
2121
use rustc::traits::specialization_graph;
2222
use rustc::ty::{self, Ty, TyCtxt, ReprOptions};
23+
use rustc::ty::util::IntTypeExt;
2324

2425
use rustc::session::config::{self, CrateTypeProcMacro};
2526
use rustc::util::nodemap::{FxHashMap, NodeSet};
@@ -257,15 +258,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
257258
let variant = &def.variants[index];
258259
let def_id = variant.did;
259260

261+
let discriminants = ty::queries::discriminants::get(tcx, DUMMY_SP, enum_did);
262+
260263
let data = VariantData {
261264
ctor_kind: variant.ctor_kind,
262265
discr: variant.discr,
263-
evaluated_discr: match variant.discr {
264-
ty::VariantDiscr::Explicit(def_id) => {
265-
ty::queries::monomorphic_const_eval::get(tcx, DUMMY_SP, def_id).ok()
266-
}
267-
ty::VariantDiscr::Relative(_) => None
268-
},
266+
evaluated_discr: discriminants[index],
269267
struct_ctor: None,
270268
};
271269

@@ -388,12 +386,15 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
388386

389387
fn encode_struct_ctor(&mut self, (adt_def_id, def_id): (DefId, DefId)) -> Entry<'tcx> {
390388
let tcx = self.tcx;
391-
let variant = tcx.lookup_adt_def(adt_def_id).struct_variant();
389+
let adt_def = tcx.lookup_adt_def(adt_def_id);
390+
let variant = adt_def.struct_variant();
391+
392+
let evaluated_discr = adt_def.repr.discr_type().initial_discriminant(tcx);
392393

393394
let data = VariantData {
394395
ctor_kind: variant.ctor_kind,
395396
discr: variant.discr,
396-
evaluated_discr: None,
397+
evaluated_discr: evaluated_discr,
397398
struct_ctor: Some(def_id.index),
398399
};
399400

@@ -658,7 +659,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
658659
hir::ItemTy(..) => EntryKind::Type,
659660
hir::ItemEnum(..) => EntryKind::Enum(get_repr_options(&tcx, def_id)),
660661
hir::ItemStruct(ref struct_def, _) => {
661-
let variant = tcx.lookup_adt_def(def_id).struct_variant();
662+
let adt_def = tcx.lookup_adt_def(def_id);
663+
let variant = adt_def.struct_variant();
662664

663665
// Encode def_ids for each field and method
664666
// for methods, write all the stuff get_trait_method
@@ -674,18 +676,19 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
674676
EntryKind::Struct(self.lazy(&VariantData {
675677
ctor_kind: variant.ctor_kind,
676678
discr: variant.discr,
677-
evaluated_discr: None,
679+
evaluated_discr: adt_def.repr.discr_type().initial_discriminant(tcx),
678680
struct_ctor: struct_ctor,
679681
}), repr_options)
680682
}
681683
hir::ItemUnion(..) => {
684+
let adt_def = tcx.lookup_adt_def(def_id);
682685
let variant = tcx.lookup_adt_def(def_id).struct_variant();
683686
let repr_options = get_repr_options(&tcx, def_id);
684687

685688
EntryKind::Union(self.lazy(&VariantData {
686689
ctor_kind: variant.ctor_kind,
687690
discr: variant.discr,
688-
evaluated_discr: None,
691+
evaluated_discr: adt_def.repr.discr_type().initial_discriminant(tcx),
689692
struct_ctor: None,
690693
}), repr_options)
691694
}

src/librustc_metadata/schema.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use index;
1414
use rustc::hir;
1515
use rustc::hir::def::{self, CtorKind};
1616
use rustc::hir::def_id::{DefIndex, DefId};
17-
use rustc::middle::const_val::ConstVal;
17+
use rustc::middle::const_val::ConstInt;
1818
use rustc::middle::cstore::{DepKind, LinkagePreference, NativeLibrary};
1919
use rustc::middle::lang_items;
2020
use rustc::mir;
@@ -230,9 +230,9 @@ pub enum EntryKind<'tcx> {
230230
Type,
231231
Enum(ReprOptions),
232232
Field,
233-
Variant(Lazy<VariantData<'tcx>>),
234-
Struct(Lazy<VariantData<'tcx>>, ReprOptions),
235-
Union(Lazy<VariantData<'tcx>>, ReprOptions),
233+
Variant(Lazy<VariantData>),
234+
Struct(Lazy<VariantData>, ReprOptions),
235+
Union(Lazy<VariantData>, ReprOptions),
236236
Fn(Lazy<FnData>),
237237
ForeignFn(Lazy<FnData>),
238238
Mod(Lazy<ModData>),
@@ -263,10 +263,10 @@ pub struct FnData {
263263
}
264264

265265
#[derive(RustcEncodable, RustcDecodable)]
266-
pub struct VariantData<'tcx> {
266+
pub struct VariantData {
267267
pub ctor_kind: CtorKind,
268268
pub discr: ty::VariantDiscr,
269-
pub evaluated_discr: Option<ConstVal<'tcx>>,
269+
pub evaluated_discr: ConstInt,
270270

271271
/// If this is a struct's only variant, this
272272
/// is the index of the "struct ctor" item.

src/librustc_mir/build/matches/test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
191191
let mut targets = Vec::with_capacity(used_variants + 1);
192192
let mut values = Vec::with_capacity(used_variants);
193193
let tcx = self.hir.tcx();
194-
for (idx, discr) in adt_def.discriminants(tcx).enumerate() {
194+
for (idx, &discr) in adt_def.discriminants(tcx).iter().enumerate() {
195195
target_blocks.place_back() <- if variants.contains(idx) {
196196
values.push(discr);
197197
*(targets.place_back() <- self.cfg.start_new_block())

src/librustc_mir/util/elaborate_drops.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
384384
};
385385
let mut otherwise = None;
386386
let mut unwind_otherwise = None;
387-
for (variant_index, discr) in adt.discriminants(self.tcx()).enumerate() {
387+
for (variant_index, &discr) in adt.discriminants(self.tcx()).iter().enumerate() {
388388
let subpath = self.elaborator.downcast_subpath(
389389
self.path, variant_index);
390390
if let Some(variant_path) = subpath {

src/librustc_trans/debuginfo/metadata.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1468,6 +1468,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
14681468

14691469
let def = enum_type.ty_adt_def().unwrap();
14701470
let enumerators_metadata: Vec<DIDescriptor> = def.discriminants(cx.tcx())
1471+
.iter()
14711472
.zip(&def.variants)
14721473
.map(|(discr, v)| {
14731474
let token = v.name.as_str();

src/librustc_trans/disr.rs

Lines changed: 8 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,40 +8,21 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use rustc::middle::const_val::ConstVal;
1211
use rustc::ty::{self, TyCtxt};
12+
use rustc::ty::util::IntTypeExt;
1313
use rustc_const_math::ConstInt;
1414

1515
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
1616
pub struct Disr(pub u64);
1717

1818
impl Disr {
19-
pub fn for_variant(tcx: TyCtxt,
20-
def: &ty::AdtDef,
21-
variant_index: usize) -> Self {
22-
let mut explicit_index = variant_index;
23-
let mut explicit_value = Disr(0);
24-
loop {
25-
match def.variants[explicit_index].discr {
26-
ty::VariantDiscr::Relative(0) => break,
27-
ty::VariantDiscr::Relative(distance) => {
28-
explicit_index -= distance;
29-
}
30-
ty::VariantDiscr::Explicit(expr_did) => {
31-
match tcx.maps.monomorphic_const_eval.borrow()[&expr_did] {
32-
Ok(ConstVal::Integral(v)) => {
33-
explicit_value = Disr::from(v);
34-
break;
35-
}
36-
_ => {
37-
explicit_index -= 1;
38-
}
39-
}
40-
}
41-
}
42-
}
43-
let distance = variant_index - explicit_index;
44-
explicit_value.wrapping_add(Disr::from(distance))
19+
pub fn for_variant(tcx: TyCtxt, def: &ty::AdtDef, variant_index: usize) -> Self {
20+
let v = if def.is_enum() {
21+
def.discriminants(tcx)[variant_index]
22+
} else {
23+
def.repr.discr_type().initial_discriminant(tcx.global_tcx())
24+
};
25+
Disr::from(v)
4526
}
4627

4728
pub fn wrapping_add(self, other: Self) -> Self {

src/librustc_typeck/check/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1370,7 +1370,7 @@ pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
13701370
}
13711371

13721372
let mut disr_vals: Vec<ConstInt> = Vec::new();
1373-
for (discr, v) in def.discriminants(tcx).zip(vs) {
1373+
for (&discr, v) in def.discriminants(tcx).iter().zip(vs) {
13741374
// Check for duplicate discriminant values
13751375
if let Some(i) = disr_vals.iter().position(|&x| x == discr) {
13761376
let variant_i_node_id = tcx.hir.as_local_node_id(def.variants[i].did).unwrap();

0 commit comments

Comments
 (0)