From 50076b00c2790a7941772cc97ee371e15b2cb776 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 4 Aug 2017 00:41:44 +0300 Subject: rustc: intern ConstVal's in TyCtxt. --- src/librustc_mir/transform/elaborate_drops.rs | 4 +++- src/librustc_mir/transform/generator.rs | 6 +++--- src/librustc_mir/transform/simplify_branches.rs | 2 +- src/librustc_mir/transform/type_check.rs | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) (limited to 'src/librustc_mir/transform') diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs index d6477f2babf..971df70a74e 100644 --- a/src/librustc_mir/transform/elaborate_drops.rs +++ b/src/librustc_mir/transform/elaborate_drops.rs @@ -520,7 +520,9 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { Rvalue::Use(Operand::Constant(Box::new(Constant { span, ty: self.tcx.types.bool, - literal: Literal::Value { value: ConstVal::Bool(val) } + literal: Literal::Value { + value: self.tcx.mk_const(ConstVal::Bool(val)) + } }))) } diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 0fb34c96b06..74edf510aa2 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -175,7 +175,7 @@ impl<'a, 'tcx> TransformVisitor<'a, 'tcx> { span: source_info.span, ty: self.tcx.types.u32, literal: Literal::Value { - value: ConstVal::Integral(ConstInt::U32(state_disc)), + value: self.tcx.mk_const(ConstVal::Integral(ConstInt::U32(state_disc))), }, }); Statement { @@ -553,7 +553,7 @@ 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: ConstVal::Bool(false), + value: tcx.mk_const(ConstVal::Bool(false)), }, }), expected: true, @@ -603,7 +603,7 @@ fn create_generator_resume_function<'a, 'tcx>( span: mir.span, ty: tcx.types.bool, literal: Literal::Value { - value: ConstVal::Bool(false), + value: tcx.mk_const(ConstVal::Bool(false)), }, }), expected: true, diff --git a/src/librustc_mir/transform/simplify_branches.rs b/src/librustc_mir/transform/simplify_branches.rs index 1dcacb29c3e..6c0a44b7631 100644 --- a/src/librustc_mir/transform/simplify_branches.rs +++ b/src/librustc_mir/transform/simplify_branches.rs @@ -56,7 +56,7 @@ impl MirPass for SimplifyBranches { }, TerminatorKind::Assert { target, cond: Operand::Constant(box Constant { literal: Literal::Value { - value: ConstVal::Bool(cond) + value: &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 7fbeb9610f4..eaafdb0ac41 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: &ConstVal::Function(def_id, _), .. }, .. }) => { Some(def_id) == self.tcx().lang_items().box_free_fn() -- cgit 1.4.1-3-g733a5 From 932289c12d26803daf6b1990cb56bb974979bf9c Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 4 Aug 2017 11:25:13 +0300 Subject: rustc: introduce ty::Const { ConstVal, Ty }. --- src/librustc/ich/impls_ty.rs | 9 ++- src/librustc/middle/const_val.rs | 16 ++--- src/librustc/mir/mod.rs | 14 ++-- src/librustc/mir/visit.rs | 35 ++++++---- src/librustc/ty/context.rs | 58 +++++++++------ src/librustc/ty/mod.rs | 6 +- src/librustc/ty/structural_impls.rs | 93 +++++++++++++++++++++++++ src/librustc/ty/sty.rs | 12 ++++ src/librustc_const_eval/_match.rs | 42 ++++++----- src/librustc_const_eval/eval.rs | 61 ++++++++-------- src/librustc_const_eval/pattern.rs | 16 ++--- src/librustc_lint/types.rs | 2 +- src/librustc_metadata/decoder.rs | 6 +- src/librustc_mir/build/expr/as_rvalue.rs | 15 +++- src/librustc_mir/build/matches/mod.rs | 11 ++- src/librustc_mir/build/matches/test.rs | 10 +-- src/librustc_mir/build/misc.rs | 15 +++- src/librustc_mir/build/mod.rs | 20 ++++++ src/librustc_mir/hair/cx/expr.rs | 15 ++-- src/librustc_mir/hair/cx/mod.rs | 24 +++++-- src/librustc_mir/shim.rs | 33 ++++++--- src/librustc_mir/transform/elaborate_drops.rs | 5 +- src/librustc_mir/transform/erase_regions.rs | 35 +++------- src/librustc_mir/transform/generator.rs | 15 +++- src/librustc_mir/transform/simplify_branches.rs | 6 +- src/librustc_mir/transform/type_check.rs | 2 +- src/librustc_mir/util/elaborate_drops.rs | 5 +- src/librustc_passes/mir_stats.rs | 13 ++-- src/librustc_trans/mir/analyze.rs | 3 +- src/librustc_trans/mir/constant.rs | 4 +- src/librustc_typeck/collect.rs | 2 +- 31 files changed, 409 insertions(+), 194 deletions(-) (limited to 'src/librustc_mir/transform') diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 0d8aead0b36..c9fb754287f 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 8eac44966bb..01f050a1bd9 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 a7c4e529d24..1985dcbd1f7 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 d2719224e37..22d93c1a276 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 5d15e3a8cab..8dee2675ee5 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 9be12195952..7c8aca9a9b1 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 44b505e1965..f260e20a3cd 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 14ea66a1b67..f082e32ff68 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 aea1f454d81..b1e3dcf53f0 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 5f0a0702291..2aa333c1f03 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 e824c4789c7..cf42d61e136 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 46a33ce807d..e6af47952b3 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 b475b02ccfe..689f9f5b244 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 c5f83b029ce..2bda4524d23 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 2d029f1a5b7..f560fa426e2 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 5553e2f4c9c..965a443d9ac 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 12b9174f3a3..bf9ad784811 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 704d138b43b..be6f8c9e56c 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 0e4d2b9a5ae..23e6fbd2b7e 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 9244ea14514..85607c04c98 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 d0a78b57217..cc0ea5911a0 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 971df70a74e..1077f3b0146 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 fa51cd91be1..dc18cdd8f0d 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 74edf510aa2..a52656becd7 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 6c0a44b7631..0dff145ecbc 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 eaafdb0ac41..3c77668e729 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 d770dbe6f4f..4a11ac11680 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 67176276f96..91203a91be5 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 a843b4171bd..1017ec6b3c3 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 d43911df83a..21c935ae638 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 8c3cf481e5e..1735ec7cc69 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) { -- cgit 1.4.1-3-g733a5 From 3ce31eb99076261291c1a0ae4b542f52e6ca0f0a Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sat, 5 Aug 2017 12:27:28 +0300 Subject: rustc: replace usize with u64 and ConstUsize. --- src/librustc/middle/const_val.rs | 11 ++---- src/librustc/middle/mem_categorization.rs | 2 +- src/librustc/mir/tcx.rs | 12 +++--- src/librustc/session/config.rs | 10 ++--- src/librustc/ty/context.rs | 4 +- src/librustc/ty/error.rs | 4 +- src/librustc/ty/inhabitedness/mod.rs | 2 +- src/librustc/ty/layout.rs | 6 +-- src/librustc/ty/mod.rs | 4 +- src/librustc/ty/relate.rs | 2 +- src/librustc/ty/sty.rs | 4 +- src/librustc/ty/util.rs | 6 +-- src/librustc_const_eval/_match.rs | 34 ++++++++--------- src/librustc_const_eval/eval.rs | 23 ++++++------ src/librustc_const_eval/pattern.rs | 2 +- src/librustc_const_math/int.rs | 8 +--- src/librustc_const_math/is.rs | 26 +++++++------ src/librustc_const_math/us.rs | 26 +++++++------ src/librustc_driver/test.rs | 22 +++++------ src/librustc_lint/types.rs | 16 ++++---- src/librustc_mir/build/expr/as_rvalue.rs | 4 +- src/librustc_mir/build/matches/test.rs | 2 +- src/librustc_mir/build/misc.rs | 4 +- src/librustc_mir/hair/cx/mod.rs | 2 +- src/librustc_mir/shim.rs | 8 ++-- src/librustc_mir/transform/qualify_consts.rs | 4 +- src/librustc_mir/transform/type_check.rs | 3 +- src/librustc_trans/abi.rs | 6 +-- src/librustc_trans/adt.rs | 6 +-- src/librustc_trans/base.rs | 10 ++--- src/librustc_trans/common.rs | 49 ++++++++++--------------- src/librustc_trans/context.rs | 20 +++++----- src/librustc_trans/debuginfo/metadata.rs | 4 +- src/librustc_trans/glue.rs | 16 ++++---- src/librustc_trans/intrinsic.rs | 18 ++++----- src/librustc_trans/machine.rs | 2 +- src/librustc_trans/meth.rs | 6 +-- src/librustc_trans/mir/constant.rs | 55 +++++++++++++--------------- src/librustc_trans/mir/lvalue.rs | 24 ++++++------ src/librustc_trans/mir/rvalue.rs | 19 +++++----- src/librustc_trans/tvec.rs | 4 +- src/librustc_trans/type_.rs | 8 ++-- src/librustc_trans/type_of.rs | 3 +- src/librustc_typeck/astconv.rs | 2 +- src/librustc_typeck/check/_match.rs | 3 +- src/librustc_typeck/check/intrinsic.rs | 2 +- src/librustc_typeck/check/mod.rs | 23 +++++++----- src/librustdoc/clean/mod.rs | 6 +-- src/librustdoc/html/format.rs | 2 +- 49 files changed, 265 insertions(+), 274 deletions(-) (limited to 'src/librustc_mir/transform') diff --git a/src/librustc/middle/const_val.rs b/src/librustc/middle/const_val.rs index 01f050a1bd9..d213bc1de20 100644 --- a/src/librustc/middle/const_val.rs +++ b/src/librustc/middle/const_val.rs @@ -250,20 +250,15 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> { pub fn eval_length(tcx: TyCtxt, count: hir::BodyId, reason: &str) - -> Result + -> Result { let count_expr = &tcx.hir.body(count).value; let count_def_id = tcx.hir.body_owner_def_id(count); 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(&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) - }, - Ok(_) | - Err(ConstEvalErr { kind: ErrKind::TypeckError, .. }) => Err(ErrorReported), + Ok(&ty::Const { val: Integral(Usize(count)), .. }) => Ok(count), + Ok(_) | Err(ConstEvalErr { kind: ErrKind::TypeckError, .. }) => Err(ErrorReported), Err(err) => { let mut diag = err.struct_error(tcx, count_expr.span, reason); diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 8bf942c1ae3..1a4d0dcd929 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -876,7 +876,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { // Always promote `[T; 0]` (even when e.g. borrowed mutably). let promotable = match expr_ty.sty { - ty::TyArray(_, 0) => true, + ty::TyArray(_, len) if len.as_u64() == 0 => true, _ => promotable, }; diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index eb403442f46..7469402daf9 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -70,7 +70,8 @@ impl<'a, 'gcx, 'tcx> LvalueTy<'tcx> { LvalueTy::Ty { ty: match ty.sty { ty::TyArray(inner, size) => { - tcx.mk_array(inner, size-(from as usize)-(to as usize)) + let len = size.as_u64() - (from as u64) - (to as u64); + tcx.mk_array(inner, len) } ty::TySlice(..) => ty, _ => { @@ -146,11 +147,8 @@ impl<'tcx> Rvalue<'tcx> { { match *self { Rvalue::Use(ref operand) => operand.ty(local_decls, tcx), - Rvalue::Repeat(ref operand, ref count) => { - let op_ty = operand.ty(local_decls, tcx); - let count = count.as_u64(tcx.sess.target.uint_type); - assert_eq!(count as usize as u64, count); - tcx.mk_array(op_ty, count as usize) + Rvalue::Repeat(ref operand, count) => { + tcx.mk_array(operand.ty(local_decls, tcx), count.as_u64()) } Rvalue::Ref(reg, bk, ref lv) => { let lv_ty = lv.ty(local_decls, tcx).to_ty(tcx); @@ -193,7 +191,7 @@ impl<'tcx> Rvalue<'tcx> { Rvalue::Aggregate(ref ak, ref ops) => { match **ak { AggregateKind::Array(ty) => { - tcx.mk_array(ty, ops.len()) + tcx.mk_array(ty, ops.len() as u64) } AggregateKind::Tuple => { tcx.mk_tup( diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 577c905a1d5..b7e07f94f3d 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -48,8 +48,8 @@ use std::path::PathBuf; pub struct Config { pub target: Target, - pub int_type: IntTy, - pub uint_type: UintTy, + pub isize_ty: IntTy, + pub usize_ty: UintTy, } #[derive(Clone, Hash, Debug)] @@ -1149,7 +1149,7 @@ pub fn build_target_config(opts: &Options, sp: &Handler) -> Config { } }; - let (int_type, uint_type) = match &target.target_pointer_width[..] { + let (isize_ty, usize_ty) = match &target.target_pointer_width[..] { "16" => (ast::IntTy::I16, ast::UintTy::U16), "32" => (ast::IntTy::I32, ast::UintTy::U32), "64" => (ast::IntTy::I64, ast::UintTy::U64), @@ -1159,8 +1159,8 @@ pub fn build_target_config(opts: &Options, sp: &Handler) -> Config { Config { target, - int_type, - uint_type, + isize_ty, + usize_ty, } } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 8dee2675ee5..7a671b5ebc6 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -49,6 +49,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; use arena::{TypedArena, DroplessArena}; +use rustc_const_math::ConstUsize; use rustc_data_structures::indexed_vec::IndexVec; use std::borrow::Borrow; use std::cell::{Cell, RefCell}; @@ -1754,7 +1755,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.mk_imm_ptr(self.mk_nil()) } - pub fn mk_array(self, ty: Ty<'tcx>, n: usize) -> Ty<'tcx> { + pub fn mk_array(self, ty: Ty<'tcx>, n: u64) -> Ty<'tcx> { + let n = ConstUsize::new(n, self.sess.target.usize_ty).unwrap(); self.mk_ty(TyArray(ty, n)) } diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 49d7f40000f..3234a9de8c7 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -18,6 +18,8 @@ use syntax::ast; use errors::DiagnosticBuilder; use syntax_pos::Span; +use rustc_const_math::ConstUsize; + use hir; #[derive(Clone, Copy, Debug)] @@ -34,7 +36,7 @@ pub enum TypeError<'tcx> { AbiMismatch(ExpectedFound), Mutability, TupleSize(ExpectedFound), - FixedArraySize(ExpectedFound), + FixedArraySize(ExpectedFound), ArgCount, RegionsDoesNotOutlive(Region<'tcx>, Region<'tcx>), diff --git a/src/librustc/ty/inhabitedness/mod.rs b/src/librustc/ty/inhabitedness/mod.rs index 900197f3dbd..bb8ef28bbf5 100644 --- a/src/librustc/ty/inhabitedness/mod.rs +++ b/src/librustc/ty/inhabitedness/mod.rs @@ -205,7 +205,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { })) }, TyArray(ty, len) => { - if len == 0 { + if len.as_u64() == 0 { DefIdForest::empty() } else { ty.uninhabited_from(visited, tcx) diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 2348c4ae767..4d94021d2c8 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -837,7 +837,7 @@ impl<'a, 'tcx> Struct { // Is this a fixed-size array of something non-zero // with at least one element? - (_, &ty::TyArray(ety, d)) if d > 0 => { + (_, &ty::TyArray(ety, d)) if d.as_u64() > 0 => { Struct::non_zero_field_paths( tcx, param_env, @@ -1177,9 +1177,7 @@ impl<'a, 'tcx> Layout { ty::TyArray(element, count) => { let element = element.layout(tcx, param_env)?; let element_size = element.size(dl); - // FIXME(eddyb) Don't use host `usize` for array lengths. - let usize_count: usize = count; - let count = usize_count as u64; + let count = count.as_u64(); if element_size.checked_mul(count, dl).is_none() { return Err(LayoutError::SizeOverflow(ty)); } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 7c8aca9a9b1..6634af59e78 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1665,11 +1665,11 @@ impl<'a, 'gcx, 'tcx> AdtDef { match repr_type { attr::UnsignedInt(ty) => { ConstInt::new_unsigned_truncating(discr, ty, - tcx.sess.target.uint_type) + tcx.sess.target.usize_ty) } attr::SignedInt(ty) => { ConstInt::new_signed_truncating(discr as i128, ty, - tcx.sess.target.int_type) + tcx.sess.target.isize_ty) } } } diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 0ff3199689c..0acb8a2c1d1 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -429,7 +429,7 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R, { let t = relation.relate(&a_t, &b_t)?; if sz_a == sz_b { - Ok(tcx.mk_array(t, sz_a)) + Ok(tcx.mk_array(t, sz_a.as_u64())) } else { Err(TypeError::FixedArraySize(expected_found(relation, &sz_a, &sz_b))) } diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index f082e32ff68..e01f9f24235 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -27,6 +27,8 @@ use syntax::ast::{self, Name}; use syntax::symbol::keywords; use util::nodemap::FxHashMap; +use rustc_const_math::ConstUsize; + use serialize; use hir; @@ -110,7 +112,7 @@ pub enum TypeVariants<'tcx> { TyStr, /// An array with the given length. Written as `[T; n]`. - TyArray(Ty<'tcx>, usize), + TyArray(Ty<'tcx>, ConstUsize), /// The pointee of an array slice. Written as `[T]`. TySlice(Ty<'tcx>), diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index f21fc8414e7..de4481116d6 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -53,7 +53,7 @@ macro_rules! typed_literal { SignedInt(ast::IntTy::I32) => ConstInt::I32($lit), SignedInt(ast::IntTy::I64) => ConstInt::I64($lit), SignedInt(ast::IntTy::I128) => ConstInt::I128($lit), - SignedInt(ast::IntTy::Is) => match $tcx.sess.target.int_type { + SignedInt(ast::IntTy::Is) => match $tcx.sess.target.isize_ty { ast::IntTy::I16 => ConstInt::Isize(ConstIsize::Is16($lit)), ast::IntTy::I32 => ConstInt::Isize(ConstIsize::Is32($lit)), ast::IntTy::I64 => ConstInt::Isize(ConstIsize::Is64($lit)), @@ -64,7 +64,7 @@ macro_rules! typed_literal { UnsignedInt(ast::UintTy::U32) => ConstInt::U32($lit), UnsignedInt(ast::UintTy::U64) => ConstInt::U64($lit), UnsignedInt(ast::UintTy::U128) => ConstInt::U128($lit), - UnsignedInt(ast::UintTy::Us) => match $tcx.sess.target.uint_type { + UnsignedInt(ast::UintTy::Us) => match $tcx.sess.target.usize_ty { ast::UintTy::U16 => ConstInt::Usize(ConstUsize::Us16($lit)), ast::UintTy::U32 => ConstInt::Usize(ConstUsize::Us32($lit)), ast::UintTy::U64 => ConstInt::Usize(ConstUsize::Us64($lit)), @@ -638,7 +638,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } pub fn const_usize(&self, val: u16) -> ConstInt { - match self.sess.target.uint_type { + match self.sess.target.usize_ty { ast::UintTy::U16 => ConstInt::Usize(ConstUsize::Us16(val as u16)), ast::UintTy::U32 => ConstInt::Usize(ConstUsize::Us32(val as u32)), ast::UintTy::U64 => ConstInt::Usize(ConstUsize::Us64(val as u64)), diff --git a/src/librustc_const_eval/_match.rs b/src/librustc_const_eval/_match.rs index b1e3dcf53f0..429332873c0 100644 --- a/src/librustc_const_eval/_match.rs +++ b/src/librustc_const_eval/_match.rs @@ -235,7 +235,7 @@ pub enum Constructor<'tcx> { /// Ranges of literal values (`2...5` and `2..5`). ConstantRange(&'tcx ty::Const<'tcx>, &'tcx ty::Const<'tcx>, RangeEnd), /// Array patterns of length n. - Slice(usize), + Slice(u64), } impl<'tcx> Constructor<'tcx> { @@ -276,7 +276,7 @@ pub enum WitnessPreference { #[derive(Copy, Clone, Debug)] struct PatternContext<'tcx> { ty: Ty<'tcx>, - max_slice_length: usize, + max_slice_length: u64, } /// A stack of patterns in reverse order of construction @@ -330,8 +330,8 @@ impl<'tcx> Witness<'tcx> { { let arity = constructor_arity(cx, ctor, ty); let pat = { - let len = self.0.len(); - let mut pats = self.0.drain(len-arity..).rev(); + let len = self.0.len() as u64; + let mut pats = self.0.drain((len-arity) as usize..).rev(); match ty.sty { ty::TyAdt(..) | @@ -423,10 +423,10 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>, } } ty::TyArray(ref sub_ty, length) => { - if length > 0 && cx.is_uninhabited(sub_ty) { + if length.as_u64() > 0 && cx.is_uninhabited(sub_ty) { vec![] } else { - vec![Slice(length)] + vec![Slice(length.as_u64())] } } ty::TyAdt(def, substs) if def.is_enum() && def.variants.len() != 1 => { @@ -447,7 +447,7 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>, fn max_slice_length<'p, 'a: 'p, 'tcx: 'a, I>( _cx: &mut MatchCheckCtxt<'a, 'tcx>, - patterns: I) -> usize + patterns: I) -> u64 where I: Iterator> { // The exhaustiveness-checking paper does not include any details on @@ -521,15 +521,15 @@ fn max_slice_length<'p, 'a: 'p, 'tcx: 'a, I>( for row in patterns { match *row.kind { PatternKind::Constant { value: &ty::Const { val: ConstVal::ByteStr(b), .. } } => { - max_fixed_len = cmp::max(max_fixed_len, b.data.len()); + max_fixed_len = cmp::max(max_fixed_len, b.data.len() as u64); } PatternKind::Slice { ref prefix, slice: None, ref suffix } => { - let fixed_len = prefix.len() + suffix.len(); + let fixed_len = prefix.len() as u64 + suffix.len() as u64; max_fixed_len = cmp::max(max_fixed_len, fixed_len); } PatternKind::Slice { ref prefix, slice: Some(_), ref suffix } => { - max_prefix_len = cmp::max(max_prefix_len, prefix.len()); - max_suffix_len = cmp::max(max_suffix_len, suffix.len()); + max_prefix_len = cmp::max(max_prefix_len, prefix.len() as u64); + max_suffix_len = cmp::max(max_suffix_len, suffix.len() as u64); } _ => {} } @@ -729,11 +729,11 @@ fn pat_constructors<'tcx>(_cx: &mut MatchCheckCtxt, PatternKind::Range { lo, hi, end } => Some(vec![ConstantRange(lo, hi, end)]), PatternKind::Array { .. } => match pcx.ty.sty { - ty::TyArray(_, length) => Some(vec![Slice(length)]), + ty::TyArray(_, length) => Some(vec![Slice(length.as_u64())]), _ => span_bug!(pat.span, "bad ty {:?} for array pattern", pcx.ty) }, PatternKind::Slice { ref prefix, ref slice, ref suffix } => { - let pat_len = prefix.len() + suffix.len(); + let pat_len = prefix.len() as u64 + suffix.len() as u64; if slice.is_some() { Some((pat_len..pcx.max_slice_length+1).map(Slice).collect()) } else { @@ -748,10 +748,10 @@ fn pat_constructors<'tcx>(_cx: &mut MatchCheckCtxt, /// /// For instance, a tuple pattern (_, 42, Some([])) has the arity of 3. /// A struct pattern's arity is the number of fields it contains, etc. -fn constructor_arity(_cx: &MatchCheckCtxt, ctor: &Constructor, ty: Ty) -> usize { +fn constructor_arity(_cx: &MatchCheckCtxt, ctor: &Constructor, ty: Ty) -> u64 { debug!("constructor_arity({:?}, {:?})", ctor, ty); match ty.sty { - ty::TyTuple(ref fs, _) => fs.len(), + ty::TyTuple(ref fs, _) => fs.len() as u64, ty::TySlice(..) | ty::TyArray(..) => match *ctor { Slice(length) => length, ConstantValue(_) => 0, @@ -759,7 +759,7 @@ fn constructor_arity(_cx: &MatchCheckCtxt, ctor: &Constructor, ty: Ty) -> usize }, ty::TyRef(..) => 1, ty::TyAdt(adt, _) => { - adt.variants[ctor.variant_index_for_adt(adt)].fields.len() + adt.variants[ctor.variant_index_for_adt(adt)].fields.len() as u64 } _ => 0 } @@ -777,7 +777,7 @@ fn constructor_sub_pattern_tys<'a, 'tcx: 'a>(cx: &MatchCheckCtxt<'a, 'tcx>, match ty.sty { ty::TyTuple(ref fs, _) => fs.into_iter().map(|t| *t).collect(), ty::TySlice(ty) | ty::TyArray(ty, _) => match *ctor { - Slice(length) => repeat(ty).take(length).collect(), + Slice(length) => (0..length).map(|_| ty).collect(), ConstantValue(_) => vec![], _ => bug!("bad slice pattern {:?} {:?}", ctor, ty) }, diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index 2aa333c1f03..9dab067f942 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -158,7 +158,7 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>, }, (&LitKind::Int(n, _), &ty::TyInt(IntTy::Is)) | (&LitKind::Int(n, Signed(IntTy::Is)), _) => { - match tcx.sess.target.int_type { + match tcx.sess.target.isize_ty { IntTy::I16 => if n == I16_OVERFLOW { Some(Isize(Is16(i16::min_value()))) } else { @@ -342,12 +342,12 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>, "size_of" => { let size = layout_of(substs.type_at(0))?.size(tcx).bytes(); return Ok(mk_const(Integral(Usize(ConstUsize::new(size, - tcx.sess.target.uint_type).unwrap())))); + tcx.sess.target.usize_ty).unwrap())))); } "min_align_of" => { let align = layout_of(substs.type_at(0))?.align(tcx).abi(); return Ok(mk_const(Integral(Usize(ConstUsize::new(align, - tcx.sess.target.uint_type).unwrap())))); + tcx.sess.target.usize_ty).unwrap())))); } _ => signal!(e, TypeckError) } @@ -421,7 +421,7 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>, } let arr = cx.eval(arr)?; let idx = match cx.eval(idx)?.val { - Integral(Usize(i)) => i.as_u64(tcx.sess.target.uint_type), + Integral(Usize(i)) => i.as_u64(), _ => signal!(idx, IndexNotUsize), }; assert_eq!(idx as usize as u64, idx); @@ -431,7 +431,6 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>, elem } else { let n = v.len() as u64; - assert_eq!(n as usize as u64, n); signal!(e, IndexOutOfBounds { len: n, index: idx }) } } @@ -457,7 +456,7 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>, } hir::ExprRepeat(ref elem, _) => { let n = match ty.sty { - ty::TyArray(_, n) => n as u64, + ty::TyArray(_, n) => n.as_u64(), _ => span_bug!(e.span, "typeck error") }; mk_const(Aggregate(Repeat(cx.eval(elem)?, n))) @@ -562,7 +561,7 @@ fn cast_const_int<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty::TyInt(ast::IntTy::I64) => Ok(Integral(I64(v as i128 as i64))), ty::TyInt(ast::IntTy::I128) => Ok(Integral(I128(v as i128))), ty::TyInt(ast::IntTy::Is) => { - Ok(Integral(Isize(ConstIsize::new_truncating(v as i128, tcx.sess.target.int_type)))) + Ok(Integral(Isize(ConstIsize::new_truncating(v as i128, tcx.sess.target.isize_ty)))) }, ty::TyUint(ast::UintTy::U8) => Ok(Integral(U8(v as u8))), ty::TyUint(ast::UintTy::U16) => Ok(Integral(U16(v as u16))), @@ -570,7 +569,7 @@ fn cast_const_int<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty::TyUint(ast::UintTy::U64) => Ok(Integral(U64(v as u64))), ty::TyUint(ast::UintTy::U128) => Ok(Integral(U128(v as u128))), ty::TyUint(ast::UintTy::Us) => { - Ok(Integral(Usize(ConstUsize::new_truncating(v, tcx.sess.target.uint_type)))) + Ok(Integral(Usize(ConstUsize::new_truncating(v, tcx.sess.target.usize_ty)))) }, ty::TyFloat(fty) => { if let Some(i) = val.to_u128() { @@ -636,7 +635,9 @@ fn cast_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, Err(ErrKind::UnimplementedConstVal("casting a bytestr to a raw ptr")) }, ty::TyRef(_, ty::TypeAndMut { ref ty, mutbl: hir::MutImmutable }) => match ty.sty { - ty::TyArray(ty, n) if ty == tcx.types.u8 && n == b.data.len() => Ok(val), + ty::TyArray(ty, n) if ty == tcx.types.u8 && n.as_u64() == b.data.len() as u64 => { + Ok(val) + } ty::TySlice(_) => { Err(ErrKind::UnimplementedConstVal("casting a bytestr to slice")) }, @@ -678,12 +679,12 @@ fn lit_to_const<'a, 'tcx>(lit: &'tcx ast::LitKind, (&ty::TyInt(ity), _) | (_, Signed(ity)) => { Ok(Integral(ConstInt::new_signed_truncating(n as i128, - ity, tcx.sess.target.int_type))) + ity, tcx.sess.target.isize_ty))) } (&ty::TyUint(uty), _) | (_, Unsigned(uty)) => { Ok(Integral(ConstInt::new_unsigned_truncating(n as u128, - uty, tcx.sess.target.uint_type))) + uty, tcx.sess.target.usize_ty))) } _ => bug!() } diff --git a/src/librustc_const_eval/pattern.rs b/src/librustc_const_eval/pattern.rs index cf42d61e136..6274796145e 100644 --- a/src/librustc_const_eval/pattern.rs +++ b/src/librustc_const_eval/pattern.rs @@ -537,7 +537,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { ty::TyArray(_, len) => { // fixed-length array - assert!(len >= prefix.len() + suffix.len()); + assert!(len.as_u64() >= prefix.len() as u64 + suffix.len() as u64); PatternKind::Array { prefix: prefix, slice: slice, suffix: suffix } } diff --git a/src/librustc_const_math/int.rs b/src/librustc_const_math/int.rs index 65471416e80..08473d729e4 100644 --- a/src/librustc_const_math/int.rs +++ b/src/librustc_const_math/int.rs @@ -311,17 +311,13 @@ impl ::std::fmt::Display for ConstInt { I32(i) => write!(fmt, "{}i32", i), I64(i) => write!(fmt, "{}i64", i), I128(i) => write!(fmt, "{}i128", i), - Isize(ConstIsize::Is64(i)) => write!(fmt, "{}isize", i), - Isize(ConstIsize::Is32(i)) => write!(fmt, "{}isize", i), - Isize(ConstIsize::Is16(i)) => write!(fmt, "{}isize", i), + Isize(i) => write!(fmt, "{}isize", i), U8(i) => write!(fmt, "{}u8", i), U16(i) => write!(fmt, "{}u16", i), U32(i) => write!(fmt, "{}u32", i), U64(i) => write!(fmt, "{}u64", i), U128(i) => write!(fmt, "{}u128", i), - Usize(ConstUsize::Us64(i)) => write!(fmt, "{}usize", i), - Usize(ConstUsize::Us32(i)) => write!(fmt, "{}usize", i), - Usize(ConstUsize::Us16(i)) => write!(fmt, "{}usize", i), + Usize(i) => write!(fmt, "{}usize", i), } } } diff --git a/src/librustc_const_math/is.rs b/src/librustc_const_math/is.rs index 8f28ba14c6a..50dfb601129 100644 --- a/src/librustc_const_math/is.rs +++ b/src/librustc_const_math/is.rs @@ -21,18 +21,22 @@ pub enum ConstIsize { } pub use self::ConstIsize::*; +impl ::std::fmt::Display for ConstIsize { + fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { + write!(fmt, "{}", self.as_i64()) + } +} + impl ConstIsize { - pub fn as_i64(self, target_int_ty: ast::IntTy) -> i64 { - match (self, target_int_ty) { - (Is16(i), ast::IntTy::I16) => i as i64, - (Is32(i), ast::IntTy::I32) => i as i64, - (Is64(i), ast::IntTy::I64) => i, - _ => panic!("unable to convert self ({:?}) to target isize ({:?})", - self, target_int_ty), + pub fn as_i64(self) -> i64 { + match self { + Is16(i) => i as i64, + Is32(i) => i as i64, + Is64(i) => i, } } - pub fn new(i: i64, target_int_ty: ast::IntTy) -> Result { - match target_int_ty { + pub fn new(i: i64, isize_ty: ast::IntTy) -> Result { + match isize_ty { ast::IntTy::I16 if i as i16 as i64 == i => Ok(Is16(i as i16)), ast::IntTy::I16 => Err(LitOutOfRange(ast::IntTy::Is)), ast::IntTy::I32 if i as i32 as i64 == i => Ok(Is32(i as i32)), @@ -41,8 +45,8 @@ impl ConstIsize { _ => unreachable!(), } } - pub fn new_truncating(i: i128, target_int_ty: ast::IntTy) -> Self { - match target_int_ty { + pub fn new_truncating(i: i128, isize_ty: ast::IntTy) -> Self { + match isize_ty { ast::IntTy::I16 => Is16(i as i16), ast::IntTy::I32 => Is32(i as i32), ast::IntTy::I64 => Is64(i as i64), diff --git a/src/librustc_const_math/us.rs b/src/librustc_const_math/us.rs index 76443f584ab..9876bc4d779 100644 --- a/src/librustc_const_math/us.rs +++ b/src/librustc_const_math/us.rs @@ -21,18 +21,22 @@ pub enum ConstUsize { } pub use self::ConstUsize::*; +impl ::std::fmt::Display for ConstUsize { + fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { + write!(fmt, "{}", self.as_u64()) + } +} + impl ConstUsize { - pub fn as_u64(self, target_uint_ty: ast::UintTy) -> u64 { - match (self, target_uint_ty) { - (Us16(i), ast::UintTy::U16) => i as u64, - (Us32(i), ast::UintTy::U32) => i as u64, - (Us64(i), ast::UintTy::U64) => i, - _ => panic!("unable to convert self ({:?}) to target usize ({:?})", - self, target_uint_ty), + pub fn as_u64(self) -> u64 { + match self { + Us16(i) => i as u64, + Us32(i) => i as u64, + Us64(i) => i, } } - pub fn new(i: u64, target_uint_ty: ast::UintTy) -> Result { - match target_uint_ty { + pub fn new(i: u64, usize_ty: ast::UintTy) -> Result { + match usize_ty { ast::UintTy::U16 if i as u16 as u64 == i => Ok(Us16(i as u16)), ast::UintTy::U16 => Err(ULitOutOfRange(ast::UintTy::Us)), ast::UintTy::U32 if i as u32 as u64 == i => Ok(Us32(i as u32)), @@ -41,8 +45,8 @@ impl ConstUsize { _ => unreachable!(), } } - pub fn new_truncating(i: u128, target_uint_ty: ast::UintTy) -> Self { - match target_uint_ty { + pub fn new_truncating(i: u128, usize_ty: ast::UintTy) -> Self { + match usize_ty { ast::UintTy::U16 => Us16(i as u16), ast::UintTy::U32 => Us32(i as u32), ast::UintTy::U64 => Us64(i as u64), diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 8038045f762..9259474ee27 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -801,13 +801,13 @@ fn walk_ty() { test_env(EMPTY_SOURCE_STR, errors(&[]), |env| { let tcx = env.infcx.tcx; let int_ty = tcx.types.isize; - let uint_ty = tcx.types.usize; - let tup1_ty = tcx.intern_tup(&[int_ty, uint_ty, int_ty, uint_ty], false); - let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, uint_ty], false); + let usize_ty = tcx.types.usize; + let tup1_ty = tcx.intern_tup(&[int_ty, usize_ty, int_ty, usize_ty], false); + let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, usize_ty], false); let walked: Vec<_> = tup2_ty.walk().collect(); assert_eq!(walked, - [tup2_ty, tup1_ty, int_ty, uint_ty, int_ty, uint_ty, tup1_ty, int_ty, - uint_ty, int_ty, uint_ty, uint_ty]); + [tup2_ty, tup1_ty, int_ty, usize_ty, int_ty, usize_ty, tup1_ty, int_ty, + usize_ty, int_ty, usize_ty, usize_ty]); }) } @@ -816,20 +816,20 @@ fn walk_ty_skip_subtree() { test_env(EMPTY_SOURCE_STR, errors(&[]), |env| { let tcx = env.infcx.tcx; let int_ty = tcx.types.isize; - let uint_ty = tcx.types.usize; - let tup1_ty = tcx.intern_tup(&[int_ty, uint_ty, int_ty, uint_ty], false); - let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, uint_ty], false); + let usize_ty = tcx.types.usize; + let tup1_ty = tcx.intern_tup(&[int_ty, usize_ty, int_ty, usize_ty], false); + let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, usize_ty], false); // types we expect to see (in order), plus a boolean saying // whether to skip the subtree. let mut expected = vec![(tup2_ty, false), (tup1_ty, false), (int_ty, false), - (uint_ty, false), + (usize_ty, false), (int_ty, false), - (uint_ty, false), + (usize_ty, false), (tup1_ty, true), // skip the isize/usize/isize/usize - (uint_ty, false)]; + (usize_ty, false)]; expected.reverse(); let mut walker = tup2_ty.walk(); diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index e6af47952b3..d3a5d52b295 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -93,8 +93,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { if binop.node.is_shift() { let opt_ty_bits = match cx.tables.node_id_to_type(l.hir_id).sty { - ty::TyInt(t) => Some(int_ty_bits(t, cx.sess().target.int_type)), - ty::TyUint(t) => Some(uint_ty_bits(t, cx.sess().target.uint_type)), + ty::TyInt(t) => Some(int_ty_bits(t, cx.sess().target.isize_ty)), + ty::TyUint(t) => Some(uint_ty_bits(t, cx.sess().target.usize_ty)), _ => None, }; @@ -141,7 +141,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { ast::LitKind::Int(v, ast::LitIntType::Signed(_)) | ast::LitKind::Int(v, ast::LitIntType::Unsuffixed) => { let int_type = if let ast::IntTy::Is = t { - cx.sess().target.int_type + cx.sess().target.isize_ty } else { t }; @@ -164,7 +164,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { } ty::TyUint(t) => { let uint_type = if let ast::UintTy::Us = t { - cx.sess().target.uint_type + cx.sess().target.usize_ty } else { t }; @@ -250,9 +250,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { } } - fn int_ty_bits(int_ty: ast::IntTy, target_int_ty: ast::IntTy) -> u64 { + fn int_ty_bits(int_ty: ast::IntTy, isize_ty: ast::IntTy) -> u64 { match int_ty { - ast::IntTy::Is => int_ty_bits(target_int_ty, target_int_ty), + ast::IntTy::Is => int_ty_bits(isize_ty, isize_ty), ast::IntTy::I8 => 8, ast::IntTy::I16 => 16 as u64, ast::IntTy::I32 => 32, @@ -261,9 +261,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { } } - fn uint_ty_bits(uint_ty: ast::UintTy, target_uint_ty: ast::UintTy) -> u64 { + fn uint_ty_bits(uint_ty: ast::UintTy, usize_ty: ast::UintTy) -> u64 { match uint_ty { - ast::UintTy::Us => uint_ty_bits(target_uint_ty, target_uint_ty), + ast::UintTy::Us => uint_ty_bits(usize_ty, usize_ty), ast::UintTy::U8 => 8, ast::UintTy::U16 => 16, ast::UintTy::U32 => 32, diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index 2bda4524d23..eeae4bce335 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -388,7 +388,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ast::IntTy::I64 => ConstInt::I64(-1), ast::IntTy::I128 => ConstInt::I128(-1), ast::IntTy::Is => { - let int_ty = self.hir.tcx().sess.target.int_type; + let int_ty = self.hir.tcx().sess.target.isize_ty; let val = ConstIsize::new(-1, int_ty).unwrap(); ConstInt::Isize(val) } @@ -420,7 +420,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ast::IntTy::I64 => ConstInt::I64(i64::min_value()), ast::IntTy::I128 => ConstInt::I128(i128::min_value()), ast::IntTy::Is => { - let int_ty = self.hir.tcx().sess.target.int_type; + let int_ty = self.hir.tcx().sess.target.isize_ty; let min = match int_ty { ast::IntTy::I16 => std::i16::MIN as i64, ast::IntTy::I32 => std::i32::MIN as i64, diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs index 965a443d9ac..7b91c43aa37 100644 --- a/src/librustc_mir/build/matches/test.rs +++ b/src/librustc_mir/build/matches/test.rs @@ -279,7 +279,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { assert!(ty.is_slice()); - let array_ty = tcx.mk_array(tcx.types.u8, bytes.data.len()); + let array_ty = tcx.mk_array(tcx.types.u8, bytes.data.len() as u64); let array_ref = tcx.mk_imm_ref(tcx.types.re_static, array_ty); let array = self.literal_operand(test.span, array_ref, Literal::Value { value diff --git a/src/librustc_mir/build/misc.rs b/src/librustc_mir/build/misc.rs index bf9ad784811..1976b70ac0a 100644 --- a/src/librustc_mir/build/misc.rs +++ b/src/librustc_mir/build/misc.rs @@ -75,7 +75,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ast::UintTy::U64 => ConstInt::U64(0), ast::UintTy::U128 => ConstInt::U128(0), ast::UintTy::Us => { - let uint_ty = self.hir.tcx().sess.target.uint_type; + let uint_ty = self.hir.tcx().sess.target.usize_ty; let val = ConstUsize::new(0, uint_ty).unwrap(); ConstInt::Usize(val) } @@ -96,7 +96,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ast::IntTy::I64 => ConstInt::I64(0), ast::IntTy::I128 => ConstInt::I128(0), ast::IntTy::Is => { - let int_ty = self.hir.tcx().sess.target.int_type; + let int_ty = self.hir.tcx().sess.target.isize_ty; let val = ConstIsize::new(0, int_ty).unwrap(); ConstInt::Isize(val) } diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index 85607c04c98..f5e15979006 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -112,7 +112,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { } pub fn usize_literal(&mut self, value: u64) -> Literal<'tcx> { - match ConstUsize::new(value, self.tcx.sess.target.uint_type) { + match ConstUsize::new(value, self.tcx.sess.target.usize_ty) { Ok(val) => { Literal::Value { value: self.tcx.mk_const(ty::Const { diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index cc0ea5911a0..eddd4f39f43 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -292,7 +292,7 @@ fn build_clone_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, match self_ty.sty { _ if is_copy => builder.copy_shim(), - ty::TyArray(ty, len) => builder.array_shim(ty, len), + ty::TyArray(ty, len) => builder.array_shim(ty, len.as_u64()), ty::TyTuple(tys, _) => builder.tuple_shim(tys), _ => { bug!("clone shim for `{:?}` which is not `Copy` and is not an aggregate", self_ty); @@ -470,8 +470,8 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { ); } - fn make_usize(&self, value: usize) -> Box> { - let value = ConstUsize::new(value as u64, self.tcx.sess.target.uint_type).unwrap(); + fn make_usize(&self, value: u64) -> Box> { + let value = ConstUsize::new(value, self.tcx.sess.target.usize_ty).unwrap(); box Constant { span: self.span, ty: self.tcx.types.usize, @@ -484,7 +484,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { } } - fn array_shim(&mut self, ty: ty::Ty<'tcx>, len: usize) { + fn array_shim(&mut self, ty: ty::Ty<'tcx>, len: u64) { let tcx = self.tcx; let span = self.span; let rcvr = Lvalue::Local(Local::new(1+0)).deref(); diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index f891c991321..30074becb09 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -695,8 +695,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { } _ => false } - } else if let ty::TyArray(_, 0) = ty.sty { - self.mode == Mode::Fn + } else if let ty::TyArray(_, len) = ty.sty { + len.as_u64() == 0 && self.mode == Mode::Fn } else { false }; diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs index 3c77668e729..07134451a4e 100644 --- a/src/librustc_mir/transform/type_check.rs +++ b/src/librustc_mir/transform/type_check.rs @@ -209,7 +209,8 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> { LvalueTy::Ty { ty: match base_ty.sty { ty::TyArray(inner, size) => { - let min_size = (from as usize) + (to as usize); + let size = size.as_u64(); + let min_size = (from as u64) + (to as u64); if let Some(rest_size) = size.checked_sub(min_size) { tcx.mk_array(inner, rest_size) } else { diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs index 5e50696b560..4211c8df5ca 100644 --- a/src/librustc_trans/abi.rs +++ b/src/librustc_trans/abi.rs @@ -11,7 +11,7 @@ use llvm::{self, ValueRef, AttributePlace}; use base; use builder::Builder; -use common::{instance_ty, ty_fn_sig, type_is_fat_ptr, C_uint}; +use common::{instance_ty, ty_fn_sig, type_is_fat_ptr, C_usize}; use context::CrateContext; use cabi_x86; use cabi_x86_64; @@ -527,7 +527,7 @@ impl<'a, 'tcx> ArgType<'tcx> { } let ccx = bcx.ccx; if self.is_indirect() { - let llsz = C_uint(ccx, self.layout.size(ccx).bytes()); + let llsz = C_usize(ccx, self.layout.size(ccx).bytes()); let llalign = self.layout.align(ccx).abi(); base::call_memcpy(bcx, dst, val, llsz, llalign as u32); } else if let Some(ty) = self.cast { @@ -564,7 +564,7 @@ impl<'a, 'tcx> ArgType<'tcx> { base::call_memcpy(bcx, bcx.pointercast(dst, Type::i8p(ccx)), bcx.pointercast(llscratch, Type::i8p(ccx)), - C_uint(ccx, self.layout.size(ccx).bytes()), + C_usize(ccx, self.layout.size(ccx).bytes()), cmp::min(self.layout.align(ccx).abi() as u32, llalign_of_min(ccx, ty))); diff --git a/src/librustc_trans/adt.rs b/src/librustc_trans/adt.rs index 11db23732fb..23a45a7962a 100644 --- a/src/librustc_trans/adt.rs +++ b/src/librustc_trans/adt.rs @@ -397,11 +397,11 @@ pub fn trans_set_discr<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, t: Ty<'tcx>, val: Valu match *l { layout::CEnum{ discr, min, max, .. } => { assert_discr_in_range(min, max, to); - bcx.store(C_integral(Type::from_integer(bcx.ccx, discr), to, true), + bcx.store(C_int(Type::from_integer(bcx.ccx, discr), to as i64), val, None); } layout::General{ discr, .. } => { - bcx.store(C_integral(Type::from_integer(bcx.ccx, discr), to, true), + bcx.store(C_int(Type::from_integer(bcx.ccx, discr), to as i64), bcx.struct_gep(val, 0), None); } layout::Univariant { .. } @@ -423,7 +423,7 @@ pub fn trans_set_discr<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, t: Ty<'tcx>, val: Valu // than storing null to single target field. let llptr = bcx.pointercast(val, Type::i8(bcx.ccx).ptr_to()); let fill_byte = C_u8(bcx.ccx, 0); - let size = C_uint(bcx.ccx, nonnull.stride().bytes()); + let size = C_usize(bcx.ccx, nonnull.stride().bytes()); let align = C_i32(bcx.ccx, nonnull.align.abi() as i32); base::call_memset(bcx, llptr, fill_byte, size, align, false); } else { diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 6cfde9c7bbc..96499424be1 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -53,7 +53,7 @@ use mir::lvalue::LvalueRef; use attributes; use builder::Builder; use callee; -use common::{C_bool, C_bytes_in_context, C_i32, C_uint}; +use common::{C_bool, C_bytes_in_context, C_i32, C_usize}; use collector::{self, TransItemCollectionMode}; use common::{C_struct_in_context, C_u64, C_undef, C_array}; use common::CrateContext; @@ -201,7 +201,7 @@ pub fn unsized_info<'ccx, 'tcx>(ccx: &CrateContext<'ccx, 'tcx>, -> ValueRef { let (source, target) = ccx.tcx().struct_lockstep_tails(source, target); match (&source.sty, &target.sty) { - (&ty::TyArray(_, len), &ty::TySlice(_)) => C_uint(ccx, len), + (&ty::TyArray(_, len), &ty::TySlice(_)) => C_usize(ccx, len.as_u64()), (&ty::TyDynamic(..), &ty::TyDynamic(..)) => { // For now, upcasts are limited to changes in marker // traits, and hence never actually require an actual @@ -524,7 +524,7 @@ pub fn call_memcpy<'a, 'tcx>(b: &Builder<'a, 'tcx>, let memcpy = ccx.get_intrinsic(&key); let src_ptr = b.pointercast(src, Type::i8p(ccx)); let dst_ptr = b.pointercast(dst, Type::i8p(ccx)); - let size = b.intcast(n_bytes, ccx.int_type(), false); + let size = b.intcast(n_bytes, ccx.isize_ty(), false); let align = C_i32(ccx, align as i32); let volatile = C_bool(ccx, false); b.call(memcpy, &[dst_ptr, src_ptr, size, align, volatile], None); @@ -545,7 +545,7 @@ pub fn memcpy_ty<'a, 'tcx>( } let align = align.unwrap_or_else(|| ccx.align_of(t)); - call_memcpy(bcx, dst, src, C_uint(ccx, size), align); + call_memcpy(bcx, dst, src, C_usize(ccx, size), align); } pub fn call_memset<'a, 'tcx>(b: &Builder<'a, 'tcx>, @@ -696,7 +696,7 @@ fn maybe_create_entry_wrapper(ccx: &CrateContext) { sp: Span, rust_main: ValueRef, use_start_lang_item: bool) { - let llfty = Type::func(&[ccx.int_type(), Type::i8p(ccx).ptr_to()], &ccx.int_type()); + let llfty = Type::func(&[ccx.isize_ty(), Type::i8p(ccx).ptr_to()], &ccx.isize_ty()); if declare::get_defined_value(ccx, "main").is_some() { // FIXME: We should be smart and show a better diagnostic here. diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index d947cd8e719..67c95b92e52 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -221,9 +221,15 @@ pub fn C_undef(t: Type) -> ValueRef { } } -pub fn C_integral(t: Type, u: u64, sign_extend: bool) -> ValueRef { +pub fn C_int(t: Type, i: i64) -> ValueRef { unsafe { - llvm::LLVMConstInt(t.to_ref(), u, sign_extend as Bool) + llvm::LLVMConstInt(t.to_ref(), i as u64, True) + } +} + +pub fn C_uint(t: Type, i: u64) -> ValueRef { + unsafe { + llvm::LLVMConstInt(t.to_ref(), i, False) } } @@ -239,49 +245,34 @@ pub fn C_nil(ccx: &CrateContext) -> ValueRef { } pub fn C_bool(ccx: &CrateContext, val: bool) -> ValueRef { - C_integral(Type::i1(ccx), val as u64, false) + C_uint(Type::i1(ccx), val as u64) } pub fn C_i32(ccx: &CrateContext, i: i32) -> ValueRef { - C_integral(Type::i32(ccx), i as u64, true) + C_int(Type::i32(ccx), i as i64) } pub fn C_u32(ccx: &CrateContext, i: u32) -> ValueRef { - C_integral(Type::i32(ccx), i as u64, false) + C_uint(Type::i32(ccx), i as u64) } pub fn C_u64(ccx: &CrateContext, i: u64) -> ValueRef { - C_integral(Type::i64(ccx), i, false) + C_uint(Type::i64(ccx), i) } -pub fn C_uint(ccx: &CrateContext, i: I) -> ValueRef { - let v = i.as_u64(); - - let bit_size = machine::llbitsize_of_real(ccx, ccx.int_type()); +pub fn C_usize(ccx: &CrateContext, i: u64) -> ValueRef { + let bit_size = machine::llbitsize_of_real(ccx, ccx.isize_ty()); if bit_size < 64 { // make sure it doesn't overflow - assert!(v < (1< i64; } -pub trait AsU64 { fn as_u64(self) -> u64; } - -// FIXME: remove the intptr conversions, because they -// are host-architecture-dependent -impl AsI64 for i64 { fn as_i64(self) -> i64 { self as i64 }} -impl AsI64 for i32 { fn as_i64(self) -> i64 { self as i64 }} -impl AsI64 for isize { fn as_i64(self) -> i64 { self as i64 }} - -impl AsU64 for u64 { fn as_u64(self) -> u64 { self as u64 }} -impl AsU64 for u32 { fn as_u64(self) -> u64 { self as u64 }} -impl AsU64 for usize { fn as_u64(self) -> u64 { self as u64 }} - pub fn C_u8(ccx: &CrateContext, i: u8) -> ValueRef { - C_integral(Type::i8(ccx), i as u64, false) + C_uint(Type::i8(ccx), i as u64) } @@ -315,7 +306,7 @@ pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> Va pub fn C_str_slice(cx: &CrateContext, s: InternedString) -> ValueRef { let len = s.len(); let cs = consts::ptrcast(C_cstr(cx, s, false), Type::i8p(cx)); - C_named_struct(cx.str_slice_type(), &[cs, C_uint(cx, len)]) + C_named_struct(cx.str_slice_type(), &[cs, C_usize(cx, len as u64)]) } pub fn C_struct(cx: &CrateContext, elts: &[ValueRef], packed: bool) -> ValueRef { @@ -482,9 +473,9 @@ pub fn shift_mask_val<'a, 'tcx>( // i8/u8 can shift by at most 7, i16/u16 by at most 15, etc. let val = llty.int_width() - 1; if invert { - C_integral(mask_llty, !val, true) + C_int(mask_llty, !val as i64) } else { - C_integral(mask_llty, val, false) + C_uint(mask_llty, val) } }, TypeKind::Vector => { diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index a5830eb17ed..77bddc7731b 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -136,7 +136,7 @@ pub struct LocalCrateContext<'a, 'tcx: 'a> { used_statics: RefCell>, lltypes: RefCell, Type>>, - int_type: Type, + isize_ty: Type, opaque_vec_type: Type, str_slice_type: Type, @@ -398,7 +398,7 @@ impl<'a, 'tcx> LocalCrateContext<'a, 'tcx> { statics_to_rauw: RefCell::new(Vec::new()), used_statics: RefCell::new(Vec::new()), lltypes: RefCell::new(FxHashMap()), - int_type: Type::from_ref(ptr::null_mut()), + isize_ty: Type::from_ref(ptr::null_mut()), opaque_vec_type: Type::from_ref(ptr::null_mut()), str_slice_type: Type::from_ref(ptr::null_mut()), dbg_cx, @@ -410,23 +410,23 @@ impl<'a, 'tcx> LocalCrateContext<'a, 'tcx> { placeholder: PhantomData, }; - let (int_type, opaque_vec_type, str_slice_ty, mut local_ccx) = { + let (isize_ty, opaque_vec_type, str_slice_ty, mut local_ccx) = { // Do a little dance to create a dummy CrateContext, so we can // create some things in the LLVM module of this codegen unit let mut local_ccxs = vec![local_ccx]; - let (int_type, opaque_vec_type, str_slice_ty) = { + let (isize_ty, opaque_vec_type, str_slice_ty) = { let dummy_ccx = LocalCrateContext::dummy_ccx(shared, local_ccxs.as_mut_slice()); let mut str_slice_ty = Type::named_struct(&dummy_ccx, "str_slice"); str_slice_ty.set_struct_body(&[Type::i8p(&dummy_ccx), - Type::int(&dummy_ccx)], + Type::isize(&dummy_ccx)], false); - (Type::int(&dummy_ccx), Type::opaque_vec(&dummy_ccx), str_slice_ty) + (Type::isize(&dummy_ccx), Type::opaque_vec(&dummy_ccx), str_slice_ty) }; - (int_type, opaque_vec_type, str_slice_ty, local_ccxs.pop().unwrap()) + (isize_ty, opaque_vec_type, str_slice_ty, local_ccxs.pop().unwrap()) }; - local_ccx.int_type = int_type; + local_ccx.isize_ty = isize_ty; local_ccx.opaque_vec_type = opaque_vec_type; local_ccx.str_slice_type = str_slice_ty; @@ -549,8 +549,8 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { &self.local().stats } - pub fn int_type(&self) -> Type { - self.local().int_type + pub fn isize_ty(&self) -> Type { + self.local().isize_ty } pub fn str_slice_type(&self) -> Type { diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index 8bd835ac5d1..0ef93e73c4b 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -366,7 +366,7 @@ fn vec_slice_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, -> bool { member_llvm_types.len() == 2 && member_llvm_types[0] == type_of::type_of(cx, element_type).ptr_to() && - member_llvm_types[1] == cx.int_type() + member_llvm_types[1] == cx.isize_ty() } } @@ -530,7 +530,7 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, MetadataCreationResult::new(basic_type_metadata(cx, t), false) } ty::TyArray(typ, len) => { - fixed_vec_metadata(cx, unique_type_id, typ, Some(len as u64), usage_site_span) + fixed_vec_metadata(cx, unique_type_id, typ, Some(len.as_u64()), usage_site_span) } ty::TySlice(typ) => { fixed_vec_metadata(cx, unique_type_id, typ, None, usage_site_span) diff --git a/src/librustc_trans/glue.rs b/src/librustc_trans/glue.rs index c2f44c089a2..8dd0b4e466c 100644 --- a/src/librustc_trans/glue.rs +++ b/src/librustc_trans/glue.rs @@ -70,8 +70,8 @@ pub fn size_and_align_of_dst<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, t: Ty<'tcx>, inf let align = bcx.ccx.align_of(t); debug!("size_and_align_of_dst t={} info={:?} size: {} align: {}", t, Value(info), size, align); - let size = C_uint(bcx.ccx, size); - let align = C_uint(bcx.ccx, align); + let size = C_usize(bcx.ccx, size); + let align = C_usize(bcx.ccx, align as u64); return (size, align); } assert!(!info.is_null()); @@ -96,8 +96,8 @@ pub fn size_and_align_of_dst<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, t: Ty<'tcx>, inf }; debug!("DST {} statically sized prefix size: {} align: {}", t, sized_size, sized_align); - let sized_size = C_uint(ccx, sized_size); - let sized_align = C_uint(ccx, sized_align); + let sized_size = C_usize(ccx, sized_size); + let sized_align = C_usize(ccx, sized_align); // Recurse to get the size of the dynamically sized field (must be // the last field). @@ -128,7 +128,7 @@ pub fn size_and_align_of_dst<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, t: Ty<'tcx>, inf (Some(sized_align), Some(unsized_align)) => { // If both alignments are constant, (the sized_align should always be), then // pick the correct alignment statically. - C_uint(ccx, std::cmp::max(sized_align, unsized_align) as u64) + C_usize(ccx, std::cmp::max(sized_align, unsized_align) as u64) } _ => bcx.select(bcx.icmp(llvm::IntUGT, sized_align, unsized_align), sized_align, @@ -146,7 +146,7 @@ pub fn size_and_align_of_dst<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, t: Ty<'tcx>, inf // // `(size + (align-1)) & -align` - let addend = bcx.sub(align, C_uint(bcx.ccx, 1_u64)); + let addend = bcx.sub(align, C_usize(bcx.ccx, 1)); let size = bcx.and(bcx.add(size, addend), bcx.neg(align)); (size, align) @@ -159,8 +159,8 @@ pub fn size_and_align_of_dst<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, t: Ty<'tcx>, inf let unit = t.sequence_element_type(bcx.tcx()); // The info in this case is the length of the str, so the size is that // times the unit size. - (bcx.mul(info, C_uint(bcx.ccx, bcx.ccx.size_of(unit))), - C_uint(bcx.ccx, bcx.ccx.align_of(unit))) + (bcx.mul(info, C_usize(bcx.ccx, bcx.ccx.size_of(unit))), + C_usize(bcx.ccx, bcx.ccx.align_of(unit) as u64)) } _ => bug!("Unexpected unsized type, found {}", t) } diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index 8f968a8a6c6..f78d80a197c 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -135,7 +135,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, "size_of" => { let tp_ty = substs.type_at(0); let lltp_ty = type_of::type_of(ccx, tp_ty); - C_uint(ccx, machine::llsize_of_alloc(ccx, lltp_ty)) + C_usize(ccx, machine::llsize_of_alloc(ccx, lltp_ty)) } "size_of_val" => { let tp_ty = substs.type_at(0); @@ -145,12 +145,12 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, llsize } else { let lltp_ty = type_of::type_of(ccx, tp_ty); - C_uint(ccx, machine::llsize_of_alloc(ccx, lltp_ty)) + C_usize(ccx, machine::llsize_of_alloc(ccx, lltp_ty)) } } "min_align_of" => { let tp_ty = substs.type_at(0); - C_uint(ccx, ccx.align_of(tp_ty)) + C_usize(ccx, ccx.align_of(tp_ty) as u64) } "min_align_of_val" => { let tp_ty = substs.type_at(0); @@ -159,13 +159,13 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, glue::size_and_align_of_dst(bcx, tp_ty, llargs[1]); llalign } else { - C_uint(ccx, ccx.align_of(tp_ty)) + C_usize(ccx, ccx.align_of(tp_ty) as u64) } } "pref_align_of" => { let tp_ty = substs.type_at(0); let lltp_ty = type_of::type_of(ccx, tp_ty); - C_uint(ccx, machine::llalign_of_pref(ccx, lltp_ty)) + C_usize(ccx, machine::llalign_of_pref(ccx, lltp_ty) as u64) } "type_name" => { let tp_ty = substs.type_at(0); @@ -182,7 +182,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, // If we store a zero constant, LLVM will drown in vreg allocation for large data // structures, and the generated code will be awful. (A telltale sign of this is // large quantities of `mov [byte ptr foo],0` in the generated code.) - memset_intrinsic(bcx, false, ty, llresult, C_u8(ccx, 0), C_uint(ccx, 1usize)); + memset_intrinsic(bcx, false, ty, llresult, C_u8(ccx, 0), C_usize(ccx, 1)); } C_nil(ccx) } @@ -386,10 +386,10 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, "align_offset" => { // `ptr as usize` - let ptr_val = bcx.ptrtoint(llargs[0], bcx.ccx.int_type()); + let ptr_val = bcx.ptrtoint(llargs[0], bcx.ccx.isize_ty()); // `ptr_val % align` let offset = bcx.urem(ptr_val, llargs[1]); - let zero = C_null(bcx.ccx.int_type()); + let zero = C_null(bcx.ccx.isize_ty()); // `offset == 0` let is_zero = bcx.icmp(llvm::IntPredicate::IntEQ, offset, zero); // `if offset == 0 { 0 } else { offset - align }` @@ -688,7 +688,7 @@ fn copy_intrinsic<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, let lltp_ty = type_of::type_of(ccx, tp_ty); let align = C_i32(ccx, ccx.align_of(tp_ty) as i32); let size = machine::llsize_of(ccx, lltp_ty); - let int_size = machine::llbitsize_of_real(ccx, ccx.int_type()); + let int_size = machine::llbitsize_of_real(ccx, ccx.isize_ty()); let operation = if allow_overlap { "memmove" diff --git a/src/librustc_trans/machine.rs b/src/librustc_trans/machine.rs index cd31f02842a..bc383abc7e0 100644 --- a/src/librustc_trans/machine.rs +++ b/src/librustc_trans/machine.rs @@ -48,7 +48,7 @@ pub fn llsize_of(cx: &CrateContext, ty: Type) -> ValueRef { // there's no need for that contrivance. The instruction // selection DAG generator would flatten that GEP(1) node into a // constant of the type's alloc size, so let's save it some work. - return C_uint(cx, llsize_of_alloc(cx, ty)); + return C_usize(cx, llsize_of_alloc(cx, ty)); } // Returns the preferred alignment of the given type for the current target. diff --git a/src/librustc_trans/meth.rs b/src/librustc_trans/meth.rs index f5f92417858..6eedd53974e 100644 --- a/src/librustc_trans/meth.rs +++ b/src/librustc_trans/meth.rs @@ -46,7 +46,7 @@ impl<'a, 'tcx> VirtualIndex { // Load the data pointer from the object. debug!("get_int({:?}, {:?})", Value(llvtable), self); - let llvtable = bcx.pointercast(llvtable, Type::int(bcx.ccx).ptr_to()); + let llvtable = bcx.pointercast(llvtable, Type::isize(bcx.ccx).ptr_to()); let ptr = bcx.load(bcx.gepi(llvtable, &[self.0]), None); // Vtable loads are invariant bcx.set_invariant_load(ptr); @@ -81,8 +81,8 @@ pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let mut components: Vec<_> = [ callee::get_fn(ccx, monomorphize::resolve_drop_in_place(ccx.shared(), ty)), - C_uint(ccx, ccx.size_of(ty)), - C_uint(ccx, ccx.align_of(ty)) + C_usize(ccx, ccx.size_of(ty)), + C_usize(ccx, ccx.align_of(ty) as u64) ].iter().cloned().collect(); if let Some(trait_ref) = trait_ref { diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs index 21c935ae638..f75c949fefe 100644 --- a/src/librustc_trans/mir/constant.rs +++ b/src/librustc_trans/mir/constant.rs @@ -26,8 +26,8 @@ use abi::{self, Abi}; use callee; use builder::Builder; use common::{self, CrateContext, const_get_elt, val_ty}; -use common::{C_array, C_bool, C_bytes, C_integral, C_big_integral, C_u32, C_u64}; -use common::{C_null, C_struct, C_str_slice, C_undef, C_uint, C_vector, is_undef}; +use common::{C_array, C_bool, C_bytes, C_int, C_uint, C_big_integral, C_u32, C_u64}; +use common::{C_null, C_struct, C_str_slice, C_undef, C_usize, C_vector, is_undef}; use common::const_to_opt_u128; use consts; use monomorphize; @@ -66,24 +66,18 @@ impl<'tcx> Const<'tcx> { -> Const<'tcx> { let tcx = ccx.tcx(); let (llval, ty) = match *ci { - I8(v) => (C_integral(Type::i8(ccx), v as u64, true), tcx.types.i8), - I16(v) => (C_integral(Type::i16(ccx), v as u64, true), tcx.types.i16), - I32(v) => (C_integral(Type::i32(ccx), v as u64, true), tcx.types.i32), - I64(v) => (C_integral(Type::i64(ccx), v as u64, true), tcx.types.i64), + I8(v) => (C_int(Type::i8(ccx), v as i64), tcx.types.i8), + I16(v) => (C_int(Type::i16(ccx), v as i64), tcx.types.i16), + I32(v) => (C_int(Type::i32(ccx), v as i64), tcx.types.i32), + I64(v) => (C_int(Type::i64(ccx), v as i64), tcx.types.i64), I128(v) => (C_big_integral(Type::i128(ccx), v as u128), tcx.types.i128), - Isize(v) => { - let i = v.as_i64(ccx.tcx().sess.target.int_type); - (C_integral(Type::int(ccx), i as u64, true), tcx.types.isize) - }, - U8(v) => (C_integral(Type::i8(ccx), v as u64, false), tcx.types.u8), - U16(v) => (C_integral(Type::i16(ccx), v as u64, false), tcx.types.u16), - U32(v) => (C_integral(Type::i32(ccx), v as u64, false), tcx.types.u32), - U64(v) => (C_integral(Type::i64(ccx), v, false), tcx.types.u64), + Isize(v) => (C_int(Type::isize(ccx), v.as_i64()), tcx.types.isize), + U8(v) => (C_uint(Type::i8(ccx), v as u64), tcx.types.u8), + U16(v) => (C_uint(Type::i16(ccx), v as u64), tcx.types.u16), + U32(v) => (C_uint(Type::i32(ccx), v as u64), tcx.types.u32), + U64(v) => (C_uint(Type::i64(ccx), v), tcx.types.u64), U128(v) => (C_big_integral(Type::i128(ccx), v), tcx.types.u128), - Usize(v) => { - let u = v.as_u64(ccx.tcx().sess.target.uint_type); - (C_integral(Type::int(ccx), u, false), tcx.types.usize) - }, + Usize(v) => (C_uint(Type::isize(ccx), v.as_u64()), tcx.types.usize), }; Const { llval: llval, ty: ty } } @@ -106,7 +100,7 @@ impl<'tcx> Const<'tcx> { ConstVal::Integral(ref i) => return Const::from_constint(ccx, i), ConstVal::Str(ref v) => C_str_slice(ccx, v.clone()), ConstVal::ByteStr(v) => consts::addr_of(ccx, C_bytes(ccx, v.data), 1, "byte_str"), - ConstVal::Char(c) => C_integral(Type::char(ccx), c as u64, false), + ConstVal::Char(c) => C_uint(Type::char(ccx), c as u64), ConstVal::Function(..) => C_null(type_of::type_of(ccx, ty)), ConstVal::Variant(_) | ConstVal::Aggregate(..) => { @@ -206,7 +200,7 @@ impl<'tcx> ConstLvalue<'tcx> { pub fn len<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> ValueRef { match self.ty.sty { - ty::TyArray(_, n) => C_uint(ccx, n), + ty::TyArray(_, n) => C_usize(ccx, n.as_u64()), ty::TySlice(_) | ty::TyStr => { assert!(self.llextra != ptr::null_mut()); self.llextra @@ -366,13 +360,13 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { let result = if fn_ty.fn_sig(tcx).abi() == Abi::RustIntrinsic { match &tcx.item_name(def_id)[..] { "size_of" => { - let llval = C_uint(self.ccx, + let llval = C_usize(self.ccx, self.ccx.size_of(substs.type_at(0))); Ok(Const::new(llval, tcx.types.usize)) } "min_align_of" => { - let llval = C_uint(self.ccx, - self.ccx.align_of(substs.type_at(0))); + let llval = C_usize(self.ccx, + self.ccx.align_of(substs.type_at(0)) as u64); Ok(Const::new(llval, tcx.types.usize)) } _ => span_bug!(span, "{:?} in constant", terminator.kind) @@ -556,9 +550,10 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { let val = match *rvalue { mir::Rvalue::Use(ref operand) => self.const_operand(operand, span)?, - mir::Rvalue::Repeat(ref elem, ref count) => { + mir::Rvalue::Repeat(ref elem, count) => { let elem = self.const_operand(elem, span)?; - let size = count.as_u64(tcx.sess.target.uint_type); + let size = count.as_u64(); + assert_eq!(size as usize as u64, size); let fields = vec![elem.llval; size as usize]; self.const_array(dest_ty, &fields) } @@ -835,7 +830,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { mir::Rvalue::NullaryOp(mir::NullOp::SizeOf, ty) => { assert!(self.ccx.shared().type_is_sized(ty)); - let llval = C_uint(self.ccx, self.ccx.size_of(ty)); + let llval = C_usize(self.ccx, self.ccx.size_of(ty)); Const::new(llval, tcx.types.usize) } @@ -853,10 +848,10 @@ fn to_const_int(value: ValueRef, t: Ty, tcx: TyCtxt) -> Option { match t.sty { ty::TyInt(int_type) => const_to_opt_u128(value, true) .and_then(|input| ConstInt::new_signed(input as i128, int_type, - tcx.sess.target.int_type)), + tcx.sess.target.isize_ty)), ty::TyUint(uint_type) => const_to_opt_u128(value, false) .and_then(|input| ConstInt::new_unsigned(input, uint_type, - tcx.sess.target.uint_type)), + tcx.sess.target.usize_ty)), _ => None } @@ -1037,11 +1032,11 @@ fn trans_const<'a, 'tcx>( }; assert_eq!(vals.len(), 0); adt::assert_discr_in_range(min, max, discr); - C_integral(Type::from_integer(ccx, d), discr, true) + C_int(Type::from_integer(ccx, d), discr as i64) } layout::General { discr: d, ref variants, .. } => { let variant = &variants[variant_index]; - let lldiscr = C_integral(Type::from_integer(ccx, d), variant_index as u64, true); + let lldiscr = C_int(Type::from_integer(ccx, d), variant_index as i64); let mut vals_with_discr = vec![lldiscr]; vals_with_discr.extend_from_slice(vals); let mut contents = build_const_struct(ccx, &variant, &vals_with_discr[..]); diff --git a/src/librustc_trans/mir/lvalue.rs b/src/librustc_trans/mir/lvalue.rs index 8155303b0d3..d34885a1e93 100644 --- a/src/librustc_trans/mir/lvalue.rs +++ b/src/librustc_trans/mir/lvalue.rs @@ -16,7 +16,7 @@ use rustc::mir::tcx::LvalueTy; use rustc_data_structures::indexed_vec::Idx; use adt; use builder::Builder; -use common::{self, CrateContext, C_uint}; +use common::{self, CrateContext, C_usize}; use consts; use machine; use type_of; @@ -106,7 +106,7 @@ impl<'a, 'tcx> LvalueRef<'tcx> { pub fn len(&self, ccx: &CrateContext<'a, 'tcx>) -> ValueRef { let ty = self.ty.to_ty(ccx.tcx()); match ty.sty { - ty::TyArray(_, n) => common::C_uint(ccx, n), + ty::TyArray(_, n) => common::C_usize(ccx, n.as_u64()), ty::TySlice(_) | ty::TyStr => { assert!(self.llextra != ptr::null_mut()); self.llextra @@ -186,7 +186,7 @@ impl<'a, 'tcx> LvalueRef<'tcx> { let offset = st.offsets[ix].bytes(); - let unaligned_offset = C_uint(bcx.ccx, offset); + let unaligned_offset = C_usize(bcx.ccx, offset); // Get the alignment of the field let (_, align) = glue::size_and_align_of_dst(bcx, fty, meta); @@ -197,7 +197,7 @@ impl<'a, 'tcx> LvalueRef<'tcx> { // (unaligned offset + (align - 1)) & -align // Calculate offset - let align_sub_1 = bcx.sub(align, C_uint(bcx.ccx, 1u64)); + let align_sub_1 = bcx.sub(align, C_usize(bcx.ccx, 1)); let offset = bcx.and(bcx.add(unaligned_offset, align_sub_1), bcx.neg(align)); @@ -276,7 +276,7 @@ impl<'a, 'tcx> LvalueRef<'tcx> { // Slices already point to the array element type. bcx.inbounds_gep(self.llval, &[llindex]) } else { - let zero = common::C_uint(bcx.ccx, 0u64); + let zero = common::C_usize(bcx.ccx, 0); bcx.inbounds_gep(self.llval, &[zero, llindex]) } } @@ -342,19 +342,19 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { mir::ProjectionElem::ConstantIndex { offset, from_end: false, min_length: _ } => { - let lloffset = C_uint(bcx.ccx, offset); + let lloffset = C_usize(bcx.ccx, offset as u64); ((tr_base.project_index(bcx, lloffset), align), ptr::null_mut()) } mir::ProjectionElem::ConstantIndex { offset, from_end: true, min_length: _ } => { - let lloffset = C_uint(bcx.ccx, offset); + let lloffset = C_usize(bcx.ccx, offset as u64); let lllen = tr_base.len(bcx.ccx); let llindex = bcx.sub(lllen, lloffset); ((tr_base.project_index(bcx, llindex), align), ptr::null_mut()) } mir::ProjectionElem::Subslice { from, to } => { - let llbase = tr_base.project_index(bcx, C_uint(bcx.ccx, from)); + let llbase = tr_base.project_index(bcx, C_usize(bcx.ccx, from as u64)); let base_ty = tr_base.ty.to_ty(bcx.tcx()); match base_ty.sty { @@ -369,7 +369,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { ty::TySlice(..) => { assert!(tr_base.llextra != ptr::null_mut()); let lllen = bcx.sub(tr_base.llextra, - C_uint(bcx.ccx, from+to)); + C_usize(bcx.ccx, (from as u64)+(to as u64))); ((llbase, align), lllen) } _ => bug!("unexpected type {:?} in Subslice", base_ty) @@ -397,11 +397,11 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { /// nmatsakis: is this still necessary? Not sure. fn prepare_index(&mut self, bcx: &Builder<'a, 'tcx>, llindex: ValueRef) -> ValueRef { let index_size = machine::llbitsize_of_real(bcx.ccx, common::val_ty(llindex)); - let int_size = machine::llbitsize_of_real(bcx.ccx, bcx.ccx.int_type()); + let int_size = machine::llbitsize_of_real(bcx.ccx, bcx.ccx.isize_ty()); if index_size < int_size { - bcx.zext(llindex, bcx.ccx.int_type()) + bcx.zext(llindex, bcx.ccx.isize_ty()) } else if index_size > int_size { - bcx.trunc(llindex, bcx.ccx.int_type()) + bcx.trunc(llindex, bcx.ccx.isize_ty()) } else { llindex } diff --git a/src/librustc_trans/mir/rvalue.rs b/src/librustc_trans/mir/rvalue.rs index 34dec57543a..0f2d0c7f296 100644 --- a/src/librustc_trans/mir/rvalue.rs +++ b/src/librustc_trans/mir/rvalue.rs @@ -19,8 +19,7 @@ use rustc::middle::lang_items::ExchangeMallocFnLangItem; use base; use builder::Builder; use callee; -use common::{self, val_ty, C_bool, C_null, C_uint}; -use common::{C_integral, C_i32}; +use common::{self, val_ty, C_bool, C_i32, C_null, C_usize, C_uint}; use adt; use machine; use monomorphize; @@ -92,7 +91,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { bcx } - mir::Rvalue::Repeat(ref elem, ref count) => { + mir::Rvalue::Repeat(ref elem, count) => { let dest_ty = dest.ty.to_ty(bcx.tcx()); // No need to inizialize memory of a zero-sized slice @@ -101,8 +100,8 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { } let tr_elem = self.trans_operand(&bcx, elem); - let size = count.as_u64(bcx.tcx().sess.target.uint_type); - let size = C_uint(bcx.ccx, size); + let size = count.as_u64(); + let size = C_usize(bcx.ccx, size); let base = base::get_dataptr(&bcx, dest.llval); let align = dest.alignment.to_align(); @@ -113,7 +112,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { let align = C_i32(bcx.ccx, align as i32); let ty = type_of::type_of(bcx.ccx, dest_ty); let size = machine::llsize_of(bcx.ccx, ty); - let fill = C_integral(Type::i8(bcx.ccx), 0, false); + let fill = C_uint(Type::i8(bcx.ccx), 0); base::call_memset(&bcx, base, fill, size, align, false); return bcx; } @@ -301,7 +300,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { base::call_assume(&bcx, bcx.icmp( llvm::IntULE, llval, - C_integral(common::val_ty(llval), max, false) + C_uint(common::val_ty(llval), max) )); } @@ -464,7 +463,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { mir::Rvalue::NullaryOp(mir::NullOp::SizeOf, ty) => { assert!(bcx.ccx.shared().type_is_sized(ty)); - let val = C_uint(bcx.ccx, bcx.ccx.size_of(ty)); + let val = C_usize(bcx.ccx, bcx.ccx.size_of(ty)); let tcx = bcx.tcx(); (bcx, OperandRef { val: OperandValue::Immediate(val), @@ -477,7 +476,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { let llty = type_of::type_of(bcx.ccx, content_ty); let llsize = machine::llsize_of(bcx.ccx, llty); let align = bcx.ccx.align_of(content_ty); - let llalign = C_uint(bcx.ccx, align); + let llalign = C_usize(bcx.ccx, align as u64); let llty_ptr = llty.ptr_to(); let box_ty = bcx.tcx().mk_box(content_ty); @@ -522,7 +521,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { if let LocalRef::Operand(Some(op)) = self.locals[index] { if common::type_is_zero_size(bcx.ccx, op.ty) { if let ty::TyArray(_, n) = op.ty.sty { - return common::C_uint(bcx.ccx, n); + return common::C_usize(bcx.ccx, n.as_u64()); } } } diff --git a/src/librustc_trans/tvec.rs b/src/librustc_trans/tvec.rs index de4d217c735..da4a4e55a67 100644 --- a/src/librustc_trans/tvec.rs +++ b/src/librustc_trans/tvec.rs @@ -34,7 +34,7 @@ pub fn slice_for_each<'a, 'tcx, F>( let next_bcx = bcx.build_sibling_block("slice_loop_next"); let start = if zst { - C_uint(bcx.ccx, 0usize) + C_usize(bcx.ccx, 1) } else { data_ptr }; @@ -46,7 +46,7 @@ pub fn slice_for_each<'a, 'tcx, F>( let keep_going = header_bcx.icmp(llvm::IntNE, current, end); header_bcx.cond_br(keep_going, body_bcx.llbb(), next_bcx.llbb()); - let next = add(&body_bcx, current, C_uint(bcx.ccx, 1usize)); + let next = add(&body_bcx, current, C_usize(bcx.ccx, 1)); f(&body_bcx, if zst { data_ptr } else { current }, header_bcx.llbb()); header_bcx.add_incoming_to_phi(current, next, body_bcx.llbb()); next_bcx diff --git a/src/librustc_trans/type_.rs b/src/librustc_trans/type_.rs index b8a8068d36a..e5e532703d7 100644 --- a/src/librustc_trans/type_.rs +++ b/src/librustc_trans/type_.rs @@ -131,7 +131,7 @@ impl Type { Type::i8_llcx(llcx).ptr_to() } - pub fn int(ccx: &CrateContext) -> Type { + pub fn isize(ccx: &CrateContext) -> Type { match &ccx.tcx().sess.target.target.target_pointer_width[..] { "16" => Type::i16(ccx), "32" => Type::i32(ccx), @@ -142,7 +142,7 @@ impl Type { pub fn int_from_ty(ccx: &CrateContext, t: ast::IntTy) -> Type { match t { - ast::IntTy::Is => ccx.int_type(), + ast::IntTy::Is => ccx.isize_ty(), ast::IntTy::I8 => Type::i8(ccx), ast::IntTy::I16 => Type::i16(ccx), ast::IntTy::I32 => Type::i32(ccx), @@ -153,7 +153,7 @@ impl Type { pub fn uint_from_ty(ccx: &CrateContext, t: ast::UintTy) -> Type { match t { - ast::UintTy::Us => ccx.int_type(), + ast::UintTy::Us => ccx.isize_ty(), ast::UintTy::U8 => Type::i8(ccx), ast::UintTy::U16 => Type::i16(ccx), ast::UintTy::U32 => Type::i32(ccx), @@ -207,7 +207,7 @@ impl Type { pub fn vec(ccx: &CrateContext, ty: &Type) -> Type { Type::struct_(ccx, - &[Type::array(ty, 0), Type::int(ccx)], + &[Type::array(ty, 0), Type::isize(ccx)], false) } diff --git a/src/librustc_trans/type_of.rs b/src/librustc_trans/type_of.rs index 38c49833e0d..149a55f8c05 100644 --- a/src/librustc_trans/type_of.rs +++ b/src/librustc_trans/type_of.rs @@ -148,9 +148,8 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> } ty::TyArray(ty, size) => { - let size = size as u64; let llty = in_memory_type_of(cx, ty); - Type::array(&llty, size) + Type::array(&llty, size.as_u64()) } // Unsized slice types (and str) have the type of their element, and diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 2583d18652d..fc05ce4cd66 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1083,7 +1083,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } hir::TyArray(ref ty, length) => { if let Ok(length) = eval_length(tcx, length, "array length") { - tcx.mk_array(self.ast_ty_to_ty(&ty), length) + tcx.mk_array(self.ast_ty_to_ty(&ty), length.as_u64()) } else { self.tcx().types.err } diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index cc84f73a42c..02017652a6c 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -264,7 +264,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let expected_ty = self.structurally_resolved_type(pat.span, expected); let (inner_ty, slice_ty) = match expected_ty.sty { ty::TyArray(inner_ty, size) => { - let min_len = before.len() + after.len(); + let size = size.as_u64(); + let min_len = before.len() as u64 + after.len() as u64; if slice.is_none() { if min_len != size { struct_span_err!( diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 6fee7e58633..fa8d3b9bcc1 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -360,7 +360,7 @@ pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, match name["simd_shuffle".len()..].parse() { Ok(n) => { let params = vec![param(0), param(0), - tcx.mk_ty(ty::TyArray(tcx.types.u32, n))]; + tcx.mk_array(tcx.types.u32, n)]; (2, params, param(1)) } Err(_) => { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 19879ff8b15..0adfca6e886 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2636,7 +2636,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ast::LitKind::Str(..) => tcx.mk_static_str(), ast::LitKind::ByteStr(ref v) => { tcx.mk_imm_ref(tcx.types.re_static, - tcx.mk_array(tcx.types.u8, v.len())) + tcx.mk_array(tcx.types.u8, v.len() as u64)) } ast::LitKind::Byte(_) => tcx.types.u8, ast::LitKind::Char(_) => tcx.types.char, @@ -3895,11 +3895,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } else { self.next_ty_var(TypeVariableOrigin::TypeInference(expr.span)) }; - tcx.mk_array(element_ty, args.len()) + tcx.mk_array(element_ty, args.len() as u64) } hir::ExprRepeat(ref element, count) => { - let count = eval_length(self.tcx, count, "repeat count") - .unwrap_or(0); + let count = eval_length(self.tcx, count, "repeat count"); let uty = match expected { ExpectHasType(uty) => { @@ -3923,17 +3922,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } }; - if count > 1 { - // For [foo, ..n] where n > 1, `foo` must have - // Copy type: - let lang_item = self.tcx.require_lang_item(lang_items::CopyTraitLangItem); - self.require_type_meets(t, expr.span, traits::RepeatVec, lang_item); + if let Ok(count) = count { + if count.as_u64() > 1 { + // For [foo, ..n] where n > 1, `foo` must have + // Copy type: + let lang_item = self.tcx.require_lang_item(lang_items::CopyTraitLangItem); + self.require_type_meets(t, expr.span, traits::RepeatVec, lang_item); + } } if element_ty.references_error() { tcx.types.err + } else if let Ok(count) = count { + tcx.mk_ty(ty::TyArray(t, count)) } else { - tcx.mk_array(t, count) + tcx.types.err } } hir::ExprTup(ref elts) => { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 88a0d3ad4ac..a78f15dd283 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1555,7 +1555,7 @@ pub enum Type { BareFunction(Box), Tuple(Vec), Slice(Box), - Array(Box, usize), + Array(Box, String), Never, Unique(Box), RawPointer(Mutability, Box), @@ -1785,7 +1785,7 @@ impl Clean for hir::Ty { TyArray(ref ty, length) => { use rustc::middle::const_val::eval_length; let n = eval_length(cx.tcx, length, "array length").unwrap(); - Array(box ty.clean(cx), n) + Array(box ty.clean(cx), n.to_string()) }, TyTup(ref tys) => Tuple(tys.clean(cx)), TyPath(hir::QPath::Resolved(None, ref path)) => { @@ -1895,7 +1895,7 @@ impl<'tcx> Clean for ty::Ty<'tcx> { ty::TyFloat(float_ty) => Primitive(float_ty.into()), ty::TyStr => Primitive(PrimitiveType::Str), ty::TySlice(ty) => Slice(box ty.clean(cx)), - ty::TyArray(ty, n) => Array(box ty.clean(cx), n), + ty::TyArray(ty, n) => Array(box ty.clean(cx), n.to_string()), ty::TyRawPtr(mt) => RawPointer(mt.mutbl.clean(cx), box mt.ty.clean(cx)), ty::TyRef(r, mt) => BorrowedRef { lifetime: r.clean(cx), diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 10a3878073e..6303fd662bf 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -633,7 +633,7 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool) -> fmt: fmt::Display::fmt(t, f)?; primitive_link(f, PrimitiveType::Slice, "]") } - clean::Array(ref t, n) => { + clean::Array(ref t, ref n) => { primitive_link(f, PrimitiveType::Array, "[")?; fmt::Display::fmt(t, f)?; primitive_link(f, PrimitiveType::Array, &format!("; {}]", n)) -- cgit 1.4.1-3-g733a5 From 8a9b78f5cca1a0585e52a19d79ea9503f5534345 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sat, 5 Aug 2017 16:11:24 +0300 Subject: rustc: use ty::Const for the length of TyArray. --- src/librustc/middle/const_val.rs | 17 +++++++---- src/librustc/middle/mem_categorization.rs | 2 +- src/librustc/mir/tcx.rs | 5 ++-- src/librustc/ty/context.rs | 12 ++++++-- src/librustc/ty/error.rs | 13 +++++++-- src/librustc/ty/flags.rs | 38 +++++++++++++++++++++++- src/librustc/ty/inhabitedness/mod.rs | 2 +- src/librustc/ty/layout.rs | 4 +-- src/librustc/ty/relate.rs | 10 +++++-- src/librustc/ty/structural_impls.rs | 4 +-- src/librustc/ty/sty.rs | 4 +-- src/librustc/ty/util.rs | 4 ++- src/librustc/ty/walk.rs | 43 ++++++++++++++++++++++++---- src/librustc/ty/wf.rs | 13 +++++++-- src/librustc/util/ppaux.rs | 15 +++++++++- src/librustc_const_eval/_match.rs | 11 ++++--- src/librustc_const_eval/eval.rs | 11 +++++-- src/librustc_const_eval/pattern.rs | 3 +- src/librustc_mir/shim.rs | 5 +++- src/librustc_mir/transform/qualify_consts.rs | 3 +- src/librustc_mir/transform/type_check.rs | 2 +- src/librustc_trans/base.rs | 4 ++- src/librustc_trans/debuginfo/metadata.rs | 3 +- src/librustc_trans/debuginfo/type_names.rs | 2 +- src/librustc_trans/mir/constant.rs | 4 ++- src/librustc_trans/mir/lvalue.rs | 4 ++- src/librustc_trans/mir/rvalue.rs | 3 +- src/librustc_trans/trans_item.rs | 3 +- src/librustc_trans/type_of.rs | 3 +- src/librustc_typeck/astconv.rs | 2 +- src/librustc_typeck/check/_match.rs | 2 +- src/librustc_typeck/check/mod.rs | 5 +++- src/librustdoc/clean/mod.rs | 18 ++++++++++-- src/librustdoc/lib.rs | 1 + 34 files changed, 215 insertions(+), 60 deletions(-) (limited to 'src/librustc_mir/transform') diff --git a/src/librustc/middle/const_val.rs b/src/librustc/middle/const_val.rs index d213bc1de20..05e4f0da001 100644 --- a/src/librustc/middle/const_val.rs +++ b/src/librustc/middle/const_val.rs @@ -247,18 +247,23 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> { } /// Returns the value of the length-valued expression -pub fn eval_length(tcx: TyCtxt, - count: hir::BodyId, - reason: &str) - -> Result +pub fn eval_length<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, + count: hir::BodyId, + reason: &str) + -> Result<&'gcx ty::Const<'gcx>, ErrorReported> { let count_expr = &tcx.hir.body(count).value; let count_def_id = tcx.hir.body_owner_def_id(count); 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(&ty::Const { val: Integral(Usize(count)), .. }) => Ok(count), - Ok(_) | Err(ConstEvalErr { kind: ErrKind::TypeckError, .. }) => Err(ErrorReported), + Ok(count) => { + // Elsewhere in the compiler this is enforced even in the presence + // of erroneous code (type mismatch error has already been emitted). + assert_eq!(count.ty, tcx.types.usize); + Ok(count) + } + Err(ConstEvalErr { kind: ErrKind::TypeckError, .. }) => Err(ErrorReported), Err(err) => { let mut diag = err.struct_error(tcx, count_expr.span, reason); diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 1a4d0dcd929..a270e0873c1 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -876,7 +876,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { // Always promote `[T; 0]` (even when e.g. borrowed mutably). let promotable = match expr_ty.sty { - ty::TyArray(_, len) if len.as_u64() == 0 => true, + ty::TyArray(_, len) if len.val.to_const_int().unwrap().to_u64().unwrap() == 0 => true, _ => promotable, }; diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index 7469402daf9..d645a00e157 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -70,7 +70,8 @@ impl<'a, 'gcx, 'tcx> LvalueTy<'tcx> { LvalueTy::Ty { ty: match ty.sty { ty::TyArray(inner, size) => { - let len = size.as_u64() - (from as u64) - (to as u64); + let size = size.val.to_const_int().unwrap().to_u64().unwrap(); + let len = size - (from as u64) - (to as u64); tcx.mk_array(inner, len) } ty::TySlice(..) => ty, @@ -148,7 +149,7 @@ impl<'tcx> Rvalue<'tcx> { match *self { Rvalue::Use(ref operand) => operand.ty(local_decls, tcx), Rvalue::Repeat(ref operand, count) => { - tcx.mk_array(operand.ty(local_decls, tcx), count.as_u64()) + tcx.mk_array_const_usize(operand.ty(local_decls, tcx), count) } Rvalue::Ref(reg, bk, ref lv) => { let lv_ty = lv.ty(local_decls, tcx).to_ty(tcx); diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 7a671b5ebc6..e02493add31 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -21,6 +21,7 @@ use hir::map as hir_map; use hir::map::DefPathHash; use lint::{self, Lint}; use ich::{self, StableHashingContext, NodeIdHashingMode}; +use middle::const_val::ConstVal; use middle::free_region::FreeRegionMap; use middle::lang_items; use middle::resolve_lifetime::{self, ObjectLifetimeDefault}; @@ -49,7 +50,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; use arena::{TypedArena, DroplessArena}; -use rustc_const_math::ConstUsize; +use rustc_const_math::{ConstInt, ConstUsize}; use rustc_data_structures::indexed_vec::IndexVec; use std::borrow::Borrow; use std::cell::{Cell, RefCell}; @@ -1757,7 +1758,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn mk_array(self, ty: Ty<'tcx>, n: u64) -> Ty<'tcx> { let n = ConstUsize::new(n, self.sess.target.usize_ty).unwrap(); - self.mk_ty(TyArray(ty, n)) + self.mk_array_const_usize(ty, n) + } + + pub fn mk_array_const_usize(self, ty: Ty<'tcx>, n: ConstUsize) -> Ty<'tcx> { + self.mk_ty(TyArray(ty, self.mk_const(ty::Const { + val: ConstVal::Integral(ConstInt::Usize(n)), + ty: self.types.usize + }))) } pub fn mk_slice(self, ty: Ty<'tcx>) -> Ty<'tcx> { diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 3234a9de8c7..52a8389bd8f 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -10,6 +10,7 @@ use hir::def_id::DefId; use infer::type_variable; +use middle::const_val::ConstVal; use ty::{self, BoundRegion, DefIdTree, Region, Ty, TyCtxt}; use std::fmt; @@ -18,7 +19,7 @@ use syntax::ast; use errors::DiagnosticBuilder; use syntax_pos::Span; -use rustc_const_math::ConstUsize; +use rustc_const_math::ConstInt; use hir; @@ -36,7 +37,7 @@ pub enum TypeError<'tcx> { AbiMismatch(ExpectedFound), Mutability, TupleSize(ExpectedFound), - FixedArraySize(ExpectedFound), + FixedArraySize(ExpectedFound), ArgCount, RegionsDoesNotOutlive(Region<'tcx>, Region<'tcx>), @@ -181,7 +182,13 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> { ty::TyTuple(ref tys, _) if tys.is_empty() => self.to_string(), ty::TyAdt(def, _) => format!("{} `{}`", def.descr(), tcx.item_path_str(def.did)), - ty::TyArray(_, n) => format!("array of {} elements", n), + ty::TyArray(_, n) => { + if let ConstVal::Integral(ConstInt::Usize(n)) = n.val { + format!("array of {} elements", n) + } else { + "array".to_string() + } + } ty::TySlice(_) => "slice".to_string(), ty::TyRawPtr(_) => "*-ptr".to_string(), ty::TyRef(region, tymut) => { diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index 27b8d245396..62e39a507f2 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use middle::const_val::{ConstVal, ConstAggregate}; use ty::subst::Substs; use ty::{self, Ty, TypeFlags, TypeFoldable}; @@ -145,7 +146,12 @@ impl FlagComputation { self.add_region(r); } - &ty::TyArray(tt, _) | &ty::TySlice(tt) => { + &ty::TyArray(tt, len) => { + self.add_ty(tt); + self.add_const(len); + } + + &ty::TySlice(tt) => { self.add_ty(tt) } @@ -202,6 +208,36 @@ impl FlagComputation { } } + fn add_const(&mut self, constant: &ty::Const) { + self.add_ty(constant.ty); + match constant.val { + ConstVal::Integral(_) | + ConstVal::Float(_) | + ConstVal::Str(_) | + ConstVal::ByteStr(_) | + ConstVal::Bool(_) | + ConstVal::Char(_) | + ConstVal::Variant(_) => {} + ConstVal::Function(_, substs) => { + self.add_substs(substs); + } + ConstVal::Aggregate(ConstAggregate::Struct(fields)) => { + for &(_, v) in fields { + self.add_const(v); + } + } + ConstVal::Aggregate(ConstAggregate::Tuple(fields)) | + ConstVal::Aggregate(ConstAggregate::Array(fields)) => { + for v in fields { + self.add_const(v); + } + } + ConstVal::Aggregate(ConstAggregate::Repeat(v, _)) => { + self.add_const(v); + } + } + } + fn add_existential_projection(&mut self, projection: &ty::ExistentialProjection) { self.add_substs(projection.substs); self.add_ty(projection.ty); diff --git a/src/librustc/ty/inhabitedness/mod.rs b/src/librustc/ty/inhabitedness/mod.rs index bb8ef28bbf5..e10a4fb9f93 100644 --- a/src/librustc/ty/inhabitedness/mod.rs +++ b/src/librustc/ty/inhabitedness/mod.rs @@ -205,7 +205,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { })) }, TyArray(ty, len) => { - if len.as_u64() == 0 { + if len.val.to_const_int().unwrap().to_u64().unwrap() == 0 { DefIdForest::empty() } else { ty.uninhabited_from(visited, tcx) diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 4d94021d2c8..bb16413c17f 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -837,7 +837,7 @@ impl<'a, 'tcx> Struct { // Is this a fixed-size array of something non-zero // with at least one element? - (_, &ty::TyArray(ety, d)) if d.as_u64() > 0 => { + (_, &ty::TyArray(ety, d)) if d.val.to_const_int().unwrap().to_u64().unwrap() != 0 => { Struct::non_zero_field_paths( tcx, param_env, @@ -1177,7 +1177,7 @@ impl<'a, 'tcx> Layout { ty::TyArray(element, count) => { let element = element.layout(tcx, param_env)?; let element_size = element.size(dl); - let count = count.as_u64(); + let count = count.val.to_const_int().unwrap().to_u64().unwrap(); if element_size.checked_mul(count, dl).is_none() { return Err(LayoutError::SizeOverflow(ty)); } diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 0acb8a2c1d1..eb465ed16a2 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -428,10 +428,14 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R, (&ty::TyArray(a_t, sz_a), &ty::TyArray(b_t, sz_b)) => { let t = relation.relate(&a_t, &b_t)?; - if sz_a == sz_b { - Ok(tcx.mk_array(t, sz_a.as_u64())) + assert_eq!(sz_a.ty, tcx.types.usize); + assert_eq!(sz_b.ty, tcx.types.usize); + let sz_a_u64 = sz_a.val.to_const_int().unwrap().to_u64().unwrap(); + let sz_b_u64 = sz_b.val.to_const_int().unwrap().to_u64().unwrap(); + if sz_a_u64 == sz_b_u64 { + Ok(tcx.mk_ty(ty::TyArray(t, sz_a))) } else { - Err(TypeError::FixedArraySize(expected_found(relation, &sz_a, &sz_b))) + Err(TypeError::FixedArraySize(expected_found(relation, &sz_a_u64, &sz_b_u64))) } } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index f260e20a3cd..758edd7d0c3 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -552,7 +552,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { let sty = match self.sty { ty::TyRawPtr(tm) => ty::TyRawPtr(tm.fold_with(folder)), - ty::TyArray(typ, sz) => ty::TyArray(typ.fold_with(folder), sz), + ty::TyArray(typ, sz) => ty::TyArray(typ.fold_with(folder), sz.fold_with(folder)), ty::TySlice(typ) => ty::TySlice(typ.fold_with(folder)), ty::TyAdt(tid, substs) => ty::TyAdt(tid, substs.fold_with(folder)), ty::TyDynamic(ref trait_ty, ref region) => @@ -590,7 +590,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { fn super_visit_with>(&self, visitor: &mut V) -> bool { match self.sty { ty::TyRawPtr(ref tm) => tm.visit_with(visitor), - ty::TyArray(typ, _sz) => typ.visit_with(visitor), + ty::TyArray(typ, sz) => typ.visit_with(visitor) || sz.visit_with(visitor), ty::TySlice(typ) => typ.visit_with(visitor), ty::TyAdt(_, substs) => substs.visit_with(visitor), ty::TyDynamic(ref trait_ty, ref reg) => diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index e01f9f24235..f17f81ca06b 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -27,8 +27,6 @@ use syntax::ast::{self, Name}; use syntax::symbol::keywords; use util::nodemap::FxHashMap; -use rustc_const_math::ConstUsize; - use serialize; use hir; @@ -112,7 +110,7 @@ pub enum TypeVariants<'tcx> { TyStr, /// An array with the given length. Written as `[T; n]`. - TyArray(Ty<'tcx>, ConstUsize), + TyArray(Ty<'tcx>, &'tcx ty::Const<'tcx>), /// The pointee of an array slice. Written as `[T]`. TySlice(Ty<'tcx>), diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index de4481116d6..95618717e0e 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -697,7 +697,9 @@ impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W> TyInt(i) => self.hash(i), TyUint(u) => self.hash(u), TyFloat(f) => self.hash(f), - TyArray(_, n) => self.hash(n), + TyArray(_, n) => { + self.hash(n.val.to_const_int().unwrap().to_u64().unwrap()) + } TyRawPtr(m) | TyRef(_, m) => self.hash(m.mutbl), TyClosure(def_id, _) | diff --git a/src/librustc/ty/walk.rs b/src/librustc/ty/walk.rs index bfabacdb172..4d7eb37ca26 100644 --- a/src/librustc/ty/walk.rs +++ b/src/librustc/ty/walk.rs @@ -11,6 +11,7 @@ //! An iterator over the type substructure. //! WARNING: this does not keep track of the region depth. +use middle::const_val::{ConstVal, ConstAggregate}; use ty::{self, Ty}; use rustc_data_structures::small_vec::SmallVec; use rustc_data_structures::accumulate_vec::IntoIter as AccIntoIter; @@ -83,7 +84,11 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) { ty::TyBool | ty::TyChar | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) | ty::TyStr | ty::TyInfer(_) | ty::TyParam(_) | ty::TyNever | ty::TyError => { } - ty::TyArray(ty, _) | ty::TySlice(ty) => { + ty::TyArray(ty, len) => { + push_const(stack, len); + stack.push(ty); + } + ty::TySlice(ty) => { stack.push(ty); } ty::TyRawPtr(ref mt) | ty::TyRef(_, ref mt) => { @@ -122,13 +127,39 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) { ty::TyFnDef(_, substs) => { stack.extend(substs.types().rev()); } - ty::TyFnPtr(ft) => { - push_sig_subtypes(stack, ft); + ty::TyFnPtr(sig) => { + stack.push(sig.skip_binder().output()); + stack.extend(sig.skip_binder().inputs().iter().cloned().rev()); } } } -fn push_sig_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, sig: ty::PolyFnSig<'tcx>) { - stack.push(sig.skip_binder().output()); - stack.extend(sig.skip_binder().inputs().iter().cloned().rev()); +fn push_const<'tcx>(stack: &mut TypeWalkerStack<'tcx>, constant: &'tcx ty::Const<'tcx>) { + match constant.val { + ConstVal::Integral(_) | + ConstVal::Float(_) | + ConstVal::Str(_) | + ConstVal::ByteStr(_) | + ConstVal::Bool(_) | + ConstVal::Char(_) | + ConstVal::Variant(_) => {} + ConstVal::Function(_, substs) => { + stack.extend(substs.types().rev()); + } + ConstVal::Aggregate(ConstAggregate::Struct(fields)) => { + for &(_, v) in fields.iter().rev() { + push_const(stack, v); + } + } + ConstVal::Aggregate(ConstAggregate::Tuple(fields)) | + ConstVal::Aggregate(ConstAggregate::Array(fields)) => { + for v in fields.iter().rev() { + push_const(stack, v); + } + } + ConstVal::Aggregate(ConstAggregate::Repeat(v, _)) => { + push_const(stack, v); + } + } + stack.push(constant.ty); } diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index 3516f7dfb25..4d2b15b6bf0 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -207,6 +207,10 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { } } + /// Pushes the obligations required for a constant value to be WF + /// into `self.out`. + fn compute_const(&mut self, _constant: &'tcx ty::Const<'tcx>) {} + fn require_sized(&mut self, subty: Ty<'tcx>, cause: traits::ObligationCauseCode<'tcx>) { if !subty.has_escaping_regions() { let cause = self.cause(cause); @@ -239,9 +243,14 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { // WfScalar, WfParameter, etc } - ty::TySlice(subty) | - ty::TyArray(subty, _) => { + ty::TySlice(subty) => { + self.require_sized(subty, traits::SliceOrArrayElem); + } + + ty::TyArray(subty, len) => { self.require_sized(subty, traits::SliceOrArrayElem); + assert_eq!(len.ty, self.infcx.tcx.types.usize); + self.compute_const(len); } ty::TyTuple(ref tys, _) => { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 9cc978a057b..6b74022806c 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -10,6 +10,7 @@ use hir::def_id::DefId; use hir::map::definitions::DefPathData; +use middle::const_val::ConstVal; use middle::region::{self, BlockRemainder}; use ty::subst::{self, Subst}; use ty::{BrAnon, BrEnv, BrFresh, BrNamed}; @@ -24,6 +25,7 @@ use std::cell::Cell; use std::fmt; use std::usize; +use rustc_const_math::ConstInt; use syntax::abi::Abi; use syntax::ast::CRATE_NODE_ID; use syntax::symbol::Symbol; @@ -886,7 +888,18 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> { write!(f, "]") }), - TyArray(ty, sz) => write!(f, "[{}; {}]", ty, sz), + TyArray(ty, sz) => { + write!(f, "[{}; ", ty)?; + match sz.val { + ConstVal::Integral(ConstInt::Usize(sz)) => { + write!(f, "{}", sz)?; + } + _ => { + write!(f, "{:?}", sz)?; + } + } + write!(f, "]") + } TySlice(ty) => write!(f, "[{}]", ty) } } diff --git a/src/librustc_const_eval/_match.rs b/src/librustc_const_eval/_match.rs index 429332873c0..efe6cfb5464 100644 --- a/src/librustc_const_eval/_match.rs +++ b/src/librustc_const_eval/_match.rs @@ -422,11 +422,12 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>, (0..pcx.max_slice_length+1).map(|length| Slice(length)).collect() } } - ty::TyArray(ref sub_ty, length) => { - if length.as_u64() > 0 && cx.is_uninhabited(sub_ty) { + ty::TyArray(ref sub_ty, len) => { + let len = len.val.to_const_int().unwrap().to_u64().unwrap(); + if len != 0 && cx.is_uninhabited(sub_ty) { vec![] } else { - vec![Slice(length.as_u64())] + vec![Slice(len)] } } ty::TyAdt(def, substs) if def.is_enum() && def.variants.len() != 1 => { @@ -729,7 +730,9 @@ fn pat_constructors<'tcx>(_cx: &mut MatchCheckCtxt, PatternKind::Range { lo, hi, end } => Some(vec![ConstantRange(lo, hi, end)]), PatternKind::Array { .. } => match pcx.ty.sty { - ty::TyArray(_, length) => Some(vec![Slice(length.as_u64())]), + ty::TyArray(_, length) => Some(vec![ + Slice(length.val.to_const_int().unwrap().to_u64().unwrap()) + ]), _ => span_bug!(pat.span, "bad ty {:?} for array pattern", pcx.ty) }, PatternKind::Slice { ref prefix, ref slice, ref suffix } => { diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index 9dab067f942..1e3d1181281 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -456,7 +456,7 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>, } hir::ExprRepeat(ref elem, _) => { let n = match ty.sty { - ty::TyArray(_, n) => n.as_u64(), + ty::TyArray(_, n) => n.val.to_const_int().unwrap().to_u64().unwrap(), _ => span_bug!(e.span, "typeck error") }; mk_const(Aggregate(Repeat(cx.eval(elem)?, n))) @@ -635,8 +635,13 @@ fn cast_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, Err(ErrKind::UnimplementedConstVal("casting a bytestr to a raw ptr")) }, ty::TyRef(_, ty::TypeAndMut { ref ty, mutbl: hir::MutImmutable }) => match ty.sty { - ty::TyArray(ty, n) if ty == tcx.types.u8 && n.as_u64() == b.data.len() as u64 => { - Ok(val) + ty::TyArray(ty, n) => { + let n = n.val.to_const_int().unwrap().to_u64().unwrap(); + if ty == tcx.types.u8 && n == b.data.len() as u64 { + Ok(val) + } else { + Err(CannotCast) + } } ty::TySlice(_) => { Err(ErrKind::UnimplementedConstVal("casting a bytestr to slice")) diff --git a/src/librustc_const_eval/pattern.rs b/src/librustc_const_eval/pattern.rs index 6274796145e..0a2e78dd51a 100644 --- a/src/librustc_const_eval/pattern.rs +++ b/src/librustc_const_eval/pattern.rs @@ -537,7 +537,8 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { ty::TyArray(_, len) => { // fixed-length array - assert!(len.as_u64() >= prefix.len() as u64 + suffix.len() as u64); + let len = len.val.to_const_int().unwrap().to_u64().unwrap(); + assert!(len >= prefix.len() as u64 + suffix.len() as u64); PatternKind::Array { prefix: prefix, slice: slice, suffix: suffix } } diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index eddd4f39f43..00ee417e02b 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -292,7 +292,10 @@ fn build_clone_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, match self_ty.sty { _ if is_copy => builder.copy_shim(), - ty::TyArray(ty, len) => builder.array_shim(ty, len.as_u64()), + ty::TyArray(ty, len) => { + let len = len.val.to_const_int().unwrap().to_u64().unwrap(); + builder.array_shim(ty, len) + } ty::TyTuple(tys, _) => builder.tuple_shim(tys), _ => { bug!("clone shim for `{:?}` which is not `Copy` and is not an aggregate", self_ty); diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 30074becb09..2267e611531 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -696,7 +696,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { _ => false } } else if let ty::TyArray(_, len) = ty.sty { - len.as_u64() == 0 && self.mode == Mode::Fn + len.val.to_const_int().unwrap().to_u64().unwrap() == 0 && + self.mode == Mode::Fn } else { false }; diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs index 07134451a4e..ab5998a3480 100644 --- a/src/librustc_mir/transform/type_check.rs +++ b/src/librustc_mir/transform/type_check.rs @@ -209,7 +209,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> { LvalueTy::Ty { ty: match base_ty.sty { ty::TyArray(inner, size) => { - let size = size.as_u64(); + let size = size.val.to_const_int().unwrap().to_u64().unwrap(); let min_size = (from as u64) + (to as u64); if let Some(rest_size) = size.checked_sub(min_size) { tcx.mk_array(inner, rest_size) diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 96499424be1..73209affe99 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -201,7 +201,9 @@ pub fn unsized_info<'ccx, 'tcx>(ccx: &CrateContext<'ccx, 'tcx>, -> ValueRef { let (source, target) = ccx.tcx().struct_lockstep_tails(source, target); match (&source.sty, &target.sty) { - (&ty::TyArray(_, len), &ty::TySlice(_)) => C_usize(ccx, len.as_u64()), + (&ty::TyArray(_, len), &ty::TySlice(_)) => { + C_usize(ccx, len.val.to_const_int().unwrap().to_u64().unwrap()) + } (&ty::TyDynamic(..), &ty::TyDynamic(..)) => { // For now, upcasts are limited to changes in marker // traits, and hence never actually require an actual diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index 0ef93e73c4b..3c87bc293b5 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -530,7 +530,8 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, MetadataCreationResult::new(basic_type_metadata(cx, t), false) } ty::TyArray(typ, len) => { - fixed_vec_metadata(cx, unique_type_id, typ, Some(len.as_u64()), usage_site_span) + let len = len.val.to_const_int().unwrap().to_u64().unwrap(); + fixed_vec_metadata(cx, unique_type_id, typ, Some(len), usage_site_span) } ty::TySlice(typ) => { fixed_vec_metadata(cx, unique_type_id, typ, None, usage_site_span) diff --git a/src/librustc_trans/debuginfo/type_names.rs b/src/librustc_trans/debuginfo/type_names.rs index 6eda8657519..7bf9d39ea2f 100644 --- a/src/librustc_trans/debuginfo/type_names.rs +++ b/src/librustc_trans/debuginfo/type_names.rs @@ -96,7 +96,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ty::TyArray(inner_type, len) => { output.push('['); push_debuginfo_type_name(cx, inner_type, true, output); - output.push_str(&format!("; {}", len)); + output.push_str(&format!("; {}", len.val.to_const_int().unwrap().to_u64().unwrap())); output.push(']'); }, ty::TySlice(inner_type) => { diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs index f75c949fefe..072d351dd61 100644 --- a/src/librustc_trans/mir/constant.rs +++ b/src/librustc_trans/mir/constant.rs @@ -200,7 +200,9 @@ impl<'tcx> ConstLvalue<'tcx> { pub fn len<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> ValueRef { match self.ty.sty { - ty::TyArray(_, n) => C_usize(ccx, n.as_u64()), + ty::TyArray(_, n) => { + C_usize(ccx, n.val.to_const_int().unwrap().to_u64().unwrap()) + } ty::TySlice(_) | ty::TyStr => { assert!(self.llextra != ptr::null_mut()); self.llextra diff --git a/src/librustc_trans/mir/lvalue.rs b/src/librustc_trans/mir/lvalue.rs index d34885a1e93..6799e52904d 100644 --- a/src/librustc_trans/mir/lvalue.rs +++ b/src/librustc_trans/mir/lvalue.rs @@ -106,7 +106,9 @@ impl<'a, 'tcx> LvalueRef<'tcx> { pub fn len(&self, ccx: &CrateContext<'a, 'tcx>) -> ValueRef { let ty = self.ty.to_ty(ccx.tcx()); match ty.sty { - ty::TyArray(_, n) => common::C_usize(ccx, n.as_u64()), + ty::TyArray(_, n) => { + common::C_usize(ccx, n.val.to_const_int().unwrap().to_u64().unwrap()) + } ty::TySlice(_) | ty::TyStr => { assert!(self.llextra != ptr::null_mut()); self.llextra diff --git a/src/librustc_trans/mir/rvalue.rs b/src/librustc_trans/mir/rvalue.rs index 0f2d0c7f296..20ed4ab50a0 100644 --- a/src/librustc_trans/mir/rvalue.rs +++ b/src/librustc_trans/mir/rvalue.rs @@ -521,7 +521,8 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { if let LocalRef::Operand(Some(op)) = self.locals[index] { if common::type_is_zero_size(bcx.ccx, op.ty) { if let ty::TyArray(_, n) = op.ty.sty { - return common::C_usize(bcx.ccx, n.as_u64()); + let n = n.val.to_const_int().unwrap().to_u64().unwrap(); + return common::C_usize(bcx.ccx, n); } } } diff --git a/src/librustc_trans/trans_item.rs b/src/librustc_trans/trans_item.rs index 672fa32aa85..1f27eb9fcb3 100644 --- a/src/librustc_trans/trans_item.rs +++ b/src/librustc_trans/trans_item.rs @@ -446,7 +446,8 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { ty::TyArray(inner_type, len) => { output.push('['); self.push_type_name(inner_type, output); - write!(output, "; {}", len).unwrap(); + write!(output, "; {}", + len.val.to_const_int().unwrap().to_u64().unwrap()).unwrap(); output.push(']'); }, ty::TySlice(inner_type) => { diff --git a/src/librustc_trans/type_of.rs b/src/librustc_trans/type_of.rs index 149a55f8c05..992c74b9020 100644 --- a/src/librustc_trans/type_of.rs +++ b/src/librustc_trans/type_of.rs @@ -149,7 +149,8 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> ty::TyArray(ty, size) => { let llty = in_memory_type_of(cx, ty); - Type::array(&llty, size.as_u64()) + let size = size.val.to_const_int().unwrap().to_u64().unwrap(); + Type::array(&llty, size) } // Unsized slice types (and str) have the type of their element, and diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index fc05ce4cd66..6759b6a422d 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1083,7 +1083,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } hir::TyArray(ref ty, length) => { if let Ok(length) = eval_length(tcx, length, "array length") { - tcx.mk_array(self.ast_ty_to_ty(&ty), length.as_u64()) + tcx.mk_ty(ty::TyArray(self.ast_ty_to_ty(&ty), length)) } else { self.tcx().types.err } diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 02017652a6c..cbf58209d05 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -264,7 +264,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let expected_ty = self.structurally_resolved_type(pat.span, expected); let (inner_ty, slice_ty) = match expected_ty.sty { ty::TyArray(inner_ty, size) => { - let size = size.as_u64(); + let size = size.val.to_const_int().unwrap().to_u64().unwrap(); let min_len = before.len() as u64 + after.len() as u64; if slice.is_none() { if min_len != size { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 0adfca6e886..0ed3cc1e905 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3923,7 +3923,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }; if let Ok(count) = count { - if count.as_u64() > 1 { + let zero_or_one = count.val.to_const_int().and_then(|count| { + count.to_u64().map(|count| count <= 1) + }).unwrap_or(false); + if !zero_or_one { // For [foo, ..n] where n > 1, `foo` must have // Copy type: let lang_item = self.tcx.require_lang_item(lang_items::CopyTraitLangItem); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index a78f15dd283..69c05050dac 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -27,6 +27,7 @@ use syntax::ptr::P; use syntax::symbol::keywords; use syntax_pos::{self, DUMMY_SP, Pos}; +use rustc::middle::const_val::ConstVal; use rustc::middle::privacy::AccessLevels; use rustc::middle::resolve_lifetime as rl; use rustc::middle::lang_items; @@ -40,6 +41,7 @@ use rustc_typeck::hir_ty_to_ty; use rustc::hir; +use rustc_const_math::ConstInt; use std::{mem, slice, vec}; use std::path::PathBuf; use std::rc::Rc; @@ -1785,7 +1787,12 @@ impl Clean for hir::Ty { TyArray(ref ty, length) => { use rustc::middle::const_val::eval_length; let n = eval_length(cx.tcx, length, "array length").unwrap(); - Array(box ty.clean(cx), n.to_string()) + let n = if let ConstVal::Integral(ConstInt::Usize(n)) = n.val { + n.to_string() + } else { + format!("{:?}", n) + }; + Array(box ty.clean(cx), n) }, TyTup(ref tys) => Tuple(tys.clean(cx)), TyPath(hir::QPath::Resolved(None, ref path)) => { @@ -1895,7 +1902,14 @@ impl<'tcx> Clean for ty::Ty<'tcx> { ty::TyFloat(float_ty) => Primitive(float_ty.into()), ty::TyStr => Primitive(PrimitiveType::Str), ty::TySlice(ty) => Slice(box ty.clean(cx)), - ty::TyArray(ty, n) => Array(box ty.clean(cx), n.to_string()), + ty::TyArray(ty, n) => { + let n = if let ConstVal::Integral(ConstInt::Usize(n)) = n.val { + n.to_string() + } else { + format!("{:?}", n) + }; + Array(box ty.clean(cx), n) + } ty::TyRawPtr(mt) => RawPointer(mt.mutbl.clean(cx), box mt.ty.clean(cx)), ty::TyRef(r, mt) => BorrowedRef { lifetime: r.clean(cx), diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index d04b6d3417a..9563ccfcc65 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -32,6 +32,7 @@ extern crate html_diff; extern crate libc; extern crate rustc; extern crate rustc_data_structures; +extern crate rustc_const_math; extern crate rustc_trans; extern crate rustc_driver; extern crate rustc_resolve; -- cgit 1.4.1-3-g733a5 From 57ebd28fdb69d7cc4df3de343664e6698a4b55f0 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sun, 3 Sep 2017 20:34:48 +0300 Subject: rustc: use ConstVal::Unevaluated instead of mir::Literal::Item. --- src/librustc/ich/impls_mir.rs | 4 ---- src/librustc/mir/mod.rs | 18 +++++------------- src/librustc/mir/visit.rs | 5 ----- src/librustc_mir/hair/cx/expr.rs | 8 +++++--- src/librustc_mir/transform/qualify_consts.rs | 9 ++++++--- src/librustc_passes/mir_stats.rs | 1 - src/librustc_trans/collector.rs | 16 +++++----------- src/librustc_trans/mir/constant.rs | 22 ++++++++++++---------- 8 files changed, 33 insertions(+), 50 deletions(-) (limited to 'src/librustc_mir/transform') diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs index 9a061da177e..dce1639b375 100644 --- a/src/librustc/ich/impls_mir.rs +++ b/src/librustc/ich/impls_mir.rs @@ -493,10 +493,6 @@ impl<'a, 'gcx, 'tcx> HashStable> for mir::L hasher: &mut StableHasher) { mem::discriminant(self).hash_stable(hcx, hasher); match *self { - mir::Literal::Item { def_id, substs } => { - def_id.hash_stable(hcx, hasher); - substs.hash_stable(hcx, hasher); - } mir::Literal::Value { ref value } => { value.hash_stable(hcx, hasher); } diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index d9ca5ddf46b..38dfe010c15 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1479,10 +1479,6 @@ newtype_index!(Promoted, "promoted"); #[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] pub enum Literal<'tcx> { - Item { - def_id: DefId, - substs: &'tcx Substs<'tcx>, - }, Value { value: &'tcx ty::Const<'tcx>, }, @@ -1502,9 +1498,6 @@ impl<'tcx> Debug for Literal<'tcx> { fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { use self::Literal::*; match *self { - Item { def_id, substs } => { - ppaux::parameterized(fmt, substs, def_id, &[]) - } Value { value } => { write!(fmt, "const ")?; fmt_const_val(fmt, &value.val) @@ -2002,17 +1995,16 @@ impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> { impl<'tcx> TypeFoldable<'tcx> for Literal<'tcx> { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { match *self { - Literal::Item { def_id, substs } => Literal::Item { - def_id, - substs: substs.fold_with(folder) + Literal::Value { value } => Literal::Value { + value: value.fold_with(folder) }, - _ => self.clone() + Literal::Promoted { index } => Literal::Promoted { index } } } fn super_visit_with>(&self, visitor: &mut V) -> bool { match *self { - Literal::Item { substs, .. } => substs.visit_with(visitor), - _ => false + Literal::Value { value } => value.visit_with(visitor), + Literal::Promoted { .. } => false } } } diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 22d93c1a276..37c97ad3dad 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -724,11 +724,6 @@ macro_rules! make_mir_visitor { literal: & $($mutability)* Literal<'tcx>, location: Location) { match *literal { - Literal::Item { ref $($mutability)* def_id, - ref $($mutability)* substs } => { - self.visit_def_id(def_id, location); - self.visit_substs(substs, location); - } Literal::Value { ref $($mutability)* value } => { self.visit_const(value, location); } diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 23e6fbd2b7e..45449103c80 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -643,9 +643,11 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, Def::Const(def_id) | Def::AssociatedConst(def_id) => ExprKind::Literal { - literal: Literal::Item { - def_id, - substs, + literal: Literal::Value { + value: cx.tcx.mk_const(ty::Const { + val: ConstVal::Unevaluated(def_id, substs), + ty: cx.tables().node_id_to_type(expr.hir_id) + }), }, }, diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 2267e611531..5550fb2788e 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -20,6 +20,7 @@ use rustc_data_structures::indexed_vec::{IndexVec, Idx}; use rustc::hir; use rustc::hir::map as hir_map; use rustc::hir::def_id::DefId; +use rustc::middle::const_val::ConstVal; use rustc::traits::{self, Reveal}; use rustc::ty::{self, TyCtxt, Ty, TypeFoldable}; use rustc::ty::cast::CastTy; @@ -622,10 +623,12 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { } } Operand::Constant(ref constant) => { - if let Literal::Item { def_id, substs: _ } = constant.literal { + if let Literal::Value { + value: &ty::Const { val: ConstVal::Unevaluated(def_id, _), ty } + } = constant.literal { // Don't peek inside trait associated constants. if self.tcx.trait_of_item(def_id).is_some() { - self.add_type(constant.ty); + self.add_type(ty); } else { let (bits, _) = self.tcx.at(constant.span).mir_const_qualif(def_id); @@ -635,7 +638,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { // Just in case the type is more specific than // the definition, e.g. impl associated const // with type parameters, take it into account. - self.qualif.restrict(constant.ty, self.tcx, self.param_env); + self.qualif.restrict(ty, self.tcx, self.param_env); } // Let `const fn` transitively have destructors, diff --git a/src/librustc_passes/mir_stats.rs b/src/librustc_passes/mir_stats.rs index 91203a91be5..1fa49614580 100644 --- a/src/librustc_passes/mir_stats.rs +++ b/src/librustc_passes/mir_stats.rs @@ -235,7 +235,6 @@ impl<'a, 'tcx> mir_visit::Visitor<'tcx> for StatCollector<'a, 'tcx> { location: Location) { self.record("Literal", literal); self.record(match *literal { - Literal::Item { .. } => "Literal::Item", Literal::Value { .. } => "Literal::Value", Literal::Promoted { .. } => "Literal::Promoted", }, literal); diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index b56fa34e348..3bf709ff7ba 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -193,6 +193,7 @@ use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir::map as hir_map; use rustc::hir::def_id::DefId; +use rustc::middle::const_val::ConstVal; use rustc::middle::lang_items::{ExchangeMallocFnLangItem}; use rustc::traits; use rustc::ty::subst::Substs; @@ -564,24 +565,17 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { self.super_rvalue(rvalue, location); } - fn visit_constant(&mut self, constant: &mir::Constant<'tcx>, location: Location) { - debug!("visiting constant {:?} @ {:?}", *constant, location); + fn visit_const(&mut self, constant: &&'tcx ty::Const<'tcx>, location: Location) { + debug!("visiting const {:?} @ {:?}", *constant, location); - if let ty::TyFnDef(..) = constant.ty.sty { - // function definitions are zero-sized, and only generate - // IR when they are called/reified. - self.super_constant(constant, location); - return - } - - if let mir::Literal::Item { def_id, substs } = constant.literal { + if let ConstVal::Unevaluated(def_id, substs) = constant.val { let substs = self.scx.tcx().trans_apply_param_substs(self.param_substs, &substs); let instance = monomorphize::resolve(self.scx, def_id, substs); collect_neighbours(self.scx, instance, true, self.output); } - self.super_constant(constant, location); + self.super_const(constant); } fn visit_terminator_kind(&mut self, diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs index 6e975941e8e..4c3326a466d 100644 --- a/src/librustc_trans/mir/constant.rs +++ b/src/librustc_trans/mir/constant.rs @@ -510,16 +510,17 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { mir::Operand::Constant(ref constant) => { let ty = self.monomorphize(&constant.ty); match constant.literal.clone() { - mir::Literal::Item { def_id, substs } => { - let substs = self.monomorphize(&substs); - MirConstContext::trans_def(self.ccx, def_id, substs, IndexVec::new()) - } mir::Literal::Promoted { index } => { let mir = &self.mir.promoted[index]; MirConstContext::new(self.ccx, mir, self.substs, IndexVec::new()).trans() } mir::Literal::Value { value } => { - Ok(Const::from_constval(self.ccx, &value.val, ty)) + if let ConstVal::Unevaluated(def_id, substs) = value.val { + let substs = self.monomorphize(&substs); + MirConstContext::trans_def(self.ccx, def_id, substs, IndexVec::new()) + } else { + Ok(Const::from_constval(self.ccx, &value.val, ty)) + } } } } @@ -960,16 +961,17 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { debug!("trans_constant({:?})", constant); let ty = self.monomorphize(&constant.ty); let result = match constant.literal.clone() { - mir::Literal::Item { def_id, substs } => { - let substs = self.monomorphize(&substs); - MirConstContext::trans_def(bcx.ccx, def_id, substs, IndexVec::new()) - } mir::Literal::Promoted { index } => { let mir = &self.mir.promoted[index]; MirConstContext::new(bcx.ccx, mir, self.param_substs, IndexVec::new()).trans() } mir::Literal::Value { value } => { - Ok(Const::from_constval(bcx.ccx, &value.val, ty)) + if let ConstVal::Unevaluated(def_id, substs) = value.val { + let substs = self.monomorphize(&substs); + MirConstContext::trans_def(bcx.ccx, def_id, substs, IndexVec::new()) + } else { + Ok(Const::from_constval(bcx.ccx, &value.val, ty)) + } } }; -- cgit 1.4.1-3-g733a5