]> git.lizzy.rs Git - rust.git/commitdiff
rustc: introduce ty::Const { ConstVal, Ty }.
authorEduard-Mihai Burtescu <edy.burt@gmail.com>
Fri, 4 Aug 2017 08:25:13 +0000 (11:25 +0300)
committerEduard-Mihai Burtescu <edy.burt@gmail.com>
Mon, 11 Sep 2017 05:41:15 +0000 (08:41 +0300)
31 files changed:
src/librustc/ich/impls_ty.rs
src/librustc/middle/const_val.rs
src/librustc/mir/mod.rs
src/librustc/mir/visit.rs
src/librustc/ty/context.rs
src/librustc/ty/mod.rs
src/librustc/ty/structural_impls.rs
src/librustc/ty/sty.rs
src/librustc_const_eval/_match.rs
src/librustc_const_eval/eval.rs
src/librustc_const_eval/pattern.rs
src/librustc_lint/types.rs
src/librustc_metadata/decoder.rs
src/librustc_mir/build/expr/as_rvalue.rs
src/librustc_mir/build/matches/mod.rs
src/librustc_mir/build/matches/test.rs
src/librustc_mir/build/misc.rs
src/librustc_mir/build/mod.rs
src/librustc_mir/hair/cx/expr.rs
src/librustc_mir/hair/cx/mod.rs
src/librustc_mir/shim.rs
src/librustc_mir/transform/elaborate_drops.rs
src/librustc_mir/transform/erase_regions.rs
src/librustc_mir/transform/generator.rs
src/librustc_mir/transform/simplify_branches.rs
src/librustc_mir/transform/type_check.rs
src/librustc_mir/util/elaborate_drops.rs
src/librustc_passes/mir_stats.rs
src/librustc_trans/mir/analyze.rs
src/librustc_trans/mir/constant.rs
src/librustc_typeck/collect.rs

index 0d8aead0b36b8123d2721ff1e86b6379ab6cbd30..c9fb754287fda3cbc4cd97cad89580fa8fd081e2 100644 (file)
@@ -277,10 +277,10 @@ fn hash_stable<W: StableHasherResult>(&self,
         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) => {
@@ -325,6 +325,11 @@ fn hash_stable<W: StableHasherResult>(&self,
     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 });
index 8eac44966bb7ef7de7ede28b6c583daf77ff5635..01f050a1bd90a9c90d2ce4d4fd1ad2d0badc7edf 100644 (file)
 
 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),
@@ -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],
@@ -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> {
@@ -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)
index a7c4e529d24e1601ce7cae2ca0c8faa1c6a6603c..1985dcbd1f73de928f9dfa14042bc0a54fcf6bb0 100644 (file)
@@ -1187,11 +1187,15 @@ pub fn function_handle<'a>(
         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
+                })
             },
         })
     }
@@ -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`.
@@ -1501,9 +1505,9 @@ fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
             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)
index d2719224e378396f31833c89cd7775ccfa18eaa2..22d93c1a276508b79a0cb954e61aac944e47b398 100644 (file)
@@ -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};
@@ -214,6 +213,18 @@ fn visit_ty(&mut self,
                 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) {
@@ -232,12 +243,6 @@ fn visit_generator_interior(&mut self,
                 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) {
@@ -517,9 +522,10 @@ fn super_rvalue(&mut self,
                         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);
                     }
@@ -724,7 +730,7 @@ fn super_literal(&mut self,
                         self.visit_substs(substs, location);
                     }
                     Literal::Value { ref $($mutability)* value } => {
-                        self.visit_const_val(value, location);
+                        self.visit_const(value, location);
                     }
                     Literal::Promoted { index: _ } => {}
                 }
@@ -749,6 +755,12 @@ fn super_source_info(&mut self, source_info: & $($mutability)* SourceInfo) {
             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>) {
             }
 
@@ -760,9 +772,6 @@ fn super_closure_substs(&mut self,
                                     _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) {
             }
 
index 5d15e3a8cab72dfd9ccdfaf77ee02b6a61317b24..8dee2675ee5ccfca855cd3f3dae8489290f26711 100644 (file)
@@ -21,7 +21,6 @@
 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};
@@ -33,7 +32,7 @@
 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};
@@ -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> {
@@ -945,21 +944,21 @@ pub fn alloc_byte_array(self, bytes: &[u8]) -> &'gcx [u8] {
         }
     }
 
-    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)
         }
     }
 
@@ -1216,13 +1215,10 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Ty<'tcx>>
     }
 }
 
-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.
@@ -1234,9 +1230,9 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<&'tcx Sub
     }
 }
 
-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) });
         }
@@ -1249,6 +1245,24 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Region<'t
     }
 }
 
+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>)
@@ -1536,8 +1550,8 @@ fn borrow<'a>(&'a self) -> &'a [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
     }
 }
@@ -1623,7 +1637,7 @@ pub fn keep_local<'tcx, T: ty::TypeFoldable<'tcx>>(x: &T) -> bool {
             _ => 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 {
index 9be12195952f90ba3408af37b0908505de16c204..7c8aca9a9b157276b42c5b2ba0dfdf58821b3595 100644 (file)
@@ -64,7 +64,7 @@
 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};
@@ -1601,7 +1601,7 @@ pub fn discriminants(&'a self, tcx: TyCtxt<'a, 'gcx, 'tcx>)
             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 => {
@@ -1641,7 +1641,7 @@ pub fn discriminant_for_variant(&self,
                 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;
                         }
index 44b505e19658f5cf45ecec30a8e51af71cc3707d..f260e20a3cd6cec1aedc8c4011834eb8701c179c 100644 (file)
@@ -9,6 +9,7 @@
 // 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;
@@ -1101,3 +1102,95 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
         }
     }
 }
+
+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)
+    }
+}
index 14ea66a1b67faadd1a9e961654c3fd359e1f9aed..f082e32ff6867e9235ad3f470d47ee46af388b5f 100644 (file)
@@ -12,6 +12,7 @@
 
 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};
@@ -1458,3 +1459,14 @@ pub fn regions(&self) -> Vec<ty::Region<'tcx>> {
         }
     }
 }
+
+/// 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> {}
index aea1f454d814183e4d97a8199eab7eb8d1740345..b1e3dcf53f0d80242c57ec5d6f25054b90d21c56 100644 (file)
@@ -182,13 +182,16 @@ fn lower_byte_str_pattern<'p>(&mut self, pat: &'p Pattern<'tcx>) -> Vec<&'p Patt
         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()
                 }
@@ -228,9 +231,9 @@ pub enum Constructor<'tcx> {
     /// 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),
 }
@@ -406,7 +409,10 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
     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) => {
@@ -514,7 +520,7 @@ fn max_slice_length<'p, 'a: 'p, 'tcx: 'a, I>(
 
     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 } => {
@@ -809,7 +815,7 @@ fn slice_pat_covered_by_constructor(_tcx: TyCtxt, _span: Span,
                                     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!()
     };
 
@@ -823,7 +829,7 @@ fn slice_pat_covered_by_constructor(_tcx: TyCtxt, _span: Span,
             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);
@@ -847,22 +853,22 @@ fn constructor_covered_by_range(tcx: TyCtxt, span: Span,
     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!(),
@@ -924,7 +930,7 @@ fn specialize<'p, 'a: 'p, 'tcx: 'a>(
 
         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))
@@ -937,7 +943,7 @@ fn specialize<'p, 'a: 'p, 'tcx: 'a>(
                 },
                 _ => {
                     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,
@@ -947,9 +953,9 @@ fn specialize<'p, 'a: 'p, 'tcx: 'a>(
             }
         }
 
-        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,
index 5f0a070229177dc086cbd156f4bb6bf8cf9136ba..2aa333c1f039c12b7ab63d1b3cb01236bd9acfde 100644 (file)
@@ -89,7 +89,7 @@ pub struct ConstContext<'a, 'tcx: 'a> {
     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> {
@@ -121,7 +121,8 @@ pub fn eval(&self, e: &'tcx Expr) -> EvalResult<'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) => {
@@ -134,7 +135,7 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
             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()))
@@ -179,17 +180,17 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
                 _ => 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)),
@@ -201,7 +202,7 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
         // 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 {
@@ -275,11 +276,11 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
       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),
             }
         }
@@ -301,13 +302,13 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
                     }
               },
               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"))
@@ -320,13 +321,13 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
                       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),
           };
@@ -340,12 +341,12 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
             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)
@@ -394,23 +395,23 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
           };
           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<_>, _>>()?))))
       }
@@ -419,12 +420,12 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
             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
@@ -444,7 +445,7 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
                 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),
@@ -452,24 +453,24 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
       }
       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 {
@@ -756,7 +757,7 @@ pub fn compare_lit_exprs(&self,
                 return Err(ErrorReported);
             }
         };
-        compare_const_vals(tcx, span, &a, &b)
+        compare_const_vals(tcx, span, &a.val, &b.val)
     }
 }
 
index e824c4789c7c64d681c3f16b66e17444b6166d5b..cf42d61e136ad900f7e9c840342b33fb513bafa1 100644 (file)
@@ -83,12 +83,12 @@ pub enum PatternKind<'tcx> {
     },
 
     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,
     },
 
@@ -228,15 +228,15 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                 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 } => {
@@ -634,7 +634,7 @@ fn lower_lit(&mut self, expr: &'tcx hir::Expr) -> PatternKind<'tcx> {
                                                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 {
@@ -816,7 +816,7 @@ fn super_fold_with<F: PatternFolder<$lt_tcx>>(&self, _: &mut F) -> Self {
 }
 
 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>
 }
index 46a33ce807d7d7ddbc66a0abe80e2062c5bd0b3f..e6af47952b37196dd4c6bed72695007579ad6a1a 100644 (file)
@@ -117,7 +117,7 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx hir::Expr) {
                                                              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)
index b475b02ccfeaa9cef80f562395fe1e2aa8c356de..689f9f5b244304b6a133a9055613747906dcbd64 100644 (file)
@@ -16,7 +16,7 @@
 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};
@@ -386,8 +386,8 @@ fn specialized_decode(&mut self) -> Result<ByteArray<'tcx>, Self::Error> {
     }
 }
 
-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)?))
     }
 }
index c5f83b029ce00724b02cf20170abb2600fe7f03c..2bda4524d23af7a69b4fc4c2f581a674e3263c91 100644 (file)
@@ -197,7 +197,10 @@ fn expr_as_rvalue(&mut 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)
@@ -392,7 +395,10 @@ fn neg_1_literal(&mut self, span: Span, ty: ty::Ty<'tcx>) -> Operand<'tcx> {
                 };
 
                 Literal::Value {
-                    value: self.hir.tcx().mk_const(ConstVal::Integral(val))
+                    value: self.hir.tcx().mk_const(ty::Const {
+                        val: ConstVal::Integral(val),
+                        ty
+                    })
                 }
             }
             _ => {
@@ -427,7 +433,10 @@ fn minval_literal(&mut self, span: Span, ty: ty::Ty<'tcx>) -> Operand<'tcx> {
                 };
 
                 Literal::Value {
-                    value: self.hir.tcx().mk_const(ConstVal::Integral(val))
+                    value: self.hir.tcx().mk_const(ty::Const {
+                        val: ConstVal::Integral(val),
+                        ty
+                    })
                 }
             }
             _ => {
index 2d029f1a5b7f74f7e4f2a49466252b1ba930ac66..f560fa426e22e2e380ff80ed0fd5ad2ddfba10d9 100644 (file)
@@ -16,8 +16,7 @@
 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::*;
@@ -294,20 +293,20 @@ pub struct MatchPair<'pat, 'tcx:'pat> {
 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>,
     },
 
index 5553e2f4c9ca17e1322c3b4e63e8812da07150e9..965a443d9ac1bf55b2de7b7668e204803c954e12 100644 (file)
@@ -112,8 +112,8 @@ pub fn add_cases_to_switch<'pat>(&mut self,
                                      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) {
@@ -228,7 +228,7 @@ pub fn perform_test(&mut self,
                     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)
@@ -245,7 +245,7 @@ pub fn perform_test(&mut self,
                                .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()),
@@ -263,7 +263,7 @@ pub fn perform_test(&mut self,
 
                 // 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.
index 12b9174f3a3a6883312e57b8d2b29ff874216d2a..bf9ad78481164ebbbc4c8613d343ad7b472f9f3d 100644 (file)
@@ -61,7 +61,10 @@ pub fn zero_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> {
             }
             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) => {
@@ -79,7 +82,10 @@ pub fn zero_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> {
                 };
 
                 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) => {
@@ -97,7 +103,10 @@ pub fn zero_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> {
                 };
 
                 Literal::Value {
-                    value: self.hir.tcx().mk_const(ConstVal::Integral(val))
+                    value: self.hir.tcx().mk_const(ty::Const {
+                        val: ConstVal::Integral(val),
+                        ty
+                    })
                 }
             }
             _ => {
index 704d138b43b58824d53fbcd7c924f0f05688e008..be6f8c9e56c40b7a67db94bdf3a8b008440ef240 100644 (file)
@@ -166,6 +166,26 @@ fn visit_ty(&mut self, ty: &mut Ty<'tcx>, _: Lookup) {
         }
     }
 
+    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;
index 0e4d2b9a5aefe4e408a1020fd1f76c96cedd98dd..23e6fbd2b7e23a0fc38eea52b0e2632e43b83022 100644 (file)
@@ -473,7 +473,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
             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")
             };
@@ -591,13 +591,17 @@ fn method_callee<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
         (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
+                }),
             },
         },
     }
@@ -630,7 +634,10 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
         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)
+                }),
             },
         },
 
index 9244ea14514fc93dc76fb7dfc739c745c9e64bc8..85607c04c98c807bc2107a22d077dd81d0602c8c 100644 (file)
@@ -115,7 +115,10 @@ pub fn usize_literal(&mut self, value: u64) -> Literal<'tcx> {
         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"),
@@ -131,11 +134,21 @@ pub fn unit_ty(&mut self) -> Ty<'tcx> {
     }
 
     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> {
@@ -186,7 +199,10 @@ pub fn trait_method(&mut self,
                 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
+                            }),
                         });
             }
         }
index d0a78b57217089f7fb7af83360e8fc51928bcf30..cc0ea5911a070c3517ec49e271d761794e85c078 100644 (file)
@@ -403,11 +403,15 @@ fn make_clone_call(
         );
 
         // `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
+                }),
             },
         });
 
@@ -472,7 +476,10 @@ fn make_usize(&self, value: usize) -> Box<Constant<'tcx>> {
             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,
+                })
             }
         }
     }
@@ -706,17 +713,21 @@ fn build_call_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
 
     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 {
index 971df70a74e256574928f27f9087127c81b20e6c..1077f3b0146168ccd48e1a0e166324306a8bbcdc 100644 (file)
@@ -521,7 +521,10 @@ fn constant_bool(&self, span: Span, val: bool) -> Rvalue<'tcx> {
             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
+                })
             }
         })))
     }
index fa51cd91be1b673b641b14ae2100374b9ac3417b..dc18cdd8f0dd6006e2270974f8cae06240319d0e 100644 (file)
@@ -15,7 +15,7 @@
 //! "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};
@@ -37,38 +37,25 @@ pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self {
 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);
     }
index 74edf510aa2e7ecb1dd9b6a9d1fb88fc9ec2616a..a52656becd74534190b114501df7e4bff8d6be39 100644 (file)
@@ -175,7 +175,10 @@ fn set_state(&self, state_disc: u32, source_info: SourceInfo) -> Statement<'tcx>
             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 {
@@ -553,7 +556,10 @@ fn insert_panic_on_resume_after_return<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             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,
@@ -603,7 +609,10 @@ fn create_generator_resume_function<'a, 'tcx>(
             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,
index 6c0a44b7631707ada7d607166858f53532ae68f3..0dff145ecbce94c547568b7651b91529fcf4079f 100644 (file)
@@ -10,7 +10,7 @@
 
 //! 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::*;
@@ -40,7 +40,7 @@ fn run_pass<'a, 'tcx>(&self,
                 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()) {
@@ -56,7 +56,7 @@ fn run_pass<'a, 'tcx>(&self,
                 },
                 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 }
index eaafdb0ac41783e29a39247ecb4f0afbc91bf440..3c77668e729c6f843e25742d4df0034bed246e90 100644 (file)
@@ -572,7 +572,7 @@ fn is_box_free(&self, operand: &Operand<'tcx>) -> bool {
         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()
index d770dbe6f4f47903fddd4168e51da6ce0799ee61..4a11ac11680906c076346e0728e1e5ee06e1b819 100644 (file)
@@ -923,7 +923,10 @@ fn constant_usize(&self, val: u16) -> Operand<'tcx> {
             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
+                })
             }
         })
     }
index 67176276f96fb1beac3256f93616d94e71920fad..91203a91be51d3e3637e5a4d0542a26948e8d690 100644 (file)
@@ -13,7 +13,6 @@
 // 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};
@@ -21,7 +20,7 @@
 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 {
@@ -256,11 +255,11 @@ fn visit_closure_substs(&mut self,
         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,
index a843b4171bd80f25b992fa1e6a5dcc69461a0995..1017ec6b3c3f85608e33a553e916e39d4fe25988 100644 (file)
@@ -17,6 +17,7 @@
 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;
 
@@ -110,7 +111,7 @@ fn visit_terminator_kind(&mut self,
             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, ..
index d43911df83a2b74399663e6109b610387bd52e71..21c935ae6381758fc4e0329bcdf959c629ceb685 100644 (file)
@@ -522,7 +522,7 @@ fn const_operand(&self, operand: &mir::Operand<'tcx>, span: Span)
                         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))
                     }
                 }
             }
@@ -971,7 +971,7 @@ pub fn trans_constant(&mut self,
                 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))
             }
         };
 
index 8c3cf481e5eeeb4977fdc0791457ee260e133fa4..1735ec7cc698c29788d0cdc51a0aa3de97536420 100644 (file)
@@ -572,7 +572,7 @@ fn convert_enum_variant_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             }
 
             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) {