Skip to content

Commit

Permalink
replace monomorphic-const-eval with discriminants
Browse files Browse the repository at this point in the history
This query applies to get an enum def-id and yields a vector of
discriminants.
  • Loading branch information
nikomatsakis committed Apr 11, 2017
1 parent c58c928 commit 7491676
Show file tree
Hide file tree
Showing 14 changed files with 127 additions and 112 deletions.
4 changes: 2 additions & 2 deletions src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ pub enum DepNode<D: Clone + Debug> {
TypeckBodiesKrate,
TypeckTables(D),
UsedTraitImports(D),
MonomorphicConstEval(D),
Discriminants(D),

// The set of impls for a given trait. Ultimately, it would be
// nice to get more fine-grained here (e.g., to include a
Expand Down Expand Up @@ -278,7 +278,7 @@ impl<D: Clone + Debug> DepNode<D> {
InherentImpls(ref d) => op(d).map(InherentImpls),
TypeckTables(ref d) => op(d).map(TypeckTables),
UsedTraitImports(ref d) => op(d).map(UsedTraitImports),
MonomorphicConstEval(ref d) => op(d).map(MonomorphicConstEval),
Discriminants(ref d) => op(d).map(Discriminants),
TraitImpls(ref d) => op(d).map(TraitImpls),
TraitItems(ref d) => op(d).map(TraitItems),
ReprHints(ref d) => op(d).map(ReprHints),
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1217,7 +1217,7 @@ impl<'a, 'gcx, 'tcx> Layout {
let (mut min, mut max, mut non_zero) = (i64::max_value(),
i64::min_value(),
true);
for discr in def.discriminants(tcx) {
for &discr in &def.discriminants(tcx)[..] {
let x = discr.to_u128_unchecked() as i64;
if x == 0 { non_zero = false; }
if x < min { min = x; }
Expand Down
7 changes: 3 additions & 4 deletions src/librustc/ty/maps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

use dep_graph::{DepGraph, DepNode, DepTrackingMap, DepTrackingMapConfig};
use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use middle::const_val::ConstVal;
use middle::const_val::ConstInt;
use middle::privacy::AccessLevels;
use mir;
use session::CompileResult;
Expand Down Expand Up @@ -439,9 +439,8 @@ define_maps! { <'tcx>
/// (Defined only for LOCAL_CRATE)
pub crate_inherent_impls_overlap_check: crate_inherent_impls_dep_node(CrateNum) -> (),

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

/// Performs the privacy check and computes "access levels".
pub privacy_access_levels: PrivacyAccessLevels(CrateNum) -> Rc<AccessLevels>,
Expand Down
24 changes: 3 additions & 21 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ use hir::{map as hir_map, FreevarMap, TraitMap};
use hir::def::{Def, CtorKind, ExportMap};
use hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
use ich::StableHashingContext;
use middle::const_val::ConstVal;
use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
use middle::privacy::AccessLevels;
use middle::region::{CodeExtent, ROOT_CODE_EXTENT};
Expand All @@ -29,7 +28,6 @@ use mir::Mir;
use traits;
use ty;
use ty::subst::{Subst, Substs};
use ty::util::IntTypeExt;
use ty::walk::TypeWalker;
use util::common::MemoizationMap;
use util::nodemap::{NodeSet, DefIdMap, FxHashMap};
Expand Down Expand Up @@ -1612,25 +1610,9 @@ impl<'a, 'gcx, 'tcx> AdtDef {
}
}

pub fn discriminants(&'a self, tcx: TyCtxt<'a, 'gcx, 'tcx>)
-> impl Iterator<Item=ConstInt> + 'a {
let repr_type = self.repr.discr_type();
let initial = repr_type.initial_discriminant(tcx.global_tcx());
let mut prev_discr = None::<ConstInt>;
self.variants.iter().map(move |v| {
let mut discr = prev_discr.map_or(initial, |d| d.wrap_incr());
if let VariantDiscr::Explicit(expr_did) = v.discr {
match tcx.maps.monomorphic_const_eval.borrow()[&expr_did] {
Ok(ConstVal::Integral(v)) => {
discr = v;
}
_ => {}
}
}
prev_discr = Some(discr);

discr
})
pub fn discriminants(&'a self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Rc<Vec<ConstInt>> {
assert!(self.is_enum(), "should not call `discriminants` except for enums");
queries::discriminants::get(tcx, DUMMY_SP, self.did)
}

pub fn destructor(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Destructor> {
Expand Down
1 change: 1 addition & 0 deletions src/librustc_metadata/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ provide! { <'tcx> tcx, def_id, cdata
tcx.alloc_trait_def(cdata.get_trait_def(def_id.index))
}
adt_def => { cdata.get_adt_def(def_id.index, tcx) }
discriminants => { Rc::new(cdata.get_discriminants(def_id.index)) }
adt_destructor => {
let _ = cdata;
tcx.calculate_dtor(def_id, &mut |_,_| Ok(()))
Expand Down
40 changes: 31 additions & 9 deletions src/librustc_metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use schema::*;
use rustc::hir::map::{DefKey, DefPath, DefPathData};
use rustc::hir;

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

fn get_variant(&self,
item: &Entry<'tcx>,
index: DefIndex,
tcx: TyCtxt<'a, 'tcx, 'tcx>)
index: DefIndex)
-> (ty::VariantDef, Option<DefIndex>) {
let data = match item.kind {
EntryKind::Variant(data) |
Expand All @@ -522,13 +522,10 @@ impl<'a, 'tcx> CrateMetadata {
_ => bug!(),
};

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

(ty::VariantDef {
did: self.local_def_id(data.struct_ctor.unwrap_or(index)),
did: variant_did,
name: self.item_name(index),
fields: item.children.decode(self).map(|index| {
let f = self.entry(index);
Expand Down Expand Up @@ -560,13 +557,13 @@ impl<'a, 'tcx> CrateMetadata {
.decode(self)
.map(|index| {
let (variant, struct_ctor) =
self.get_variant(&self.entry(index), index, tcx);
self.get_variant(&self.entry(index), index);
assert_eq!(struct_ctor, None);
variant
})
.collect()
} else {
let (variant, _struct_ctor) = self.get_variant(&item, item_id, tcx);
let (variant, _struct_ctor) = self.get_variant(&item, item_id);
vec![variant]
};
let (kind, repr) = match item.kind {
Expand All @@ -579,6 +576,31 @@ impl<'a, 'tcx> CrateMetadata {
tcx.alloc_adt_def(did, kind, variants, repr)
}

pub fn get_discriminants(&self,
item_id: DefIndex)
-> Vec<ConstInt>
{
let item = self.entry(item_id);
let did = self.local_def_id(item_id);
match item.kind {
EntryKind::Enum(_) => (),
_ => bug!("get_discriminants called on a non-enum {:?}", did),
}
let discriminants =
item.children
.decode(self)
.map(|variant_index| {
let variant_entry = self.entry(variant_index);
let variant_data = match variant_entry.kind {
EntryKind::Variant(data) => data.decode(self),
_ => bug!("expected variant as child of enum {:?}", did),
};
variant_data.evaluated_discr
})
.collect();
discriminants
}

pub fn get_predicates(&self,
item_id: DefIndex,
tcx: TyCtxt<'a, 'tcx, 'tcx>)
Expand Down
25 changes: 14 additions & 11 deletions src/librustc_metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use rustc::middle::lang_items;
use rustc::mir;
use rustc::traits::specialization_graph;
use rustc::ty::{self, Ty, TyCtxt, ReprOptions};
use rustc::ty::util::IntTypeExt;

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

let discriminants = ty::queries::discriminants::get(tcx, DUMMY_SP, enum_did);

let data = VariantData {
ctor_kind: variant.ctor_kind,
discr: variant.discr,
evaluated_discr: match variant.discr {
ty::VariantDiscr::Explicit(def_id) => {
ty::queries::monomorphic_const_eval::get(tcx, DUMMY_SP, def_id).ok()
}
ty::VariantDiscr::Relative(_) => None
},
evaluated_discr: discriminants[index],
struct_ctor: None,
};

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

fn encode_struct_ctor(&mut self, (adt_def_id, def_id): (DefId, DefId)) -> Entry<'tcx> {
let tcx = self.tcx;
let variant = tcx.lookup_adt_def(adt_def_id).struct_variant();
let adt_def = tcx.lookup_adt_def(adt_def_id);
let variant = adt_def.struct_variant();

let evaluated_discr = adt_def.repr.discr_type().initial_discriminant(tcx);

let data = VariantData {
ctor_kind: variant.ctor_kind,
discr: variant.discr,
evaluated_discr: None,
evaluated_discr: evaluated_discr,
struct_ctor: Some(def_id.index),
};

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

// Encode def_ids for each field and method
// for methods, write all the stuff get_trait_method
Expand All @@ -674,18 +676,19 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
EntryKind::Struct(self.lazy(&VariantData {
ctor_kind: variant.ctor_kind,
discr: variant.discr,
evaluated_discr: None,
evaluated_discr: adt_def.repr.discr_type().initial_discriminant(tcx),
struct_ctor: struct_ctor,
}), repr_options)
}
hir::ItemUnion(..) => {
let adt_def = tcx.lookup_adt_def(def_id);
let variant = tcx.lookup_adt_def(def_id).struct_variant();
let repr_options = get_repr_options(&tcx, def_id);

EntryKind::Union(self.lazy(&VariantData {
ctor_kind: variant.ctor_kind,
discr: variant.discr,
evaluated_discr: None,
evaluated_discr: adt_def.repr.discr_type().initial_discriminant(tcx),
struct_ctor: None,
}), repr_options)
}
Expand Down
12 changes: 6 additions & 6 deletions src/librustc_metadata/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use index;
use rustc::hir;
use rustc::hir::def::{self, CtorKind};
use rustc::hir::def_id::{DefIndex, DefId};
use rustc::middle::const_val::ConstVal;
use rustc::middle::const_val::ConstInt;
use rustc::middle::cstore::{DepKind, LinkagePreference, NativeLibrary};
use rustc::middle::lang_items;
use rustc::mir;
Expand Down Expand Up @@ -230,9 +230,9 @@ pub enum EntryKind<'tcx> {
Type,
Enum(ReprOptions),
Field,
Variant(Lazy<VariantData<'tcx>>),
Struct(Lazy<VariantData<'tcx>>, ReprOptions),
Union(Lazy<VariantData<'tcx>>, ReprOptions),
Variant(Lazy<VariantData>),
Struct(Lazy<VariantData>, ReprOptions),
Union(Lazy<VariantData>, ReprOptions),
Fn(Lazy<FnData>),
ForeignFn(Lazy<FnData>),
Mod(Lazy<ModData>),
Expand Down Expand Up @@ -263,10 +263,10 @@ pub struct FnData {
}

#[derive(RustcEncodable, RustcDecodable)]
pub struct VariantData<'tcx> {
pub struct VariantData {
pub ctor_kind: CtorKind,
pub discr: ty::VariantDiscr,
pub evaluated_discr: Option<ConstVal<'tcx>>,
pub evaluated_discr: ConstInt,

/// If this is a struct's only variant, this
/// is the index of the "struct ctor" item.
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/build/matches/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let mut targets = Vec::with_capacity(used_variants + 1);
let mut values = Vec::with_capacity(used_variants);
let tcx = self.hir.tcx();
for (idx, discr) in adt_def.discriminants(tcx).enumerate() {
for (idx, &discr) in adt_def.discriminants(tcx).iter().enumerate() {
target_blocks.place_back() <- if variants.contains(idx) {
values.push(discr);
*(targets.place_back() <- self.cfg.start_new_block())
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/util/elaborate_drops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
};
let mut otherwise = None;
let mut unwind_otherwise = None;
for (variant_index, discr) in adt.discriminants(self.tcx()).enumerate() {
for (variant_index, &discr) in adt.discriminants(self.tcx()).iter().enumerate() {
let subpath = self.elaborator.downcast_subpath(
self.path, variant_index);
if let Some(variant_path) = subpath {
Expand Down
1 change: 1 addition & 0 deletions src/librustc_trans/debuginfo/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1468,6 +1468,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,

let def = enum_type.ty_adt_def().unwrap();
let enumerators_metadata: Vec<DIDescriptor> = def.discriminants(cx.tcx())
.iter()
.zip(&def.variants)
.map(|(discr, v)| {
let token = v.name.as_str();
Expand Down
35 changes: 8 additions & 27 deletions src/librustc_trans/disr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,40 +8,21 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use rustc::middle::const_val::ConstVal;
use rustc::ty::{self, TyCtxt};
use rustc::ty::util::IntTypeExt;
use rustc_const_math::ConstInt;

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

impl Disr {
pub fn for_variant(tcx: TyCtxt,
def: &ty::AdtDef,
variant_index: usize) -> Self {
let mut explicit_index = variant_index;
let mut explicit_value = Disr(0);
loop {
match def.variants[explicit_index].discr {
ty::VariantDiscr::Relative(0) => break,
ty::VariantDiscr::Relative(distance) => {
explicit_index -= distance;
}
ty::VariantDiscr::Explicit(expr_did) => {
match tcx.maps.monomorphic_const_eval.borrow()[&expr_did] {
Ok(ConstVal::Integral(v)) => {
explicit_value = Disr::from(v);
break;
}
_ => {
explicit_index -= 1;
}
}
}
}
}
let distance = variant_index - explicit_index;
explicit_value.wrapping_add(Disr::from(distance))
pub fn for_variant(tcx: TyCtxt, def: &ty::AdtDef, variant_index: usize) -> Self {
let v = if def.is_enum() {
def.discriminants(tcx)[variant_index]
} else {
def.repr.discr_type().initial_discriminant(tcx.global_tcx())
};
Disr::from(v)
}

pub fn wrapping_add(self, other: Self) -> Self {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1370,7 +1370,7 @@ pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}

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

0 comments on commit 7491676

Please sign in to comment.