diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 0d8aead0b36b..c9fb754287fd 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -277,10 +277,10 @@ for ::middle::const_val::ConstVal<'gcx> { mem::discriminant(self).hash_stable(hcx, hasher); match *self { - Float(ref value) => { + Integral(ref value) => { value.hash_stable(hcx, hasher); } - Integral(ref value) => { + Float(ref value) => { value.hash_stable(hcx, hasher); } Str(ref value) => { @@ -325,6 +325,11 @@ impl_stable_hash_for!(struct ::middle::const_val::ByteArray<'tcx> { data }); +impl_stable_hash_for!(struct ty::Const<'tcx> { + ty, + val +}); + impl_stable_hash_for!(struct ty::ClosureSubsts<'tcx> { substs }); impl_stable_hash_for!(struct ty::GeneratorInterior<'tcx> { witness }); diff --git a/src/librustc/middle/const_val.rs b/src/librustc/middle/const_val.rs index 8eac44966bb7..01f050a1bd90 100644 --- a/src/librustc/middle/const_val.rs +++ b/src/librustc/middle/const_val.rs @@ -30,12 +30,12 @@ use syntax_pos::Span; use std::borrow::Cow; -pub type EvalResult<'tcx> = Result<&'tcx ConstVal<'tcx>, ConstEvalErr<'tcx>>; +pub type EvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ConstEvalErr<'tcx>>; #[derive(Copy, Clone, Debug, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq)] pub enum ConstVal<'tcx> { - Float(ConstFloat), Integral(ConstInt), + Float(ConstFloat), Str(InternedString), ByteStr(ByteArray<'tcx>), Bool(bool), @@ -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) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index a7c4e529d24e..1985dcbd1f73 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1187,11 +1187,15 @@ impl<'tcx> Operand<'tcx> { substs: &'tcx Substs<'tcx>, span: Span, ) -> Self { + let ty = tcx.type_of(def_id).subst(tcx, substs); Operand::Constant(box Constant { span, - ty: tcx.type_of(def_id).subst(tcx, substs), + ty, literal: Literal::Value { - value: tcx.mk_const(ConstVal::Function(def_id, substs)) + value: tcx.mk_const(ty::Const { + val: ConstVal::Function(def_id, substs), + ty + }) }, }) } @@ -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 @@ impl<'tcx> Debug for Literal<'tcx> { Item { def_id, substs } => { ppaux::parameterized(fmt, substs, def_id, &[]) } - Value { ref value } => { + Value { value } => { write!(fmt, "const ")?; - fmt_const_val(fmt, value) + fmt_const_val(fmt, &value.val) } Promoted { index } => { write!(fmt, "{:?}", index) diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index d2719224e378..22d93c1a2765 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -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 @@ macro_rules! make_mir_visitor { self.super_ty(ty); } + fn visit_region(&mut self, + region: & $($mutability)* ty::Region<'tcx>, + _: Location) { + self.super_region(region); + } + + fn visit_const(&mut self, + constant: & $($mutability)* &'tcx ty::Const<'tcx>, + _: Location) { + self.super_const(constant); + } + fn visit_substs(&mut self, substs: & $($mutability)* &'tcx Substs<'tcx>, _: Location) { @@ -232,12 +243,6 @@ macro_rules! make_mir_visitor { self.super_generator_interior(interior); } - fn visit_const_val(&mut self, - const_val: & $($mutability)* &'tcx ConstVal<'tcx>, - _: Location) { - self.super_const_val(const_val); - } - fn visit_const_int(&mut self, const_int: &ConstInt, _: Location) { @@ -517,9 +522,10 @@ macro_rules! make_mir_visitor { self.visit_const_usize(length, location); } - Rvalue::Ref(r, bk, ref $($mutability)* path) => { + Rvalue::Ref(ref $($mutability)* r, bk, ref $($mutability)* path) => { + self.visit_region(r, location); self.visit_lvalue(path, LvalueContext::Borrow { - region: r, + region: *r, kind: bk }, location); } @@ -724,7 +730,7 @@ macro_rules! make_mir_visitor { self.visit_substs(substs, location); } Literal::Value { ref $($mutability)* value } => { - self.visit_const_val(value, location); + self.visit_const(value, location); } Literal::Promoted { index: _ } => {} } @@ -749,6 +755,12 @@ macro_rules! make_mir_visitor { fn super_ty(&mut self, _ty: & $($mutability)* Ty<'tcx>) { } + fn super_region(&mut self, _region: & $($mutability)* ty::Region<'tcx>) { + } + + fn super_const(&mut self, _const: & $($mutability)* &'tcx ty::Const<'tcx>) { + } + fn super_substs(&mut self, _substs: & $($mutability)* &'tcx Substs<'tcx>) { } @@ -760,9 +772,6 @@ macro_rules! make_mir_visitor { _substs: & $($mutability)* ClosureSubsts<'tcx>) { } - fn super_const_val(&mut self, _const_val: & $($mutability)* &'tcx ConstVal<'tcx>) { - } - fn super_const_int(&mut self, _const_int: &ConstInt) { } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 5d15e3a8cab7..8dee2675ee5c 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -21,7 +21,6 @@ use hir::map as hir_map; use hir::map::DefPathHash; use lint::{self, Lint}; use ich::{self, StableHashingContext, NodeIdHashingMode}; -use middle::const_val::ConstVal; use middle::free_region::FreeRegionMap; use middle::lang_items; use middle::resolve_lifetime::{self, ObjectLifetimeDefault}; @@ -33,7 +32,7 @@ use ty::ReprOptions; use traits; use ty::{self, Ty, TypeAndMut}; use ty::{TyS, TypeVariants, Slice}; -use ty::{AdtKind, AdtDef, ClosureSubsts, GeneratorInterior, Region}; +use ty::{AdtKind, AdtDef, ClosureSubsts, GeneratorInterior, Region, Const}; use ty::{PolyFnSig, InferTy, ParamTy, ProjectionTy, ExistentialPredicate, Predicate}; use ty::RegionKind; use ty::{TyVar, TyVid, IntVar, IntVid, FloatVar, FloatVid}; @@ -109,7 +108,7 @@ pub struct CtxtInterners<'tcx> { region: RefCell>>, existential_predicates: RefCell>>>>, predicates: RefCell>>>>, - const_: RefCell>>>, + const_: RefCell>>>, } impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> { @@ -945,21 +944,21 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } - pub fn alloc_constval_slice(self, values: &[&'tcx ConstVal<'gcx>]) - -> &'gcx [&'tcx ConstVal<'gcx>] { + pub fn alloc_const_slice(self, values: &[&'tcx ty::Const<'tcx>]) + -> &'tcx [&'tcx ty::Const<'tcx>] { if values.is_empty() { &[] } else { - self.global_interners.arena.alloc_slice(values) + self.interners.arena.alloc_slice(values) } } - pub fn alloc_name_constval_slice(self, values: &[(ast::Name, &'tcx ConstVal<'gcx>)]) - -> &'gcx [(ast::Name, &'tcx ConstVal<'gcx>)] { + pub fn alloc_name_const_slice(self, values: &[(ast::Name, &'tcx ty::Const<'tcx>)]) + -> &'tcx [(ast::Name, &'tcx ty::Const<'tcx>)] { if values.is_empty() { &[] } else { - self.global_interners.arena.alloc_slice(values) + self.interners.arena.alloc_slice(values) } } @@ -1216,13 +1215,10 @@ impl<'a, 'tcx> Lift<'tcx> for Ty<'a> { } } -impl<'a, 'tcx> Lift<'tcx> for &'a Substs<'a> { - type Lifted = &'tcx Substs<'tcx>; - fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<&'tcx Substs<'tcx>> { - if self.len() == 0 { - return Some(Slice::empty()); - } - if tcx.interners.arena.in_arena(&self[..] as *const _) { +impl<'a, 'tcx> Lift<'tcx> for Region<'a> { + type Lifted = Region<'tcx>; + fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option> { + 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 @@ impl<'a, 'tcx> Lift<'tcx> for &'a Substs<'a> { } } -impl<'a, 'tcx> Lift<'tcx> for Region<'a> { - type Lifted = Region<'tcx>; - fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option> { +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 @@ impl<'a, 'tcx> Lift<'tcx> for Region<'a> { } } +impl<'a, 'tcx> Lift<'tcx> for &'a Substs<'a> { + type Lifted = &'tcx Substs<'tcx>; + fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<&'tcx Substs<'tcx>> { + if self.len() == 0 { + return Some(Slice::empty()); + } + if tcx.interners.arena.in_arena(&self[..] as *const _) { + return Some(unsafe { mem::transmute(*self) }); + } + // Also try in the global tcx if we're not that. + if !tcx.is_global() { + self.lift_to_tcx(tcx.global_tcx()) + } else { + None + } + } +} + impl<'a, 'tcx> Lift<'tcx> for &'a Slice> { type Lifted = &'tcx Slice>; fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) @@ -1536,8 +1550,8 @@ impl<'tcx: 'lcx, 'lcx> Borrow<[Predicate<'lcx>]> } } -impl<'tcx: 'lcx, 'lcx> Borrow> for Interned<'tcx, ConstVal<'tcx>> { - fn borrow<'a>(&'a self) -> &'a ConstVal<'lcx> { +impl<'tcx: 'lcx, 'lcx> Borrow> for Interned<'tcx, Const<'tcx>> { + fn borrow<'a>(&'a self) -> &'a Const<'lcx> { &self.0 } } @@ -1623,7 +1637,7 @@ direct_interners!('tcx, _ => false } }) -> RegionKind, - const_: mk_const(/*|c: &Const| keep_local(&c.ty)*/ |_| false) -> ConstVal<'tcx> + const_: mk_const(|c: &Const| keep_local(&c.ty) || keep_local(&c.val)) -> Const<'tcx> ); macro_rules! slice_interners { diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 9be12195952f..7c8aca9a9b15 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -64,7 +64,7 @@ pub use self::sty::{InferTy, ParamTy, ProjectionTy, ExistentialPredicate}; pub use self::sty::{ClosureSubsts, GeneratorInterior, TypeAndMut}; pub use self::sty::{TraitRef, TypeVariants, PolyTraitRef}; pub use self::sty::{ExistentialTraitRef, PolyExistentialTraitRef}; -pub use self::sty::{ExistentialProjection, PolyExistentialProjection}; +pub use self::sty::{ExistentialProjection, PolyExistentialProjection, Const}; pub use self::sty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region}; pub use self::sty::RegionKind; pub use self::sty::{TyVid, IntVid, FloatVid, RegionVid, SkolemizedRegionVid}; @@ -1601,7 +1601,7 @@ impl<'a, 'gcx, 'tcx> AdtDef { if let VariantDiscr::Explicit(expr_did) = v.discr { let substs = Substs::identity_for_item(tcx.global_tcx(), expr_did); match tcx.const_eval(param_env.and((expr_did, substs))) { - Ok(&ConstVal::Integral(v)) => { + Ok(&ty::Const { val: ConstVal::Integral(v), .. }) => { discr = v; } err => { @@ -1641,7 +1641,7 @@ impl<'a, 'gcx, 'tcx> AdtDef { ty::VariantDiscr::Explicit(expr_did) => { let substs = Substs::identity_for_item(tcx.global_tcx(), expr_did); match tcx.const_eval(param_env.and((expr_did, substs))) { - Ok(&ConstVal::Integral(v)) => { + Ok(&ty::Const { val: ConstVal::Integral(v), .. }) => { explicit_value = v; break; } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 44b505e19658..f260e20a3cd6 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -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 @@ impl<'tcx> TypeFoldable<'tcx> for ty::error::TypeError<'tcx> { } } } + +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>(&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>(&self, visitor: &mut V) -> bool { + self.ty.visit_with(visitor) || self.val.visit_with(visitor) + } +} diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 14ea66a1b67f..f082e32ff686 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -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 @@ impl<'a, 'gcx, 'tcx> TyS<'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> {} diff --git a/src/librustc_const_eval/_match.rs b/src/librustc_const_eval/_match.rs index aea1f454d814..b1e3dcf53f0d 100644 --- a/src/librustc_const_eval/_match.rs +++ b/src/librustc_const_eval/_match.rs @@ -182,13 +182,16 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, '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() } @@ -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 { 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, diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index 5f0a07022917..2aa333c1f039 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -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>> + fn_args: Option>> } impl<'a, 'tcx> ConstContext<'a, 'tcx> { @@ -121,7 +121,8 @@ type CastResult<'tcx> = Result, ErrKind<'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::, _>>()?; - 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::, _>>()?)))) } @@ -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::, _>>()?; - 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 @@ impl<'a, 'tcx> ConstContext<'a, 'tcx> { return Err(ErrorReported); } }; - compare_const_vals(tcx, span, &a, &b) + compare_const_vals(tcx, span, &a.val, &b.val) } } diff --git a/src/librustc_const_eval/pattern.rs b/src/librustc_const_eval/pattern.rs index e824c4789c7c..cf42d61e136a 100644 --- a/src/librustc_const_eval/pattern.rs +++ b/src/librustc_const_eval/pattern.rs @@ -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 @@ impl<'tcx> fmt::Display for Pattern<'tcx> { 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 @@ impl<'a, 'tcx> PatternContext<'a, '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 @@ macro_rules! CloneImpls { } 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> } diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 46a33ce807d7..e6af47952b37 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -117,7 +117,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { 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) diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index b475b02ccfea..689f9f5b2443 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -16,7 +16,7 @@ use schema::*; 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 @@ impl<'a, 'tcx> SpecializedDecoder> for DecodeContext<'a, 'tcx> { } } -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)?)) } } diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index c5f83b029ce0..2bda4524d23a 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -197,7 +197,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, '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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, '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 + }) } } _ => { diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index 2d029f1a5b7f..f560fa426e22 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -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>, }, diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs index 5553e2f4c9ca..965a443d9ac1 100644 --- a/src/librustc_mir/build/matches/test.rs +++ b/src/librustc_mir/build/matches/test.rs @@ -112,8 +112,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, '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) { @@ -228,7 +228,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { .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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // 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. diff --git a/src/librustc_mir/build/misc.rs b/src/librustc_mir/build/misc.rs index 12b9174f3a3a..bf9ad7848116 100644 --- a/src/librustc_mir/build/misc.rs +++ b/src/librustc_mir/build/misc.rs @@ -61,7 +61,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, '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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, '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 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, '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 + }) } } _ => { diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 704d138b43b5..be6f8c9e56c4 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -166,6 +166,26 @@ impl<'a, 'gcx: 'tcx, 'tcx> MutVisitor<'tcx> for GlobalizeMir<'a, 'gcx> { } } + 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; diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 0e4d2b9a5aef..23e6fbd2b7e2 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -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) + }), }, }, diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index 9244ea14514f..85607c04c98c 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -115,7 +115,10 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, '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 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, '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 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, '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 + }), }); } } diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index d0a78b572170..cc0ea5911a07 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -403,11 +403,15 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { ); // `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 @@ impl<'a, 'tcx> CloneShimBuilder<'a, '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 { diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs index 971df70a74e2..1077f3b01461 100644 --- a/src/librustc_mir/transform/elaborate_drops.rs +++ b/src/librustc_mir/transform/elaborate_drops.rs @@ -521,7 +521,10 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, '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 + }) } }))) } diff --git a/src/librustc_mir/transform/erase_regions.rs b/src/librustc_mir/transform/erase_regions.rs index fa51cd91be1b..dc18cdd8f0dd 100644 --- a/src/librustc_mir/transform/erase_regions.rs +++ b/src/librustc_mir/transform/erase_regions.rs @@ -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 @@ impl<'a, 'tcx> EraseRegionsVisitor<'a, 'tcx> { 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); } diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 74edf510aa2e..a52656becd74 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -175,7 +175,10 @@ impl<'a, 'tcx> TransformVisitor<'a, '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, diff --git a/src/librustc_mir/transform/simplify_branches.rs b/src/librustc_mir/transform/simplify_branches.rs index 6c0a44b76317..0dff145ecbce 100644 --- a/src/librustc_mir/transform/simplify_branches.rs +++ b/src/librustc_mir/transform/simplify_branches.rs @@ -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 @@ impl MirPass for SimplifyBranches { 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 @@ impl MirPass for SimplifyBranches { }, 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 } diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs index eaafdb0ac417..3c77668e729c 100644 --- a/src/librustc_mir/transform/type_check.rs +++ b/src/librustc_mir/transform/type_check.rs @@ -572,7 +572,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { 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() diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index d770dbe6f4f4..4a11ac116809 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -923,7 +923,10 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> 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 + }) } }) } diff --git a/src/librustc_passes/mir_stats.rs b/src/librustc_passes/mir_stats.rs index 67176276f96f..91203a91be51 100644 --- a/src/librustc_passes/mir_stats.rs +++ b/src/librustc_passes/mir_stats.rs @@ -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::{Mir, Operand, ProjectionElem}; 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 @@ impl<'a, 'tcx> mir_visit::Visitor<'tcx> for StatCollector<'a, 'tcx> { 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, diff --git a/src/librustc_trans/mir/analyze.rs b/src/librustc_trans/mir/analyze.rs index a843b4171bd8..1017ec6b3c3f 100644 --- a/src/librustc_trans/mir/analyze.rs +++ b/src/librustc_trans/mir/analyze.rs @@ -17,6 +17,7 @@ use rustc::middle::const_val::ConstVal; 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 @@ impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> { 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, .. diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs index d43911df83a2..21c935ae6381 100644 --- a/src/librustc_trans/mir/constant.rs +++ b/src/librustc_trans/mir/constant.rs @@ -522,7 +522,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { 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 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { 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)) } }; diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 8c3cf481e5ee..1735ec7cc698 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -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) {