diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 8a32e8f46c29..b8ccec4fec72 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1939,7 +1939,7 @@ pub enum ProjectionElem<'tcx, V, T> { /// "Downcast" to a variant of an ADT. Currently, we only introduce /// this for ADTs with more than one variant. It may be better to /// just introduce it always, or always for enums. - Downcast(&'tcx AdtDef, usize), + Downcast(&'tcx AdtDef, u32), } /// Alias for projections as they appear in places, where the base is a place @@ -1950,6 +1950,11 @@ pub type PlaceProjection<'tcx> = Projection<'tcx, Place<'tcx>, Local, Ty<'tcx>>; /// and the index is a local. pub type PlaceElem<'tcx> = ProjectionElem<'tcx, Local, Ty<'tcx>>; +// at least on 64 bit systems, `PlaceElem` should not be larger than two pointers +static_assert!(PROJECTION_ELEM_IS_2_PTRS_LARGE: + mem::size_of::>() <= 16 +); + /// Alias for projections as they appear in `UserTypeProjection`, where we /// need neither the `V` parameter for `Index` nor the `T` for `Field`. pub type ProjectionKind<'tcx> = ProjectionElem<'tcx, (), ()>; @@ -1970,7 +1975,7 @@ impl<'tcx> Place<'tcx> { } pub fn downcast(self, adt_def: &'tcx AdtDef, variant_index: usize) -> Place<'tcx> { - self.elem(ProjectionElem::Downcast(adt_def, variant_index)) + self.elem(ProjectionElem::Downcast(adt_def, variant_index as u32)) } pub fn index(self, index: Local) -> Place<'tcx> { @@ -2021,7 +2026,7 @@ impl<'tcx> Debug for Place<'tcx> { Promoted(ref promoted) => write!(fmt, "({:?}: {:?})", promoted.0, promoted.1), Projection(ref data) => match data.elem { ProjectionElem::Downcast(ref adt_def, index) => { - write!(fmt, "({:?} as {})", data.base, adt_def.variants[index].name) + write!(fmt, "({:?} as {})", data.base, adt_def.variants[index as usize].name) } ProjectionElem::Deref => write!(fmt, "(*{:?})", data.base), ProjectionElem::Field(field, ty) => { diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index f773f46b6f58..c9a396ff8c59 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -27,9 +27,13 @@ pub enum PlaceTy<'tcx> { /// Downcast to a particular variant of an enum. Downcast { adt_def: &'tcx AdtDef, substs: &'tcx Substs<'tcx>, - variant_index: usize }, + variant_index: u32 }, } +static_assert!(PLACE_TY_IS_3_PTRS_LARGE: + mem::size_of::>() <= 24 +); + impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> { pub fn from_ty(ty: Ty<'tcx>) -> PlaceTy<'tcx> { PlaceTy::Ty { ty } @@ -58,7 +62,7 @@ impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> { (PlaceTy::Ty { ty: &ty::TyS { sty: ty::TyKind::Adt(adt_def, substs), .. } }, variant_index) | (PlaceTy::Downcast { adt_def, substs, variant_index }, _) => { - let variant_def = &adt_def.variants[variant_index]; + let variant_def = &adt_def.variants[variant_index as usize]; let field_def = &variant_def.fields[f.index()]; field_def.ty(tcx, substs) } @@ -134,7 +138,7 @@ impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> { match self.to_ty(tcx).sty { ty::Adt(adt_def, substs) => { assert!(adt_def.is_enum()); - assert!(index < adt_def.variants.len()); + assert!(index < adt_def.variants.len() as u32); assert_eq!(adt_def, adt_def1); PlaceTy::Downcast { adt_def, substs, diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 9a63bb374c66..0ba28811a90a 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1801,6 +1801,7 @@ pub struct FieldDef { /// table. pub struct AdtDef { pub did: DefId, + // TODO: make this an IndexVec pub variants: Vec, flags: AdtFlags, pub repr: ReprOptions, diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 59a66513eef0..17a5f0999e7b 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -33,6 +33,7 @@ CloneTypeFoldableAndLiftImpls! { (), bool, usize, + u32, u64, ::middle::region::Scope, ::syntax::ast::FloatTy,