Skip to content

Commit

Permalink
rustc: introduce ty::Const { ConstVal, Ty }.
Browse files Browse the repository at this point in the history
  • Loading branch information
eddyb committed Sep 11, 2017
1 parent 50076b0 commit 932289c
Show file tree
Hide file tree
Showing 31 changed files with 409 additions and 194 deletions.
9 changes: 7 additions & 2 deletions src/librustc/ich/impls_ty.rs
Expand Up @@ -277,10 +277,10 @@ for ::middle::const_val::ConstVal<'gcx> {
mem::discriminant(self).hash_stable(hcx, hasher);

match *self {
Float(ref value) => {
Integral(ref value) => {
value.hash_stable(hcx, hasher);
}
Integral(ref value) => {
Float(ref value) => {
value.hash_stable(hcx, hasher);
}
Str(ref value) => {
Expand Down Expand Up @@ -325,6 +325,11 @@ impl_stable_hash_for!(struct ::middle::const_val::ByteArray<'tcx> {
data
});

impl_stable_hash_for!(struct ty::Const<'tcx> {
ty,
val
});

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

impl_stable_hash_for!(struct ty::GeneratorInterior<'tcx> { witness });
Expand Down
16 changes: 7 additions & 9 deletions src/librustc/middle/const_val.rs
Expand Up @@ -30,12 +30,12 @@ use syntax_pos::Span;

use std::borrow::Cow;

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

#[derive(Copy, Clone, Debug, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq)]
pub enum ConstVal<'tcx> {
Float(ConstFloat),
Integral(ConstInt),
Float(ConstFloat),
Str(InternedString),
ByteStr(ByteArray<'tcx>),
Bool(bool),
Expand All @@ -45,8 +45,6 @@ pub enum ConstVal<'tcx> {
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],
Expand All @@ -56,10 +54,10 @@ 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),
Struct(&'tcx [(ast::Name, &'tcx ty::Const<'tcx>)]),
Tuple(&'tcx [&'tcx ty::Const<'tcx>]),
Array(&'tcx [&'tcx ty::Const<'tcx>]),
Repeat(&'tcx ty::Const<'tcx>, u64),
}

impl<'tcx> Encodable for ConstAggregate<'tcx> {
Expand Down Expand Up @@ -259,7 +257,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(&ty::Const { val: 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
14 changes: 9 additions & 5 deletions src/librustc/mir/mod.rs
Expand Up @@ -1187,11 +1187,15 @@ impl<'tcx> Operand<'tcx> {
substs: &'tcx Substs<'tcx>,
span: Span,
) -> Self {
let ty = tcx.type_of(def_id).subst(tcx, substs);
Operand::Constant(box Constant {
span,
ty: tcx.type_of(def_id).subst(tcx, substs),
ty,
literal: Literal::Value {
value: tcx.mk_const(ConstVal::Function(def_id, substs))
value: tcx.mk_const(ty::Const {
val: ConstVal::Function(def_id, substs),
ty
})
},
})
}
Expand Down Expand Up @@ -1480,7 +1484,7 @@ pub enum Literal<'tcx> {
substs: &'tcx Substs<'tcx>,
},
Value {
value: &'tcx ConstVal<'tcx>,
value: &'tcx ty::Const<'tcx>,
},
Promoted {
// Index into the `promoted` vector of `Mir`.
Expand All @@ -1501,9 +1505,9 @@ impl<'tcx> Debug for Literal<'tcx> {
Item { def_id, substs } => {
ppaux::parameterized(fmt, substs, def_id, &[])
}
Value { ref value } => {
Value { value } => {
write!(fmt, "const ")?;
fmt_const_val(fmt, value)
fmt_const_val(fmt, &value.val)
}
Promoted { index } => {
write!(fmt, "{:?}", index)
Expand Down
35 changes: 22 additions & 13 deletions src/librustc/mir/visit.rs
Expand Up @@ -8,7 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use middle::const_val::ConstVal;
use hir::def_id::DefId;
use ty::subst::Substs;
use ty::{ClosureSubsts, Region, Ty, GeneratorInterior};
Expand Down Expand Up @@ -214,6 +213,18 @@ macro_rules! make_mir_visitor {
self.super_ty(ty);
}

fn visit_region(&mut self,
region: & $($mutability)* ty::Region<'tcx>,
_: Location) {
self.super_region(region);
}

fn visit_const(&mut self,
constant: & $($mutability)* &'tcx ty::Const<'tcx>,
_: Location) {
self.super_const(constant);
}

fn visit_substs(&mut self,
substs: & $($mutability)* &'tcx Substs<'tcx>,
_: Location) {
Expand All @@ -232,12 +243,6 @@ macro_rules! make_mir_visitor {
self.super_generator_interior(interior);
}

fn visit_const_val(&mut self,
const_val: & $($mutability)* &'tcx ConstVal<'tcx>,
_: Location) {
self.super_const_val(const_val);
}

fn visit_const_int(&mut self,
const_int: &ConstInt,
_: Location) {
Expand Down Expand Up @@ -517,9 +522,10 @@ macro_rules! make_mir_visitor {
self.visit_const_usize(length, location);
}

Rvalue::Ref(r, bk, ref $($mutability)* path) => {
Rvalue::Ref(ref $($mutability)* r, bk, ref $($mutability)* path) => {
self.visit_region(r, location);
self.visit_lvalue(path, LvalueContext::Borrow {
region: r,
region: *r,
kind: bk
}, location);
}
Expand Down Expand Up @@ -724,7 +730,7 @@ macro_rules! make_mir_visitor {
self.visit_substs(substs, location);
}
Literal::Value { ref $($mutability)* value } => {
self.visit_const_val(value, location);
self.visit_const(value, location);
}
Literal::Promoted { index: _ } => {}
}
Expand All @@ -749,6 +755,12 @@ macro_rules! make_mir_visitor {
fn super_ty(&mut self, _ty: & $($mutability)* Ty<'tcx>) {
}

fn super_region(&mut self, _region: & $($mutability)* ty::Region<'tcx>) {
}

fn super_const(&mut self, _const: & $($mutability)* &'tcx ty::Const<'tcx>) {
}

fn super_substs(&mut self, _substs: & $($mutability)* &'tcx Substs<'tcx>) {
}

Expand All @@ -760,9 +772,6 @@ macro_rules! make_mir_visitor {
_substs: & $($mutability)* ClosureSubsts<'tcx>) {
}

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

fn super_const_int(&mut self, _const_int: &ConstInt) {
}

Expand Down
58 changes: 36 additions & 22 deletions src/librustc/ty/context.rs
Expand Up @@ -21,7 +21,6 @@ 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 All @@ -33,7 +32,7 @@ use ty::ReprOptions;
use traits;
use ty::{self, Ty, TypeAndMut};
use ty::{TyS, TypeVariants, Slice};
use ty::{AdtKind, AdtDef, ClosureSubsts, GeneratorInterior, Region};
use ty::{AdtKind, AdtDef, ClosureSubsts, GeneratorInterior, Region, Const};
use ty::{PolyFnSig, InferTy, ParamTy, ProjectionTy, ExistentialPredicate, Predicate};
use ty::RegionKind;
use ty::{TyVar, TyVid, IntVar, IntVid, FloatVar, FloatVid};
Expand Down Expand Up @@ -109,7 +108,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>>>>,
const_: RefCell<FxHashSet<Interned<'tcx, Const<'tcx>>>>,
}

impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
Expand Down Expand Up @@ -945,21 +944,21 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
}

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

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

Expand Down Expand Up @@ -1216,13 +1215,10 @@ impl<'a, 'tcx> Lift<'tcx> for Ty<'a> {
}
}

impl<'a, 'tcx> Lift<'tcx> for &'a Substs<'a> {
type Lifted = &'tcx Substs<'tcx>;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<&'tcx Substs<'tcx>> {
if self.len() == 0 {
return Some(Slice::empty());
}
if tcx.interners.arena.in_arena(&self[..] as *const _) {
impl<'a, 'tcx> Lift<'tcx> for Region<'a> {
type Lifted = Region<'tcx>;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Region<'tcx>> {
if tcx.interners.arena.in_arena(*self as *const _) {
return Some(unsafe { mem::transmute(*self) });
}
// Also try in the global tcx if we're not that.
Expand All @@ -1234,9 +1230,9 @@ impl<'a, 'tcx> Lift<'tcx> for &'a Substs<'a> {
}
}

impl<'a, 'tcx> Lift<'tcx> for Region<'a> {
type Lifted = Region<'tcx>;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Region<'tcx>> {
impl<'a, 'tcx> Lift<'tcx> for &'a Const<'a> {
type Lifted = &'tcx Const<'tcx>;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<&'tcx Const<'tcx>> {
if tcx.interners.arena.in_arena(*self as *const _) {
return Some(unsafe { mem::transmute(*self) });
}
Expand All @@ -1249,6 +1245,24 @@ impl<'a, 'tcx> Lift<'tcx> for Region<'a> {
}
}

impl<'a, 'tcx> Lift<'tcx> for &'a Substs<'a> {
type Lifted = &'tcx Substs<'tcx>;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<&'tcx Substs<'tcx>> {
if self.len() == 0 {
return Some(Slice::empty());
}
if tcx.interners.arena.in_arena(&self[..] as *const _) {
return Some(unsafe { mem::transmute(*self) });
}
// Also try in the global tcx if we're not that.
if !tcx.is_global() {
self.lift_to_tcx(tcx.global_tcx())
} else {
None
}
}
}

impl<'a, 'tcx> Lift<'tcx> for &'a Slice<Ty<'a>> {
type Lifted = &'tcx Slice<Ty<'tcx>>;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
Expand Down Expand Up @@ -1536,8 +1550,8 @@ 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> {
impl<'tcx: 'lcx, 'lcx> Borrow<Const<'lcx>> for Interned<'tcx, Const<'tcx>> {
fn borrow<'a>(&'a self) -> &'a Const<'lcx> {
&self.0
}
}
Expand Down Expand Up @@ -1623,7 +1637,7 @@ direct_interners!('tcx,
_ => false
}
}) -> RegionKind,
const_: mk_const(/*|c: &Const| keep_local(&c.ty)*/ |_| false) -> ConstVal<'tcx>
const_: mk_const(|c: &Const| keep_local(&c.ty) || keep_local(&c.val)) -> Const<'tcx>
);

macro_rules! slice_interners {
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/ty/mod.rs
Expand Up @@ -64,7 +64,7 @@ pub use self::sty::{InferTy, ParamTy, ProjectionTy, ExistentialPredicate};
pub use self::sty::{ClosureSubsts, GeneratorInterior, TypeAndMut};
pub use self::sty::{TraitRef, TypeVariants, PolyTraitRef};
pub use self::sty::{ExistentialTraitRef, PolyExistentialTraitRef};
pub use self::sty::{ExistentialProjection, PolyExistentialProjection};
pub use self::sty::{ExistentialProjection, PolyExistentialProjection, Const};
pub use self::sty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region};
pub use self::sty::RegionKind;
pub use self::sty::{TyVid, IntVid, FloatVid, RegionVid, SkolemizedRegionVid};
Expand Down 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(&ty::Const { val: 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(&ty::Const { val: ConstVal::Integral(v), .. }) => {
explicit_value = v;
break;
}
Expand Down

0 comments on commit 932289c

Please sign in to comment.