Skip to content

Commit

Permalink
rustc: intern ConstVal's in TyCtxt.
Browse files Browse the repository at this point in the history
  • Loading branch information
eddyb committed Sep 11, 2017
1 parent e6bce95 commit 50076b0
Show file tree
Hide file tree
Showing 31 changed files with 347 additions and 240 deletions.
2 changes: 1 addition & 1 deletion src/librustc/hir/mod.rs
Expand Up @@ -611,7 +611,7 @@ pub enum BindingAnnotation {
RefMut,
}

#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum RangeEnd {
Included,
Excluded,
Expand Down
38 changes: 19 additions & 19 deletions src/librustc/ich/impls_ty.rs
Expand Up @@ -16,7 +16,6 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
StableHasherResult};
use std::hash as std_hash;
use std::mem;
use syntax_pos::symbol::InternedString;
use middle::region;
use ty;

Expand Down Expand Up @@ -272,59 +271,60 @@ for ::middle::const_val::ConstVal<'gcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
hasher: &mut StableHasher<W>) {
use middle::const_val::ConstVal;
use middle::const_val::ConstVal::*;
use middle::const_val::ConstAggregate::*;

mem::discriminant(self).hash_stable(hcx, hasher);

match *self {
ConstVal::Float(ref value) => {
Float(ref value) => {
value.hash_stable(hcx, hasher);
}
ConstVal::Integral(ref value) => {
Integral(ref value) => {
value.hash_stable(hcx, hasher);
}
ConstVal::Str(ref value) => {
Str(ref value) => {
value.hash_stable(hcx, hasher);
}
ConstVal::ByteStr(ref value) => {
ByteStr(ref value) => {
value.hash_stable(hcx, hasher);
}
ConstVal::Bool(value) => {
Bool(value) => {
value.hash_stable(hcx, hasher);
}
ConstVal::Char(value) => {
Char(value) => {
value.hash_stable(hcx, hasher);
}
ConstVal::Variant(def_id) => {
Variant(def_id) => {
def_id.hash_stable(hcx, hasher);
}
ConstVal::Function(def_id, substs) => {
Function(def_id, substs) => {
def_id.hash_stable(hcx, hasher);
substs.hash_stable(hcx, hasher);
}
ConstVal::Struct(ref name_value_map) => {
let mut values: Vec<(InternedString, &ConstVal)> =
name_value_map.iter()
.map(|(name, val)| (name.as_str(), val))
.collect();

Aggregate(Struct(ref name_values)) => {
let mut values = name_values.to_vec();
values.sort_unstable_by_key(|&(ref name, _)| name.clone());
values.hash_stable(hcx, hasher);
}
ConstVal::Tuple(ref value) => {
Aggregate(Tuple(ref value)) => {
value.hash_stable(hcx, hasher);
}
ConstVal::Array(ref value) => {
Aggregate(Array(ref value)) => {
value.hash_stable(hcx, hasher);
}
ConstVal::Repeat(ref value, times) => {
Aggregate(Repeat(ref value, times)) => {
value.hash_stable(hcx, hasher);
times.hash_stable(hcx, hasher);
}
}
}
}

impl_stable_hash_for!(struct ::middle::const_val::ByteArray<'tcx> {
data
});

impl_stable_hash_for!(struct ty::ClosureSubsts<'tcx> { substs });

impl_stable_hash_for!(struct ty::GeneratorInterior<'tcx> { witness });
Expand Down
54 changes: 40 additions & 14 deletions src/librustc/middle/const_val.rs
Expand Up @@ -9,6 +9,7 @@
// except according to those terms.

use self::ConstVal::*;
use self::ConstAggregate::*;
pub use rustc_const_math::ConstInt;

use hir;
Expand All @@ -22,30 +23,55 @@ use rustc_const_math::*;

use graphviz::IntoCow;
use errors::DiagnosticBuilder;
use serialize::{self, Encodable, Encoder, Decodable, Decoder};
use syntax::symbol::InternedString;
use syntax::ast;
use syntax_pos::Span;

use std::borrow::Cow;
use std::collections::BTreeMap;
use std::rc::Rc;

pub type EvalResult<'tcx> = Result<ConstVal<'tcx>, ConstEvalErr<'tcx>>;
pub type EvalResult<'tcx> = Result<&'tcx ConstVal<'tcx>, ConstEvalErr<'tcx>>;

#[derive(Clone, Debug, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq)]
#[derive(Copy, Clone, Debug, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq)]
pub enum ConstVal<'tcx> {
Float(ConstFloat),
Integral(ConstInt),
Str(InternedString),
ByteStr(Rc<Vec<u8>>),
ByteStr(ByteArray<'tcx>),
Bool(bool),
Char(char),
Variant(DefId),
Function(DefId, &'tcx Substs<'tcx>),
Struct(BTreeMap<ast::Name, ConstVal<'tcx>>),
Tuple(Vec<ConstVal<'tcx>>),
Array(Vec<ConstVal<'tcx>>),
Repeat(Box<ConstVal<'tcx>>, u64),
Aggregate(ConstAggregate<'tcx>),
}

impl<'tcx> serialize::UseSpecializedDecodable for &'tcx ConstVal<'tcx> {}

#[derive(Copy, Clone, Debug, Hash, RustcEncodable, Eq, PartialEq)]
pub struct ByteArray<'tcx> {
pub data: &'tcx [u8],
}

impl<'tcx> serialize::UseSpecializedDecodable for ByteArray<'tcx> {}

#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub enum ConstAggregate<'tcx> {
Struct(&'tcx [(ast::Name, &'tcx ConstVal<'tcx>)]),
Tuple(&'tcx [&'tcx ConstVal<'tcx>]),
Array(&'tcx [&'tcx ConstVal<'tcx>]),
Repeat(&'tcx ConstVal<'tcx>, u64),
}

impl<'tcx> Encodable for ConstAggregate<'tcx> {
fn encode<S: Encoder>(&self, _: &mut S) -> Result<(), S::Error> {
bug!("should never encode ConstAggregate::{:?}", self)
}
}

impl<'tcx> Decodable for ConstAggregate<'tcx> {
fn decode<D: Decoder>(_: &mut D) -> Result<Self, D::Error> {
bug!("should never decode ConstAggregate")
}
}

impl<'tcx> ConstVal<'tcx> {
Expand All @@ -58,11 +84,11 @@ impl<'tcx> ConstVal<'tcx> {
Bool(_) => "boolean",
Char(..) => "char",
Variant(_) => "enum variant",
Struct(_) => "struct",
Tuple(_) => "tuple",
Aggregate(Struct(_)) => "struct",
Aggregate(Tuple(_)) => "tuple",
Function(..) => "function definition",
Array(..) => "array",
Repeat(..) => "repeat",
Aggregate(Array(..)) => "array",
Aggregate(Repeat(..)) => "repeat",
}
}

Expand Down Expand Up @@ -233,7 +259,7 @@ pub fn eval_length(tcx: TyCtxt,
let param_env = ty::ParamEnv::empty(Reveal::UserFacing);
let substs = Substs::identity_for_item(tcx.global_tcx(), count_def_id);
match tcx.at(count_expr.span).const_eval(param_env.and((count_def_id, substs))) {
Ok(Integral(Usize(count))) => {
Ok(&Integral(Usize(count))) => {
let val = count.as_u64(tcx.sess.target.uint_type);
assert_eq!(val as usize as u64, val);
Ok(val as usize)
Expand Down
15 changes: 8 additions & 7 deletions src/librustc/mir/mod.rs
Expand Up @@ -1190,7 +1190,9 @@ impl<'tcx> Operand<'tcx> {
Operand::Constant(box Constant {
span,
ty: tcx.type_of(def_id).subst(tcx, substs),
literal: Literal::Value { value: ConstVal::Function(def_id, substs) },
literal: Literal::Value {
value: tcx.mk_const(ConstVal::Function(def_id, substs))
},
})
}

Expand Down Expand Up @@ -1478,7 +1480,7 @@ pub enum Literal<'tcx> {
substs: &'tcx Substs<'tcx>,
},
Value {
value: ConstVal<'tcx>,
value: &'tcx ConstVal<'tcx>,
},
Promoted {
// Index into the `promoted` vector of `Mir`.
Expand Down Expand Up @@ -1516,9 +1518,9 @@ fn fmt_const_val<W: Write>(fmt: &mut W, const_val: &ConstVal) -> fmt::Result {
match *const_val {
Float(f) => write!(fmt, "{:?}", f),
Integral(n) => write!(fmt, "{}", n),
Str(ref s) => write!(fmt, "{:?}", s),
ByteStr(ref bytes) => {
let escaped: String = bytes
Str(s) => write!(fmt, "{:?}", s),
ByteStr(bytes) => {
let escaped: String = bytes.data
.iter()
.flat_map(|&ch| ascii::escape_default(ch).map(|c| c as char))
.collect();
Expand All @@ -1528,8 +1530,7 @@ fn fmt_const_val<W: Write>(fmt: &mut W, const_val: &ConstVal) -> fmt::Result {
Char(c) => write!(fmt, "{:?}", c),
Variant(def_id) |
Function(def_id, _) => write!(fmt, "{}", item_path_str(def_id)),
Struct(_) | Tuple(_) | Array(_) | Repeat(..) =>
bug!("ConstVal `{:?}` should not be in MIR", const_val),
Aggregate(_) => bug!("`ConstVal::{:?}` should not be in MIR", const_val),
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/librustc/mir/visit.rs
Expand Up @@ -233,7 +233,7 @@ macro_rules! make_mir_visitor {
}

fn visit_const_val(&mut self,
const_val: & $($mutability)* ConstVal,
const_val: & $($mutability)* &'tcx ConstVal<'tcx>,
_: Location) {
self.super_const_val(const_val);
}
Expand Down Expand Up @@ -760,7 +760,7 @@ macro_rules! make_mir_visitor {
_substs: & $($mutability)* ClosureSubsts<'tcx>) {
}

fn super_const_val(&mut self, _const_val: & $($mutability)* ConstVal) {
fn super_const_val(&mut self, _const_val: & $($mutability)* &'tcx ConstVal<'tcx>) {
}

fn super_const_int(&mut self, _const_int: &ConstInt) {
Expand Down
38 changes: 37 additions & 1 deletion src/librustc/ty/context.rs
Expand Up @@ -21,6 +21,7 @@ use hir::map as hir_map;
use hir::map::DefPathHash;
use lint::{self, Lint};
use ich::{self, StableHashingContext, NodeIdHashingMode};
use middle::const_val::ConstVal;
use middle::free_region::FreeRegionMap;
use middle::lang_items;
use middle::resolve_lifetime::{self, ObjectLifetimeDefault};
Expand Down Expand Up @@ -108,6 +109,7 @@ pub struct CtxtInterners<'tcx> {
region: RefCell<FxHashSet<Interned<'tcx, RegionKind>>>,
existential_predicates: RefCell<FxHashSet<Interned<'tcx, Slice<ExistentialPredicate<'tcx>>>>>,
predicates: RefCell<FxHashSet<Interned<'tcx, Slice<Predicate<'tcx>>>>>,
const_: RefCell<FxHashSet<Interned<'tcx, ConstVal<'tcx>>>>,
}

impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
Expand All @@ -120,6 +122,7 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
region: RefCell::new(FxHashSet()),
existential_predicates: RefCell::new(FxHashSet()),
predicates: RefCell::new(FxHashSet()),
const_: RefCell::new(FxHashSet()),
}
}

Expand Down Expand Up @@ -934,6 +937,32 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
self.global_arenas.adt_def.alloc(def)
}

pub fn alloc_byte_array(self, bytes: &[u8]) -> &'gcx [u8] {
if bytes.is_empty() {
&[]
} else {
self.global_interners.arena.alloc_slice(bytes)
}
}

pub fn alloc_constval_slice(self, values: &[&'tcx ConstVal<'gcx>])
-> &'gcx [&'tcx ConstVal<'gcx>] {
if values.is_empty() {
&[]
} else {
self.global_interners.arena.alloc_slice(values)
}
}

pub fn alloc_name_constval_slice(self, values: &[(ast::Name, &'tcx ConstVal<'gcx>)])
-> &'gcx [(ast::Name, &'tcx ConstVal<'gcx>)] {
if values.is_empty() {
&[]
} else {
self.global_interners.arena.alloc_slice(values)
}
}

pub fn intern_stability(self, stab: attr::Stability) -> &'gcx attr::Stability {
if let Some(st) = self.stability_interner.borrow().get(&stab) {
return st;
Expand Down Expand Up @@ -1507,6 +1536,12 @@ impl<'tcx: 'lcx, 'lcx> Borrow<[Predicate<'lcx>]>
}
}

impl<'tcx: 'lcx, 'lcx> Borrow<ConstVal<'lcx>> for Interned<'tcx, ConstVal<'tcx>> {
fn borrow<'a>(&'a self) -> &'a ConstVal<'lcx> {
&self.0
}
}

macro_rules! intern_method {
($lt_tcx:tt, $name:ident: $method:ident($alloc:ty,
$alloc_method:ident,
Expand Down Expand Up @@ -1587,7 +1622,8 @@ direct_interners!('tcx,
&ty::ReVar(_) | &ty::ReSkolemized(..) => true,
_ => false
}
}) -> RegionKind
}) -> RegionKind,
const_: mk_const(/*|c: &Const| keep_local(&c.ty)*/ |_| false) -> ConstVal<'tcx>
);

macro_rules! slice_interners {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/ty/mod.rs
Expand Up @@ -1601,7 +1601,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
if let VariantDiscr::Explicit(expr_did) = v.discr {
let substs = Substs::identity_for_item(tcx.global_tcx(), expr_did);
match tcx.const_eval(param_env.and((expr_did, substs))) {
Ok(ConstVal::Integral(v)) => {
Ok(&ConstVal::Integral(v)) => {
discr = v;
}
err => {
Expand Down Expand Up @@ -1641,7 +1641,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
ty::VariantDiscr::Explicit(expr_did) => {
let substs = Substs::identity_for_item(tcx.global_tcx(), expr_did);
match tcx.const_eval(param_env.and((expr_did, substs))) {
Ok(ConstVal::Integral(v)) => {
Ok(&ConstVal::Integral(v)) => {
explicit_value = v;
break;
}
Expand Down

0 comments on commit 50076b0

Please sign in to comment.