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) => {
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 });
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),
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],
#[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> {
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)
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
+ })
},
})
}
substs: &'tcx Substs<'tcx>,
},
Value {
- value: &'tcx ConstVal<'tcx>,
+ value: &'tcx ty::Const<'tcx>,
},
Promoted {
// Index into the `promoted` vector of `Mir`.
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)
// 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};
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) {
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) {
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);
}
self.visit_substs(substs, location);
}
Literal::Value { ref $($mutability)* value } => {
- self.visit_const_val(value, location);
+ self.visit_const(value, location);
}
Literal::Promoted { index: _ } => {}
}
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>) {
}
_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) {
}
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};
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};
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> {
}
}
- 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)
}
}
}
}
-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.
}
}
-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) });
}
}
}
+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>)
}
}
-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
}
}
_ => 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 {
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};
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 => {
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;
}
// except according to those terms.
use infer::type_variable;
+use middle::const_val::{ConstVal, ConstAggregate};
use ty::{self, Lift, Ty, TyCtxt};
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
use rustc_data_structures::accumulate_vec::AccumulateVec;
}
}
}
+
+impl<'tcx> TypeFoldable<'tcx> for ConstVal<'tcx> {
+ fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+ match *self {
+ ConstVal::Integral(i) => ConstVal::Integral(i),
+ ConstVal::Float(f) => ConstVal::Float(f),
+ ConstVal::Str(s) => ConstVal::Str(s),
+ ConstVal::ByteStr(b) => ConstVal::ByteStr(b),
+ ConstVal::Bool(b) => ConstVal::Bool(b),
+ ConstVal::Char(c) => ConstVal::Char(c),
+ ConstVal::Variant(def_id) => ConstVal::Variant(def_id),
+ ConstVal::Function(def_id, substs) => {
+ ConstVal::Function(def_id, substs.fold_with(folder))
+ }
+ ConstVal::Aggregate(ConstAggregate::Struct(fields)) => {
+ let new_fields: Vec<_> = fields.iter().map(|&(name, v)| {
+ (name, v.fold_with(folder))
+ }).collect();
+ let fields = if new_fields == fields {
+ fields
+ } else {
+ folder.tcx().alloc_name_const_slice(&new_fields)
+ };
+ ConstVal::Aggregate(ConstAggregate::Struct(fields))
+ }
+ ConstVal::Aggregate(ConstAggregate::Tuple(fields)) => {
+ let new_fields: Vec<_> = fields.iter().map(|v| {
+ v.fold_with(folder)
+ }).collect();
+ let fields = if new_fields == fields {
+ fields
+ } else {
+ folder.tcx().alloc_const_slice(&new_fields)
+ };
+ ConstVal::Aggregate(ConstAggregate::Tuple(fields))
+ }
+ ConstVal::Aggregate(ConstAggregate::Array(fields)) => {
+ let new_fields: Vec<_> = fields.iter().map(|v| {
+ v.fold_with(folder)
+ }).collect();
+ let fields = if new_fields == fields {
+ fields
+ } else {
+ folder.tcx().alloc_const_slice(&new_fields)
+ };
+ ConstVal::Aggregate(ConstAggregate::Array(fields))
+ }
+ ConstVal::Aggregate(ConstAggregate::Repeat(v, count)) => {
+ let v = v.fold_with(folder);
+ ConstVal::Aggregate(ConstAggregate::Repeat(v, count))
+ }
+ }
+ }
+
+ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
+ match *self {
+ ConstVal::Integral(_) |
+ ConstVal::Float(_) |
+ ConstVal::Str(_) |
+ ConstVal::ByteStr(_) |
+ ConstVal::Bool(_) |
+ ConstVal::Char(_) |
+ ConstVal::Variant(_) => false,
+ ConstVal::Function(_, substs) => substs.visit_with(visitor),
+ ConstVal::Aggregate(ConstAggregate::Struct(fields)) => {
+ fields.iter().any(|&(_, v)| v.visit_with(visitor))
+ }
+ ConstVal::Aggregate(ConstAggregate::Tuple(fields)) |
+ ConstVal::Aggregate(ConstAggregate::Array(fields)) => {
+ fields.iter().any(|v| v.visit_with(visitor))
+ }
+ ConstVal::Aggregate(ConstAggregate::Repeat(v, _)) => {
+ v.visit_with(visitor)
+ }
+ }
+ }
+}
+
+impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> {
+ fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+ let ty = self.ty.fold_with(folder);
+ let val = self.val.fold_with(folder);
+ folder.tcx().mk_const(ty::Const {
+ ty,
+ val
+ })
+ }
+
+ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
+ self.ty.visit_with(visitor) || self.val.visit_with(visitor)
+ }
+}
use hir::def_id::DefId;
+use middle::const_val::ConstVal;
use middle::region;
use ty::subst::{Substs, Subst};
use ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable};
}
}
}
+
+/// Typed constant value.
+#[derive(Copy, Clone, Debug, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq)]
+pub struct Const<'tcx> {
+ pub ty: Ty<'tcx>,
+
+ // FIXME(eddyb) Replace this with a miri value.
+ pub val: ConstVal<'tcx>,
+}
+
+impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Const<'tcx> {}
self.byte_array_map.entry(pat).or_insert_with(|| {
match pat.kind {
box PatternKind::Constant {
- value: &ConstVal::ByteStr(b)
+ value: &ty::Const { val: ConstVal::ByteStr(b), .. }
} => {
b.data.iter().map(|&b| &*pattern_arena.alloc(Pattern {
ty: tcx.types.u8,
span: pat.span,
kind: box PatternKind::Constant {
- value: tcx.mk_const(ConstVal::Integral(ConstInt::U8(b)))
+ value: tcx.mk_const(ty::Const {
+ val: ConstVal::Integral(ConstInt::U8(b)),
+ ty: tcx.types.u8
+ })
}
})).collect()
}
/// Enum variants.
Variant(DefId),
/// Literal values.
- ConstantValue(&'tcx ConstVal<'tcx>),
+ ConstantValue(&'tcx ty::Const<'tcx>),
/// Ranges of literal values (`2...5` and `2..5`).
- ConstantRange(&'tcx ConstVal<'tcx>, &'tcx ConstVal<'tcx>, RangeEnd),
+ ConstantRange(&'tcx ty::Const<'tcx>, &'tcx ty::Const<'tcx>, RangeEnd),
/// Array patterns of length n.
Slice(usize),
}
match pcx.ty.sty {
ty::TyBool => {
[true, false].iter().map(|&b| {
- ConstantValue(cx.tcx.mk_const(ConstVal::Bool(b)))
+ ConstantValue(cx.tcx.mk_const(ty::Const {
+ val: ConstVal::Bool(b),
+ ty: cx.tcx.types.bool
+ }))
}).collect()
}
ty::TySlice(ref sub_ty) => {
for row in patterns {
match *row.kind {
- PatternKind::Constant { value: &ConstVal::ByteStr(b) } => {
+ PatternKind::Constant { value: &ty::Const { val: ConstVal::ByteStr(b), .. } } => {
max_fixed_len = cmp::max(max_fixed_len, b.data.len());
}
PatternKind::Slice { ref prefix, slice: None, ref suffix } => {
suffix: &[Pattern])
-> Result<bool, ErrorReported> {
let data = match *ctor {
- ConstantValue(&ConstVal::ByteStr(b)) => b.data,
+ ConstantValue(&ty::Const { val: ConstVal::ByteStr(b), .. }) => b.data,
_ => bug!()
};
data[data.len()-suffix.len()..].iter().zip(suffix))
{
match pat.kind {
- box PatternKind::Constant { value } => match *value {
+ box PatternKind::Constant { value } => match value.val {
ConstVal::Integral(ConstInt::U8(u)) => {
if u != *ch {
return Ok(false);
let cmp_to = |c_to| compare_const_vals(tcx, span, c_to, to);
match *ctor {
ConstantValue(value) => {
- let to = cmp_to(value)?;
+ let to = cmp_to(&value.val)?;
let end = (to == Ordering::Less) ||
(end == RangeEnd::Included && to == Ordering::Equal);
- Ok(cmp_from(value)? && end)
+ Ok(cmp_from(&value.val)? && end)
},
ConstantRange(from, to, RangeEnd::Included) => {
- let to = cmp_to(to)?;
+ let to = cmp_to(&to.val)?;
let end = (to == Ordering::Less) ||
(end == RangeEnd::Included && to == Ordering::Equal);
- Ok(cmp_from(from)? && end)
+ Ok(cmp_from(&from.val)? && end)
},
ConstantRange(from, to, RangeEnd::Excluded) => {
- let to = cmp_to(to)?;
+ let to = cmp_to(&to.val)?;
let end = (to == Ordering::Less) ||
(end == RangeEnd::Excluded && to == Ordering::Equal);
- Ok(cmp_from(from)? && end)
+ Ok(cmp_from(&from.val)? && end)
}
Single => Ok(true),
_ => bug!(),
PatternKind::Constant { value } => {
match *constructor {
- Slice(..) => match *value {
+ Slice(..) => match value.val {
ConstVal::ByteStr(b) => {
if wild_patterns.len() == b.data.len() {
Some(cx.lower_byte_str_pattern(pat))
},
_ => {
match constructor_covered_by_range(
- cx.tcx, pat.span, constructor, value, value, RangeEnd::Included
+ cx.tcx, pat.span, constructor, &value.val, &value.val, RangeEnd::Included
) {
Ok(true) => Some(vec![]),
Ok(false) => None,
}
}
- PatternKind::Range { ref lo, ref hi, ref end } => {
+ PatternKind::Range { lo, hi, ref end } => {
match constructor_covered_by_range(
- cx.tcx, pat.span, constructor, lo, hi, end.clone()
+ cx.tcx, pat.span, constructor, &lo.val, &hi.val, end.clone()
) {
Ok(true) => Some(vec![]),
Ok(false) => None,
tables: &'a ty::TypeckTables<'tcx>,
param_env: ty::ParamEnv<'tcx>,
substs: &'tcx Substs<'tcx>,
- fn_args: Option<NodeMap<&'tcx ConstVal<'tcx>>>
+ fn_args: Option<NodeMap<&'tcx ty::Const<'tcx>>>
}
impl<'a, 'tcx> ConstContext<'a, 'tcx> {
fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
e: &'tcx Expr) -> EvalResult<'tcx> {
let tcx = cx.tcx;
- let ety = cx.tables.expr_ty(e).subst(tcx, cx.substs);
+ let ty = cx.tables.expr_ty(e).subst(tcx, cx.substs);
+ let mk_const = |val| tcx.mk_const(ty::Const { val, ty });
let result = match e.node {
hir::ExprUnary(hir::UnNeg, ref inner) => {
const I32_OVERFLOW: u128 = i32::min_value() as u32 as u128;
const I64_OVERFLOW: u128 = i64::min_value() as u64 as u128;
const I128_OVERFLOW: u128 = i128::min_value() as u128;
- let negated = match (&lit.node, &ety.sty) {
+ let negated = match (&lit.node, &ty.sty) {
(&LitKind::Int(I8_OVERFLOW, _), &ty::TyInt(IntTy::I8)) |
(&LitKind::Int(I8_OVERFLOW, Signed(IntTy::I8)), _) => {
Some(I8(i8::min_value()))
_ => None
};
if let Some(i) = negated {
- return Ok(tcx.mk_const(Integral(i)));
+ return Ok(mk_const(Integral(i)));
}
}
- tcx.mk_const(match *cx.eval(inner)? {
+ mk_const(match cx.eval(inner)?.val {
Float(f) => Float(-f),
Integral(i) => Integral(math!(e, -i)),
const_val => signal!(e, NegateOn(const_val)),
})
}
hir::ExprUnary(hir::UnNot, ref inner) => {
- tcx.mk_const(match *cx.eval(inner)? {
+ mk_const(match cx.eval(inner)?.val {
Integral(i) => Integral(math!(e, !i)),
Bool(b) => Bool(!b),
const_val => signal!(e, NotOn(const_val)),
// gives us a type through a type-suffix, cast or const def type
// we need to re-eval the other value of the BinOp if it was
// not inferred
- tcx.mk_const(match (*cx.eval(a)?, *cx.eval(b)?) {
+ mk_const(match (cx.eval(a)?.val, cx.eval(b)?.val) {
(Float(a), Float(b)) => {
use std::cmp::Ordering::*;
match op.node {
hir::ExprCast(ref base, _) => {
let base_val = cx.eval(base)?;
let base_ty = cx.tables.expr_ty(base).subst(tcx, cx.substs);
- if ety == base_ty {
+ if ty == base_ty {
base_val
} else {
- match cast_const(tcx, *base_val, ety) {
- Ok(val) => tcx.mk_const(val),
+ match cast_const(tcx, base_val.val, ty) {
+ Ok(val) => mk_const(val),
Err(kind) => signal!(e, kind),
}
}
}
},
Def::VariantCtor(variant_def, CtorKind::Const) => {
- tcx.mk_const(Variant(variant_def))
+ mk_const(Variant(variant_def))
}
Def::VariantCtor(_, CtorKind::Fn) => {
signal!(e, UnimplementedConstVal("enum variants"));
}
Def::StructCtor(_, CtorKind::Const) => {
- tcx.mk_const(Aggregate(Struct(&[])))
+ mk_const(Aggregate(Struct(&[])))
}
Def::StructCtor(_, CtorKind::Fn) => {
signal!(e, UnimplementedConstVal("tuple struct constructors"))
signal!(e, NonConstPath);
}
},
- Def::Method(id) | Def::Fn(id) => tcx.mk_const(Function(id, substs)),
+ Def::Method(id) | Def::Fn(id) => mk_const(Function(id, substs)),
Def::Err => span_bug!(e.span, "typeck error"),
_ => signal!(e, NonConstPath),
}
}
hir::ExprCall(ref callee, ref args) => {
- let (def_id, substs) = match *cx.eval(callee)? {
+ let (def_id, substs) = match cx.eval(callee)?.val {
Function(def_id, substs) => (def_id, substs),
_ => signal!(e, TypeckError),
};
match &tcx.item_name(def_id)[..] {
"size_of" => {
let size = layout_of(substs.type_at(0))?.size(tcx).bytes();
- return Ok(tcx.mk_const(Integral(Usize(ConstUsize::new(size,
+ return Ok(mk_const(Integral(Usize(ConstUsize::new(size,
tcx.sess.target.uint_type).unwrap()))));
}
"min_align_of" => {
let align = layout_of(substs.type_at(0))?.align(tcx).abi();
- return Ok(tcx.mk_const(Integral(Usize(ConstUsize::new(align,
+ return Ok(mk_const(Integral(Usize(ConstUsize::new(align,
tcx.sess.target.uint_type).unwrap()))));
}
_ => signal!(e, TypeckError)
};
callee_cx.eval(&body.value)?
},
- hir::ExprLit(ref lit) => match lit_to_const(&lit.node, tcx, ety) {
- Ok(val) => tcx.mk_const(val),
+ hir::ExprLit(ref lit) => match lit_to_const(&lit.node, tcx, ty) {
+ Ok(val) => mk_const(val),
Err(err) => signal!(e, err),
},
hir::ExprBlock(ref block) => {
match block.expr {
Some(ref expr) => cx.eval(expr)?,
- None => tcx.mk_const(Aggregate(Tuple(&[]))),
+ None => mk_const(Aggregate(Tuple(&[]))),
}
}
hir::ExprType(ref e, _) => cx.eval(e)?,
hir::ExprTup(ref fields) => {
let values = fields.iter().map(|e| cx.eval(e)).collect::<Result<Vec<_>, _>>()?;
- tcx.mk_const(Aggregate(Tuple(tcx.alloc_constval_slice(&values))))
+ mk_const(Aggregate(Tuple(tcx.alloc_const_slice(&values))))
}
hir::ExprStruct(_, ref fields, _) => {
- tcx.mk_const(Aggregate(Struct(tcx.alloc_name_constval_slice(&fields.iter().map(|f| {
+ mk_const(Aggregate(Struct(tcx.alloc_name_const_slice(&fields.iter().map(|f| {
cx.eval(&f.expr).map(|v| (f.name.node, v))
}).collect::<Result<Vec<_>, _>>()?))))
}
signal!(e, IndexOpFeatureGated);
}
let arr = cx.eval(arr)?;
- let idx = match *cx.eval(idx)? {
+ let idx = match cx.eval(idx)?.val {
Integral(Usize(i)) => i.as_u64(tcx.sess.target.uint_type),
_ => signal!(idx, IndexNotUsize),
};
assert_eq!(idx as usize as u64, idx);
- match *arr {
+ match arr.val {
Aggregate(Array(v)) => {
if let Some(&elem) = v.get(idx as usize) {
elem
signal!(e, IndexOutOfBounds { len: b.data.len() as u64, index: idx })
}
ByteStr(b) => {
- tcx.mk_const(Integral(U8(b.data[idx as usize])))
+ mk_const(Integral(U8(b.data[idx as usize])))
},
_ => signal!(e, IndexedNonVec),
}
hir::ExprArray(ref v) => {
let values = v.iter().map(|e| cx.eval(e)).collect::<Result<Vec<_>, _>>()?;
- tcx.mk_const(Aggregate(Array(tcx.alloc_constval_slice(&values))))
+ mk_const(Aggregate(Array(tcx.alloc_const_slice(&values))))
}
hir::ExprRepeat(ref elem, _) => {
- let n = match ety.sty {
+ let n = match ty.sty {
ty::TyArray(_, n) => n as u64,
_ => span_bug!(e.span, "typeck error")
};
- tcx.mk_const(Aggregate(Repeat(cx.eval(elem)?, n)))
+ mk_const(Aggregate(Repeat(cx.eval(elem)?, n)))
},
hir::ExprTupField(ref base, index) => {
- if let Aggregate(Tuple(fields)) = *cx.eval(base)? {
+ if let Aggregate(Tuple(fields)) = cx.eval(base)?.val {
fields[index.node]
} else {
signal!(base, ExpectedConstTuple);
}
}
hir::ExprField(ref base, field_name) => {
- if let Aggregate(Struct(fields)) = *cx.eval(base)? {
+ if let Aggregate(Struct(fields)) = cx.eval(base)?.val {
if let Some(&(_, f)) = fields.iter().find(|&&(name, _)| name == field_name.node) {
f
} else {
return Err(ErrorReported);
}
};
- compare_const_vals(tcx, span, &a, &b)
+ compare_const_vals(tcx, span, &a.val, &b.val)
}
}
},
Constant {
- value: &'tcx ConstVal<'tcx>,
+ value: &'tcx ty::Const<'tcx>,
},
Range {
- lo: &'tcx ConstVal<'tcx>,
- hi: &'tcx ConstVal<'tcx>,
+ lo: &'tcx ty::Const<'tcx>,
+ hi: &'tcx ty::Const<'tcx>,
end: RangeEnd,
},
write!(f, "{}", subpattern)
}
PatternKind::Constant { value } => {
- print_const_val(value, f)
+ print_const_val(&value.val, f)
}
PatternKind::Range { lo, hi, end } => {
- print_const_val(lo, f)?;
+ print_const_val(&lo.val, f)?;
match end {
RangeEnd::Included => write!(f, "...")?,
RangeEnd::Excluded => write!(f, "..")?,
}
- print_const_val(hi, f)
+ print_const_val(&hi.val, f)
}
PatternKind::Slice { ref prefix, ref slice, ref suffix } |
PatternKind::Array { ref prefix, ref slice, ref suffix } => {
self.tables);
match const_cx.eval(expr) {
Ok(value) => {
- if let ConstVal::Variant(def_id) = *value {
+ if let ConstVal::Variant(def_id) = value.val {
let ty = self.tables.expr_ty(expr);
self.lower_variant_or_leaf(Def::Variant(def_id), ty, vec![])
} else {
}
CloneImpls!{ <'tcx>
- Span, Field, Mutability, ast::Name, ast::NodeId, usize, &'tcx ConstVal<'tcx>,
+ Span, Field, Mutability, ast::Name, ast::NodeId, usize, &'tcx ty::Const<'tcx>,
Region<'tcx>, Ty<'tcx>, BindingMode<'tcx>, &'tcx AdtDef,
&'tcx Substs<'tcx>, &'tcx Kind<'tcx>
}
cx.param_env.and(substs),
cx.tables);
match const_cx.eval(&r) {
- Ok(&ConstVal::Integral(i)) => {
+ Ok(&ty::Const { val: ConstVal::Integral(i), .. }) => {
i.is_negative() ||
i.to_u64()
.map(|i| i >= bits)
use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash};
use rustc::hir;
-use rustc::middle::const_val::{ByteArray, ConstVal};
+use rustc::middle::const_val::ByteArray;
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};
}
}
-impl<'a, 'tcx> SpecializedDecoder<&'tcx ConstVal<'tcx>> for DecodeContext<'a, 'tcx> {
- fn specialized_decode(&mut self) -> Result<&'tcx ConstVal<'tcx>, Self::Error> {
+impl<'a, 'tcx> SpecializedDecoder<&'tcx ty::Const<'tcx>> for DecodeContext<'a, 'tcx> {
+ fn specialized_decode(&mut self) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
Ok(self.tcx().mk_const(Decodable::decode(self)?))
}
}
span: expr_span,
ty: this.hir.tcx().types.u32,
literal: Literal::Value {
- value: this.hir.tcx().mk_const(ConstVal::Integral(ConstInt::U32(0))),
+ value: this.hir.tcx().mk_const(ty::Const {
+ val: ConstVal::Integral(ConstInt::U32(0)),
+ ty: this.hir.tcx().types.u32
+ }),
},
}));
box AggregateKind::Generator(closure_id, substs, interior)
};
Literal::Value {
- value: self.hir.tcx().mk_const(ConstVal::Integral(val))
+ value: self.hir.tcx().mk_const(ty::Const {
+ val: ConstVal::Integral(val),
+ ty
+ })
}
}
_ => {
};
Literal::Value {
- value: self.hir.tcx().mk_const(ConstVal::Integral(val))
+ value: self.hir.tcx().mk_const(ty::Const {
+ val: ConstVal::Integral(val),
+ ty
+ })
}
}
_ => {
use build::{BlockAnd, BlockAndExtension, Builder};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::bitvec::BitVector;
-use rustc::middle::const_val::ConstVal;
-use rustc::ty::{AdtDef, Ty};
+use rustc::ty::{self, Ty};
use rustc::mir::*;
use rustc::hir;
use hair::*;
enum TestKind<'tcx> {
// test the branches of enum
Switch {
- adt_def: &'tcx AdtDef,
+ adt_def: &'tcx ty::AdtDef,
variants: BitVector,
},
// test the branches of enum
SwitchInt {
switch_ty: Ty<'tcx>,
- options: Vec<&'tcx ConstVal<'tcx>>,
- indices: FxHashMap<&'tcx ConstVal<'tcx>, usize>,
+ options: Vec<&'tcx ty::Const<'tcx>>,
+ indices: FxHashMap<&'tcx ty::Const<'tcx>, usize>,
},
// test for equality
Eq {
- value: &'tcx ConstVal<'tcx>,
+ value: &'tcx ty::Const<'tcx>,
ty: Ty<'tcx>,
},
test_lvalue: &Lvalue<'tcx>,
candidate: &Candidate<'pat, 'tcx>,
switch_ty: Ty<'tcx>,
- options: &mut Vec<&'tcx ConstVal<'tcx>>,
- indices: &mut FxHashMap<&'tcx ConstVal<'tcx>, usize>)
+ options: &mut Vec<&'tcx ty::Const<'tcx>>,
+ indices: &mut FxHashMap<&'tcx ty::Const<'tcx>, usize>)
-> bool
{
let match_pair = match candidate.match_pairs.iter().find(|mp| mp.lvalue == *test_lvalue) {
assert!(options.len() > 0 && options.len() <= 2);
let (true_bb, false_bb) = (self.cfg.start_new_block(),
self.cfg.start_new_block());
- let ret = match *options[0] {
+ let ret = match options[0].val {
ConstVal::Bool(true) => vec![true_bb, false_bb],
ConstVal::Bool(false) => vec![false_bb, true_bb],
v => span_bug!(test.span, "expected boolean value but got {:?}", v)
.chain(Some(otherwise))
.collect();
let values: Vec<_> = options.iter().map(|v|
- v.to_const_int().expect("switching on integral")
+ v.val.to_const_int().expect("switching on integral")
).collect();
(targets.clone(), TerminatorKind::SwitchInt {
discr: Operand::Consume(lvalue.clone()),
// If we're using b"..." as a pattern, we need to insert an
// unsizing coercion, as the byte string has the type &[u8; N].
- let expect = if let ConstVal::ByteStr(bytes) = *value {
+ let expect = if let ConstVal::ByteStr(bytes) = value.val {
let tcx = self.hir.tcx();
// Unsize the lvalue to &[u8], too, if necessary.
}
ty::TyChar => {
Literal::Value {
- value: self.hir.tcx().mk_const(ConstVal::Char('\0'))
+ value: self.hir.tcx().mk_const(ty::Const {
+ val: ConstVal::Char('\0'),
+ ty
+ })
}
}
ty::TyUint(ity) => {
};
Literal::Value {
- value: self.hir.tcx().mk_const(ConstVal::Integral(val))
+ value: self.hir.tcx().mk_const(ty::Const {
+ val: ConstVal::Integral(val),
+ ty
+ })
}
}
ty::TyInt(ity) => {
};
Literal::Value {
- value: self.hir.tcx().mk_const(ConstVal::Integral(val))
+ value: self.hir.tcx().mk_const(ty::Const {
+ val: ConstVal::Integral(val),
+ ty
+ })
}
}
_ => {
}
}
+ fn visit_region(&mut self, region: &mut ty::Region<'tcx>, _: Location) {
+ if let Some(lifted) = self.tcx.lift(region) {
+ *region = lifted;
+ } else {
+ span_bug!(self.span,
+ "found region `{:?}` with inference types/regions in MIR",
+ region);
+ }
+ }
+
+ fn visit_const(&mut self, constant: &mut &'tcx ty::Const<'tcx>, _: Location) {
+ if let Some(lifted) = self.tcx.lift(constant) {
+ *constant = lifted;
+ } else {
+ span_bug!(self.span,
+ "found constant `{:?}` with inference types/regions in MIR",
+ constant);
+ }
+ }
+
fn visit_substs(&mut self, substs: &mut &'tcx Substs<'tcx>, _: Location) {
if let Some(lifted) = self.tcx.lift(substs) {
*substs = lifted;
let def_id = cx.tcx.hir.body_owner_def_id(count);
let substs = Substs::identity_for_item(cx.tcx.global_tcx(), def_id);
let count = match cx.tcx.at(c.span).const_eval(cx.param_env.and((def_id, substs))) {
- Ok(&ConstVal::Integral(ConstInt::Usize(u))) => u,
+ Ok(&ty::Const { val: ConstVal::Integral(ConstInt::Usize(u)), .. }) => u,
Ok(other) => bug!("constant evaluation of repeat count yielded {:?}", other),
Err(s) => cx.fatal_const_eval_err(&s, c.span, "expression")
};
(cx.tables().type_dependent_defs()[expr.hir_id].def_id(),
cx.tables().node_substs(expr.hir_id))
});
+ let ty = cx.tcx().mk_fn_def(def_id, substs);
Expr {
temp_lifetime,
- ty: cx.tcx().mk_fn_def(def_id, substs),
+ ty,
span: expr.span,
kind: ExprKind::Literal {
literal: Literal::Value {
- value: cx.tcx.mk_const(ConstVal::Function(def_id, substs)),
+ value: cx.tcx.mk_const(ty::Const {
+ val: ConstVal::Function(def_id, substs),
+ ty
+ }),
},
},
}
Def::StructCtor(def_id, CtorKind::Fn) |
Def::VariantCtor(def_id, CtorKind::Fn) => ExprKind::Literal {
literal: Literal::Value {
- value: cx.tcx.mk_const(ConstVal::Function(def_id, substs)),
+ value: cx.tcx.mk_const(ty::Const {
+ val: ConstVal::Function(def_id, substs),
+ ty: cx.tables().node_id_to_type(expr.hir_id)
+ }),
},
},
match ConstUsize::new(value, self.tcx.sess.target.uint_type) {
Ok(val) => {
Literal::Value {
- value: self.tcx.mk_const(ConstVal::Integral(ConstInt::Usize(val)))
+ value: self.tcx.mk_const(ty::Const {
+ val: ConstVal::Integral(ConstInt::Usize(val)),
+ ty: self.tcx.types.usize
+ })
}
}
Err(_) => bug!("usize literal out of range for target"),
}
pub fn true_literal(&mut self) -> Literal<'tcx> {
- Literal::Value { value: self.tcx.mk_const(ConstVal::Bool(true)) }
+ Literal::Value {
+ value: self.tcx.mk_const(ty::Const {
+ val: ConstVal::Bool(true),
+ ty: self.tcx.types.bool
+ })
+ }
}
pub fn false_literal(&mut self) -> Literal<'tcx> {
- Literal::Value { value: self.tcx.mk_const(ConstVal::Bool(false)) }
+ Literal::Value {
+ value: self.tcx.mk_const(ty::Const {
+ val: ConstVal::Bool(false),
+ ty: self.tcx.types.bool
+ })
+ }
}
pub fn const_eval_literal(&mut self, e: &hir::Expr) -> Literal<'tcx> {
let method_ty = method_ty.subst(self.tcx, substs);
return (method_ty,
Literal::Value {
- value: self.tcx.mk_const(ConstVal::Function(item.def_id, substs)),
+ value: self.tcx.mk_const(ty::Const {
+ val: ConstVal::Function(item.def_id, substs),
+ ty: method_ty
+ }),
});
}
}
);
// `func == Clone::clone(&ty) -> ty`
+ let func_ty = tcx.mk_fn_def(self.def_id, substs);
let func = Operand::Constant(box Constant {
span: self.span,
- ty: tcx.mk_fn_def(self.def_id, substs),
+ ty: func_ty,
literal: Literal::Value {
- value: tcx.mk_const(ConstVal::Function(self.def_id, substs)),
+ value: tcx.mk_const(ty::Const {
+ val: ConstVal::Function(self.def_id, substs),
+ ty: func_ty
+ }),
},
});
span: self.span,
ty: self.tcx.types.usize,
literal: Literal::Value {
- value: self.tcx.mk_const(ConstVal::Integral(ConstInt::Usize(value)))
+ value: self.tcx.mk_const(ty::Const {
+ val: ConstVal::Integral(ConstInt::Usize(value)),
+ ty: self.tcx.types.usize,
+ })
}
}
}
let (callee, mut args) = match call_kind {
CallKind::Indirect => (rcvr, vec![]),
- CallKind::Direct(def_id) => (
- Operand::Constant(box Constant {
+ CallKind::Direct(def_id) => {
+ let ty = tcx.type_of(def_id);
+ (Operand::Constant(box Constant {
span,
- ty: tcx.type_of(def_id),
+ ty,
literal: Literal::Value {
- value: tcx.mk_const(ConstVal::Function(def_id,
- Substs::identity_for_item(tcx, def_id))),
+ value: tcx.mk_const(ty::Const {
+ val: ConstVal::Function(def_id,
+ Substs::identity_for_item(tcx, def_id)),
+ ty
+ }),
},
- }),
- vec![rcvr]
- )
+ }),
+ vec![rcvr])
+ }
};
if let Some(untuple_args) = untuple_args {
span,
ty: self.tcx.types.bool,
literal: Literal::Value {
- value: self.tcx.mk_const(ConstVal::Bool(val))
+ value: self.tcx.mk_const(ty::Const {
+ val: ConstVal::Bool(val),
+ ty: self.tcx.types.bool
+ })
}
})))
}
//! "types-as-contracts"-validation, namely, AcquireValid, ReleaseValid, and EndRegion.
use rustc::ty::subst::Substs;
-use rustc::ty::{Ty, TyCtxt, ClosureSubsts};
+use rustc::ty::{self, Ty, TyCtxt};
use rustc::mir::*;
use rustc::mir::visit::{MutVisitor, Lookup};
use rustc::mir::transform::{MirPass, MirSource};
impl<'a, 'tcx> MutVisitor<'tcx> for EraseRegionsVisitor<'a, 'tcx> {
fn visit_ty(&mut self, ty: &mut Ty<'tcx>, _: Lookup) {
if !self.in_validation_statement {
- *ty = self.tcx.erase_regions(&{*ty});
+ *ty = self.tcx.erase_regions(ty);
}
self.super_ty(ty);
}
- fn visit_substs(&mut self, substs: &mut &'tcx Substs<'tcx>, _: Location) {
- *substs = self.tcx.erase_regions(&{*substs});
+ fn visit_region(&mut self, region: &mut ty::Region<'tcx>, _: Location) {
+ *region = self.tcx.types.re_erased;
}
- fn visit_rvalue(&mut self, rvalue: &mut Rvalue<'tcx>, location: Location) {
- match *rvalue {
- Rvalue::Ref(ref mut r, _, _) => {
- *r = self.tcx.types.re_erased;
- }
- Rvalue::Use(..) |
- Rvalue::Repeat(..) |
- Rvalue::Len(..) |
- Rvalue::Cast(..) |
- Rvalue::BinaryOp(..) |
- Rvalue::CheckedBinaryOp(..) |
- Rvalue::UnaryOp(..) |
- Rvalue::Discriminant(..) |
- Rvalue::NullaryOp(..) |
- Rvalue::Aggregate(..) => {
- // These variants don't contain regions.
- }
- }
- self.super_rvalue(rvalue, location);
+ fn visit_const(&mut self, constant: &mut &'tcx ty::Const<'tcx>, _: Location) {
+ *constant = self.tcx.erase_regions(constant);
+ }
+
+ fn visit_substs(&mut self, substs: &mut &'tcx Substs<'tcx>, _: Location) {
+ *substs = self.tcx.erase_regions(substs);
}
fn visit_closure_substs(&mut self,
- substs: &mut ClosureSubsts<'tcx>,
+ substs: &mut ty::ClosureSubsts<'tcx>,
_: Location) {
*substs = self.tcx.erase_regions(substs);
}
span: source_info.span,
ty: self.tcx.types.u32,
literal: Literal::Value {
- value: self.tcx.mk_const(ConstVal::Integral(ConstInt::U32(state_disc))),
+ value: self.tcx.mk_const(ty::Const {
+ val: ConstVal::Integral(ConstInt::U32(state_disc)),
+ ty: self.tcx.types.u32
+ }),
},
});
Statement {
span: mir.span,
ty: tcx.types.bool,
literal: Literal::Value {
- value: tcx.mk_const(ConstVal::Bool(false)),
+ value: tcx.mk_const(ty::Const {
+ val: ConstVal::Bool(false),
+ ty: tcx.types.bool
+ }),
},
}),
expected: true,
span: mir.span,
ty: tcx.types.bool,
literal: Literal::Value {
- value: tcx.mk_const(ConstVal::Bool(false)),
+ value: tcx.mk_const(ty::Const {
+ val: ConstVal::Bool(false),
+ ty: tcx.types.bool
+ }),
},
}),
expected: true,
//! A pass that simplifies branches when their condition is known.
-use rustc::ty::TyCtxt;
+use rustc::ty::{self, TyCtxt};
use rustc::middle::const_val::ConstVal;
use rustc::mir::transform::{MirPass, MirSource};
use rustc::mir::*;
TerminatorKind::SwitchInt { discr: Operand::Constant(box Constant {
literal: Literal::Value { ref value }, ..
}), ref values, ref targets, .. } => {
- if let Some(ref constint) = value.to_const_int() {
+ if let Some(ref constint) = value.val.to_const_int() {
let (otherwise, targets) = targets.split_last().unwrap();
let mut ret = TerminatorKind::Goto { target: *otherwise };
for (v, t) in values.iter().zip(targets.iter()) {
},
TerminatorKind::Assert { target, cond: Operand::Constant(box Constant {
literal: Literal::Value {
- value: &ConstVal::Bool(cond)
+ value: &ty::Const { val: ConstVal::Bool(cond), .. }
}, ..
}), expected, .. } if cond == expected => {
TerminatorKind::Goto { target: target }
match operand {
&Operand::Constant(box Constant {
literal: Literal::Value {
- value: &ConstVal::Function(def_id, _), ..
+ value: &ty::Const { val: ConstVal::Function(def_id, _), .. }, ..
}, ..
}) => {
Some(def_id) == self.tcx().lang_items().box_free_fn()
span: self.source_info.span,
ty: self.tcx().types.usize,
literal: Literal::Value {
- value: self.tcx().mk_const(ConstVal::Integral(self.tcx().const_usize(val)))
+ value: self.tcx().mk_const(ty::Const {
+ val: ConstVal::Integral(self.tcx().const_usize(val)),
+ ty: self.tcx().types.usize
+ })
}
})
}
// completely accurate (some things might be counted twice, others missed).
use rustc_const_math::{ConstUsize};
-use rustc::middle::const_val::{ConstVal};
use rustc::mir::{AggregateKind, AssertMessage, BasicBlock, BasicBlockData};
use rustc::mir::{Constant, Literal, Location, LocalDecl};
use rustc::mir::{Lvalue, LvalueElem, LvalueProjection};
use rustc::mir::{Rvalue, SourceInfo, Statement, StatementKind};
use rustc::mir::{Terminator, TerminatorKind, VisibilityScope, VisibilityScopeData};
use rustc::mir::visit as mir_visit;
-use rustc::ty::{ClosureSubsts, TyCtxt};
+use rustc::ty::{self, ClosureSubsts, TyCtxt};
use rustc::util::nodemap::{FxHashMap};
struct NodeData {
self.super_closure_substs(substs);
}
- fn visit_const_val(&mut self,
- const_val: &&'tcx ConstVal<'tcx>,
- _: Location) {
- self.record("ConstVal", const_val);
- self.super_const_val(const_val);
+ fn visit_const(&mut self,
+ constant: &&'tcx ty::Const<'tcx>,
+ _: Location) {
+ self.record("Const", constant);
+ self.super_const(constant);
}
fn visit_const_usize(&mut self,
use rustc::mir::{self, Location, TerminatorKind, Literal};
use rustc::mir::visit::{Visitor, LvalueContext};
use rustc::mir::traversal;
+use rustc::ty;
use common;
use super::MirContext;
mir::TerminatorKind::Call {
func: mir::Operand::Constant(box mir::Constant {
literal: Literal::Value {
- value: &ConstVal::Function(def_id, _), ..
+ value: &ty::Const { val: ConstVal::Function(def_id, _), .. }, ..
}, ..
}),
ref args, ..
MirConstContext::new(self.ccx, mir, self.substs, IndexVec::new()).trans()
}
mir::Literal::Value { value } => {
- Ok(Const::from_constval(self.ccx, value, ty))
+ Ok(Const::from_constval(self.ccx, &value.val, ty))
}
}
}
MirConstContext::new(bcx.ccx, mir, self.param_substs, IndexVec::new()).trans()
}
mir::Literal::Value { value } => {
- Ok(Const::from_constval(bcx.ccx, value, ty))
+ Ok(Const::from_constval(bcx.ccx, &value.val, ty))
}
};
}
match result {
- Ok(&ConstVal::Integral(x)) => Some(x),
+ Ok(&ty::Const { val: ConstVal::Integral(x), .. }) => Some(x),
_ => None
}
} else if let Some(discr) = repr_type.disr_incr(tcx, prev_discr) {