From 8b2037c6fec88fc02b7f5087f14f25b9476dd42d Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 23 Feb 2018 01:13:54 +0000 Subject: [PATCH] Introduce UnpackedKind This adds an `UnpackedKind` type as a typesafe counterpart to `Kind`. This should make future changes to kinds (such as const generics!) more resilient, as the type-checker should catch more potential issues. --- src/librustc/ich/impls_ty.rs | 15 +- src/librustc/infer/anon_types/mod.rs | 7 +- src/librustc/traits/select.rs | 4 +- src/librustc/ty/instance.rs | 5 +- src/librustc/ty/relate.rs | 16 +- src/librustc/ty/sty.rs | 19 ++- src/librustc/ty/subst.rs | 175 ++++++++++---------- src/librustc/ty/util.rs | 28 ++-- src/librustc_const_eval/_match.rs | 2 +- src/librustc_driver/test.rs | 8 +- src/librustc_mir/interpret/eval_context.rs | 4 +- src/librustc_mir/monomorphize/mod.rs | 4 +- src/librustc_mir/transform/generator.rs | 6 +- src/librustc_trans/common.rs | 5 +- src/librustc_typeck/astconv.rs | 7 +- src/librustc_typeck/check/dropck.rs | 9 +- src/librustc_typeck/variance/constraints.rs | 15 +- 17 files changed, 175 insertions(+), 154 deletions(-) diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index d1e431597e7..71a57dbf32f 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -56,8 +56,19 @@ for ty::subst::Kind<'gcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher) { - self.as_type().hash_stable(hcx, hasher); - self.as_region().hash_stable(hcx, hasher); + self.unpack().hash_stable(hcx, hasher); + } +} + +impl<'gcx> HashStable> +for ty::subst::UnpackedKind<'gcx> { + fn hash_stable(&self, + hcx: &mut StableHashingContext<'gcx>, + hasher: &mut StableHasher) { + match self { + ty::subst::UnpackedKind::Lifetime(lt) => lt.hash_stable(hcx, hasher), + ty::subst::UnpackedKind::Type(ty) => ty.hash_stable(hcx, hasher), + } } } diff --git a/src/librustc/infer/anon_types/mod.rs b/src/librustc/infer/anon_types/mod.rs index f5b88dbc2a9..a749d0dddd7 100644 --- a/src/librustc/infer/anon_types/mod.rs +++ b/src/librustc/infer/anon_types/mod.rs @@ -17,7 +17,7 @@ use traits::{self, PredicateObligation}; use ty::{self, Ty}; use ty::fold::{BottomUpFolder, TypeFoldable}; use ty::outlives::Component; -use ty::subst::{Kind, Substs}; +use ty::subst::{Kind, UnpackedKind, Substs}; use util::nodemap::DefIdMap; pub type AnonTypeMap<'tcx> = DefIdMap>; @@ -321,7 +321,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { let index = region_def.index as usize; // Get the value supplied for this region from the substs. - let subst_arg = anon_defn.substs[index].as_region().unwrap(); + let subst_arg = anon_defn.substs.region_at(index); // Compute the least upper bound of it with the other regions. debug!("constrain_anon_types: least_region={:?}", least_region); @@ -466,7 +466,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // All other regions, we map them appropriately to their adjusted // indices, erroring if we find any lifetimes that were not mapped // into the new set. - _ => if let Some(r1) = map.get(&Kind::from(r)).and_then(|k| k.as_region()) { + _ => if let Some(UnpackedKind::Lifetime(r1)) = map.get(&r.into()) + .map(|k| k.unpack()) { r1 } else { // No mapping was found. This means that diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index cfeb456acef..6b0e3ce0539 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -584,7 +584,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { let trait_ref = &mut trait_pred.trait_ref; let unit_substs = trait_ref.substs; let mut never_substs = Vec::with_capacity(unit_substs.len()); - never_substs.push(From::from(tcx.types.never)); + never_substs.push(tcx.types.never.into()); never_substs.extend(&unit_substs[1..]); trait_ref.substs = tcx.intern_substs(&never_substs); } @@ -2997,7 +2997,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // unsized parameters is equal to the target. let params = substs_a.iter().enumerate().map(|(i, &k)| { if ty_params.contains(i) { - Kind::from(substs_b.type_at(i)) + substs_b.type_at(i).into() } else { k } diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 63bf52a9bdf..f4b5ffbb7dc 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -355,10 +355,7 @@ fn fn_once_adapter_instance<'a, 'tcx>( let sig = substs.closure_sig(closure_did, tcx); let sig = tcx.erase_late_bound_regions_and_normalize(&sig); assert_eq!(sig.inputs().len(), 1); - let substs = tcx.mk_substs([ - Kind::from(self_ty), - Kind::from(sig.inputs()[0]), - ].iter().cloned()); + let substs = tcx.mk_substs([Kind::from(self_ty), sig.inputs()[0].into()].iter().cloned()); debug!("fn_once_adapter_shim: self_ty={:?} sig={:?}", self_ty, sig); Instance { def, substs } diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index a6c72728a51..b9927c7eeb2 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -16,7 +16,7 @@ use hir::def_id::DefId; use middle::const_val::ConstVal; use traits::Reveal; -use ty::subst::{Kind, Substs}; +use ty::subst::{UnpackedKind, Substs}; use ty::{self, Ty, TyCtxt, TypeFoldable}; use ty::fold::{TypeVisitor, TypeFolder}; use ty::error::{ExpectedFound, TypeError}; @@ -142,12 +142,14 @@ pub fn relate_substs<'a, 'gcx, 'tcx, R>(relation: &mut R, let params = a_subst.iter().zip(b_subst).enumerate().map(|(i, (a, b))| { let variance = variances.map_or(ty::Invariant, |v| v[i]); - if let (Some(a_ty), Some(b_ty)) = (a.as_type(), b.as_type()) { - Ok(Kind::from(relation.relate_with_variance(variance, &a_ty, &b_ty)?)) - } else if let (Some(a_r), Some(b_r)) = (a.as_region(), b.as_region()) { - Ok(Kind::from(relation.relate_with_variance(variance, &a_r, &b_r)?)) - } else { - bug!() + match (a.unpack(), b.unpack()) { + (UnpackedKind::Lifetime(a_lt), UnpackedKind::Lifetime(b_lt)) => { + Ok(relation.relate_with_variance(variance, &a_lt, &b_lt)?.into()) + } + (UnpackedKind::Type(a_ty), UnpackedKind::Type(b_ty)) => { + Ok(relation.relate_with_variance(variance, &a_ty, &b_ty)?.into()) + } + (UnpackedKind::Lifetime(_), _) | (UnpackedKind::Type(_), _) => bug!() } }); diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 961c2650afd..4f8c9ecf080 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -15,10 +15,9 @@ use hir::def_id::DefId; use middle::const_val::ConstVal; use middle::region; use rustc_data_structures::indexed_vec::Idx; -use ty::subst::{Substs, Subst}; +use ty::subst::{Substs, Subst, Kind, UnpackedKind}; use ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable}; use ty::{Slice, TyS}; -use ty::subst::Kind; use std::iter; use std::cmp::Ordering; @@ -297,8 +296,8 @@ impl<'tcx> ClosureSubsts<'tcx> { let generics = tcx.generics_of(def_id); let parent_len = generics.parent_count(); SplitClosureSubsts { - closure_kind_ty: self.substs[parent_len].as_type().expect("CK should be a type"), - closure_sig_ty: self.substs[parent_len + 1].as_type().expect("CS should be a type"), + closure_kind_ty: self.substs.type_at(parent_len), + closure_sig_ty: self.substs.type_at(parent_len + 1), upvar_kinds: &self.substs[parent_len + 2..], } } @@ -308,7 +307,13 @@ impl<'tcx> ClosureSubsts<'tcx> { impl Iterator> + 'tcx { let SplitClosureSubsts { upvar_kinds, .. } = self.split(def_id, tcx); - upvar_kinds.iter().map(|t| t.as_type().expect("upvar should be type")) + upvar_kinds.iter().map(|t| { + if let UnpackedKind::Type(ty) = t.unpack() { + ty + } else { + bug!("upvar should be type") + } + }) } /// Returns the closure kind for this closure; may return a type @@ -620,7 +625,7 @@ impl<'a, 'gcx, 'tcx> ExistentialTraitRef<'tcx> { ty::TraitRef { def_id: self.def_id, substs: tcx.mk_substs( - iter::once(Kind::from(self_ty)).chain(self.substs.iter().cloned())) + iter::once(self_ty.into()).chain(self.substs.iter().cloned())) } } } @@ -1127,7 +1132,7 @@ impl<'a, 'tcx, 'gcx> ExistentialProjection<'tcx> { projection_ty: ty::ProjectionTy { item_def_id: self.item_def_id, substs: tcx.mk_substs( - iter::once(Kind::from(self_ty)).chain(self.substs.iter().cloned())), + iter::once(self_ty.into()).chain(self.substs.iter().cloned())), }, ty: self.ty, } diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index 7c167f69ebd..3eb859679da 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -39,15 +39,29 @@ const TAG_MASK: usize = 0b11; const TYPE_TAG: usize = 0b00; const REGION_TAG: usize = 0b01; -impl<'tcx> From> for Kind<'tcx> { - fn from(ty: Ty<'tcx>) -> Kind<'tcx> { - // Ensure we can use the tag bits. - assert_eq!(mem::align_of_val(ty) & TAG_MASK, 0); +pub enum UnpackedKind<'tcx> { + Lifetime(ty::Region<'tcx>), + Type(Ty<'tcx>), +} + +impl<'tcx> UnpackedKind<'tcx> { + fn pack(self) -> Kind<'tcx> { + let (tag, ptr) = match self { + UnpackedKind::Lifetime(lt) => { + // Ensure we can use the tag bits. + assert_eq!(mem::align_of_val(lt) & TAG_MASK, 0); + (REGION_TAG, lt as *const _ as usize) + } + UnpackedKind::Type(ty) => { + // Ensure we can use the tag bits. + assert_eq!(mem::align_of_val(ty) & TAG_MASK, 0); + (TYPE_TAG, ty as *const _ as usize) + } + }; - let ptr = ty as *const _ as usize; Kind { ptr: unsafe { - NonZero::new_unchecked(ptr | TYPE_TAG) + NonZero::new_unchecked(ptr | tag) }, marker: PhantomData } @@ -56,88 +70,62 @@ impl<'tcx> From> for Kind<'tcx> { impl<'tcx> From> for Kind<'tcx> { fn from(r: ty::Region<'tcx>) -> Kind<'tcx> { - // Ensure we can use the tag bits. - assert_eq!(mem::align_of_val(r) & TAG_MASK, 0); + UnpackedKind::Lifetime(r).pack() + } +} - let ptr = r as *const _ as usize; - Kind { - ptr: unsafe { - NonZero::new_unchecked(ptr | REGION_TAG) - }, - marker: PhantomData - } +impl<'tcx> From> for Kind<'tcx> { + fn from(ty: Ty<'tcx>) -> Kind<'tcx> { + UnpackedKind::Type(ty).pack() } } impl<'tcx> Kind<'tcx> { #[inline] - unsafe fn downcast(self, tag: usize) -> Option<&'tcx T> { + pub fn unpack(self) -> UnpackedKind<'tcx> { let ptr = self.ptr.get(); - if ptr & TAG_MASK == tag { - Some(&*((ptr & !TAG_MASK) as *const _)) - } else { - None - } - } - - #[inline] - pub fn as_type(self) -> Option> { - unsafe { - self.downcast(TYPE_TAG) - } - } - - #[inline] - pub fn as_region(self) -> Option> { - unsafe { - self.downcast(REGION_TAG) + match ptr & TAG_MASK { + REGION_TAG => unsafe { + UnpackedKind::Lifetime(&*((ptr & !TAG_MASK) as *const _)) + }, + TYPE_TAG => unsafe { + UnpackedKind::Type(&*((ptr & !TAG_MASK) as *const _)) + }, + _ => bug!("packed kind has invalid tag") } } } impl<'tcx> fmt::Debug for Kind<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if let Some(ty) = self.as_type() { - write!(f, "{:?}", ty) - } else if let Some(r) = self.as_region() { - write!(f, "{:?}", r) - } else { - write!(f, "", self.ptr.get() as *const ()) + match self.unpack() { + UnpackedKind::Lifetime(lt) => write!(f, "{:?}", lt), + UnpackedKind::Type(ty) => write!(f, "{:?}", ty), } } } impl<'tcx> fmt::Display for Kind<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if let Some(ty) = self.as_type() { - write!(f, "{}", ty) - } else if let Some(r) = self.as_region() { - write!(f, "{}", r) - } else { - // FIXME(RFC 2000): extend this if/else chain when we support const generic. - unimplemented!(); + match self.unpack() { + UnpackedKind::Lifetime(lt) => write!(f, "{}", lt), + UnpackedKind::Type(ty) => write!(f, "{}", ty), } } } impl<'tcx> TypeFoldable<'tcx> for Kind<'tcx> { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - if let Some(ty) = self.as_type() { - Kind::from(ty.fold_with(folder)) - } else if let Some(r) = self.as_region() { - Kind::from(r.fold_with(folder)) - } else { - bug!() + match self.unpack() { + UnpackedKind::Lifetime(lt) => lt.fold_with(folder).into(), + UnpackedKind::Type(ty) => ty.fold_with(folder).into(), } } fn super_visit_with>(&self, visitor: &mut V) -> bool { - if let Some(ty) = self.as_type() { - ty.visit_with(visitor) - } else if let Some(r) = self.as_region() { - r.visit_with(visitor) - } else { - bug!() + match self.unpack() { + UnpackedKind::Lifetime(lt) => lt.visit_with(visitor), + UnpackedKind::Type(ty) => ty.visit_with(visitor), } } } @@ -145,16 +133,17 @@ impl<'tcx> TypeFoldable<'tcx> for Kind<'tcx> { impl<'tcx> Encodable for Kind<'tcx> { fn encode(&self, e: &mut E) -> Result<(), E::Error> { e.emit_enum("Kind", |e| { - if let Some(ty) = self.as_type() { - e.emit_enum_variant("Ty", TYPE_TAG, 1, |e| { - e.emit_enum_variant_arg(0, |e| ty.encode(e)) - }) - } else if let Some(r) = self.as_region() { - e.emit_enum_variant("Region", REGION_TAG, 1, |e| { - e.emit_enum_variant_arg(0, |e| r.encode(e)) - }) - } else { - bug!() + match self.unpack() { + UnpackedKind::Lifetime(lt) => { + e.emit_enum_variant("Region", REGION_TAG, 1, |e| { + e.emit_enum_variant_arg(0, |e| lt.encode(e)) + }) + } + UnpackedKind::Type(ty) => { + e.emit_enum_variant("Ty", TYPE_TAG, 1, |e| { + e.emit_enum_variant_arg(0, |e| ty.encode(e)) + }) + } } }) } @@ -247,7 +236,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { let def = types.next().unwrap(); let ty = mk_type(def, substs); assert_eq!(def.index as usize, substs.len()); - substs.push(Kind::from(ty)); + substs.push(ty.into()); } for def in &defs.regions { @@ -269,26 +258,42 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { #[inline] pub fn types(&'a self) -> impl DoubleEndedIterator> + 'a { - self.iter().filter_map(|k| k.as_type()) + self.iter().filter_map(|k| { + if let UnpackedKind::Type(ty) = k.unpack() { + Some(ty) + } else { + None + } + }) } #[inline] pub fn regions(&'a self) -> impl DoubleEndedIterator> + 'a { - self.iter().filter_map(|k| k.as_region()) + self.iter().filter_map(|k| { + if let UnpackedKind::Lifetime(lt) = k.unpack() { + Some(lt) + } else { + None + } + }) } #[inline] pub fn type_at(&self, i: usize) -> Ty<'tcx> { - self[i].as_type().unwrap_or_else(|| { + if let UnpackedKind::Type(ty) = self[i].unpack() { + ty + } else { bug!("expected type for param #{} in {:?}", i, self); - }) + } } #[inline] pub fn region_at(&self, i: usize) -> ty::Region<'tcx> { - self[i].as_region().unwrap_or_else(|| { + if let UnpackedKind::Lifetime(lt) = self[i].unpack() { + lt + } else { bug!("expected region for param #{} in {:?}", i, self); - }) + } } #[inline] @@ -413,13 +418,12 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for SubstFolder<'a, 'gcx, 'tcx> { // the specialized routine `ty::replace_late_regions()`. match *r { ty::ReEarlyBound(data) => { - let r = self.substs.get(data.index as usize) - .and_then(|k| k.as_region()); + let r = self.substs.get(data.index as usize).map(|k| k.unpack()); match r { - Some(r) => { - self.shift_region_through_binders(r) + Some(UnpackedKind::Lifetime(lt)) => { + self.shift_region_through_binders(lt) } - None => { + _ => { let span = self.span.unwrap_or(DUMMY_SP); span_bug!( span, @@ -470,11 +474,10 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for SubstFolder<'a, 'gcx, 'tcx> { impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> { fn ty_for_param(&self, p: ty::ParamTy, source_ty: Ty<'tcx>) -> Ty<'tcx> { // Look up the type in the substitutions. It really should be in there. - let opt_ty = self.substs.get(p.idx as usize) - .and_then(|k| k.as_type()); + let opt_ty = self.substs.get(p.idx as usize).map(|k| k.unpack()); let ty = match opt_ty { - Some(t) => t, - None => { + Some(UnpackedKind::Type(ty)) => ty, + _ => { let span = self.span.unwrap_or(DUMMY_SP); span_bug!( span, @@ -600,7 +603,7 @@ impl<'a, 'gcx, 'tcx> ty::PolyExistentialTraitRef<'tcx> { ty::TraitRef { def_id: trait_ref.def_id, substs: tcx.mk_substs( - iter::once(Kind::from(self_ty)).chain(trait_ref.substs.iter().cloned())) + iter::once(self_ty.into()).chain(trait_ref.substs.iter().cloned())) } }) } diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 34f05232adc..110808919e9 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -19,7 +19,7 @@ use middle::const_val::ConstVal; use traits::{self, Reveal}; use ty::{self, Ty, TyCtxt, TypeFoldable}; use ty::fold::TypeVisitor; -use ty::subst::{Subst, Kind}; +use ty::subst::{Subst, UnpackedKind}; use ty::TypeVariants::*; use util::common::ErrorReported; use middle::lang_items; @@ -509,16 +509,20 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let result = item_substs.iter().zip(impl_substs.iter()) .filter(|&(_, &k)| { - if let Some(&ty::RegionKind::ReEarlyBound(ref ebr)) = k.as_region() { - !impl_generics.region_param(ebr, self).pure_wrt_drop - } else if let Some(&ty::TyS { - sty: ty::TypeVariants::TyParam(ref pt), .. - }) = k.as_type() { - !impl_generics.type_param(pt, self).pure_wrt_drop - } else { - // not a type or region param - this should be reported - // as an error. - false + match k.unpack() { + UnpackedKind::Lifetime(&ty::RegionKind::ReEarlyBound(ref ebr)) => { + !impl_generics.region_param(ebr, self).pure_wrt_drop + } + UnpackedKind::Type(&ty::TyS { + sty: ty::TypeVariants::TyParam(ref pt), .. + }) => { + !impl_generics.type_param(pt, self).pure_wrt_drop + } + UnpackedKind::Lifetime(_) | UnpackedKind::Type(_) => { + // not a type or region param - this should be reported + // as an error. + false + } } }).map(|(&item_param, _)| item_param).collect(); debug!("destructor_constraint({:?}) = {:?}", def.did, result); @@ -596,7 +600,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // Objects must be alive in order for their destructor // to be called. ty::TyDynamic(..) => Ok(ty::DtorckConstraint { - outlives: vec![Kind::from(ty)], + outlives: vec![ty.into()], dtorck_types: vec![], }), diff --git a/src/librustc_const_eval/_match.rs b/src/librustc_const_eval/_match.rs index e30f5cb4f12..54e3418d4f0 100644 --- a/src/librustc_const_eval/_match.rs +++ b/src/librustc_const_eval/_match.rs @@ -878,7 +878,7 @@ fn constructor_sub_pattern_tys<'a, 'tcx: 'a>(cx: &MatchCheckCtxt<'a, 'tcx>, ty::TyAdt(adt, substs) => { if adt.is_box() { // Use T as the sub pattern type of Box. - vec![substs[0].as_type().unwrap()] + vec![substs.type_at(0)] } else { adt.variants[ctor.variant_index_for_adt(adt)].fields.iter().map(|field| { let is_visible = adt.is_enum() diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 306e7e9c16d..35d2205cf33 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -17,7 +17,7 @@ use driver; use rustc_lint; use rustc_resolve::MakeGlobMap; use rustc::middle::region; -use rustc::ty::subst::{Kind, Subst}; +use rustc::ty::subst::Subst; use rustc::traits::{ObligationCause, Reveal}; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc::ty::maps::OnDiskCache; @@ -468,7 +468,7 @@ fn subst_ty_renumber_bound() { env.t_fn(&[t_param], env.t_nil()) }; - let substs = env.infcx.tcx.intern_substs(&[Kind::from(t_rptr_bound1)]); + let substs = env.infcx.tcx.intern_substs(&[t_rptr_bound1.into()]); let t_substituted = t_source.subst(env.infcx.tcx, substs); // t_expected = fn(&'a isize) @@ -503,7 +503,7 @@ fn subst_ty_renumber_some_bounds() { env.t_pair(t_param, env.t_fn(&[t_param], env.t_nil())) }; - let substs = env.infcx.tcx.intern_substs(&[Kind::from(t_rptr_bound1)]); + let substs = env.infcx.tcx.intern_substs(&[t_rptr_bound1.into()]); let t_substituted = t_source.subst(env.infcx.tcx, substs); // t_expected = (&'a isize, fn(&'a isize)) @@ -565,7 +565,7 @@ fn subst_region_renumber_region() { env.t_fn(&[env.t_rptr(re_early)], env.t_nil()) }; - let substs = env.infcx.tcx.intern_substs(&[Kind::from(re_bound1)]); + let substs = env.infcx.tcx.intern_substs(&[re_bound1.into()]); let t_substituted = t_source.subst(env.infcx.tcx, substs); // t_expected = fn(&'a isize) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 3578164feb7..08c16fed5dd 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -7,7 +7,7 @@ use rustc::middle::const_val::ConstVal; use rustc::mir; use rustc::traits::Reveal; use rustc::ty::layout::{self, Size, Align, HasDataLayout, LayoutOf, TyLayout}; -use rustc::ty::subst::{Subst, Substs, Kind}; +use rustc::ty::subst::{Subst, Substs}; use rustc::ty::{self, Ty, TyCtxt}; use rustc_data_structures::indexed_vec::Idx; use syntax::codemap::{self, DUMMY_SP}; @@ -1663,6 +1663,6 @@ pub fn resolve_drop_in_place<'a, 'tcx>( ty: Ty<'tcx>, ) -> ty::Instance<'tcx> { let def_id = tcx.require_lang_item(::rustc::middle::lang_items::DropInPlaceFnLangItem); - let substs = tcx.intern_substs(&[Kind::from(ty)]); + let substs = tcx.intern_substs(&[ty.into()]); ty::Instance::resolve(tcx, ty::ParamEnv::empty(Reveal::All), def_id, substs).unwrap() } diff --git a/src/librustc_mir/monomorphize/mod.rs b/src/librustc_mir/monomorphize/mod.rs index 95ebb6c970a..2ca6c76a800 100644 --- a/src/librustc_mir/monomorphize/mod.rs +++ b/src/librustc_mir/monomorphize/mod.rs @@ -92,7 +92,7 @@ fn fn_once_adapter_instance<'a, 'tcx>( assert_eq!(sig.inputs().len(), 1); let substs = tcx.mk_substs([ Kind::from(self_ty), - Kind::from(sig.inputs()[0]), + sig.inputs()[0].into(), ].iter().cloned()); debug!("fn_once_adapter_shim: self_ty={:?} sig={:?}", self_ty, sig); @@ -153,7 +153,7 @@ pub fn resolve_drop_in_place<'a, 'tcx>( -> ty::Instance<'tcx> { let def_id = tcx.require_lang_item(DropInPlaceFnLangItem); - let substs = tcx.intern_substs(&[Kind::from(ty)]); + let substs = tcx.intern_substs(&[ty.into()]); Instance::resolve(tcx, ty::ParamEnv::empty(traits::Reveal::All), def_id, substs).unwrap() } diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 812665f5fa4..04ebaa031fe 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -65,7 +65,7 @@ use rustc::middle::const_val::ConstVal; use rustc::mir::*; use rustc::mir::visit::{PlaceContext, Visitor, MutVisitor}; use rustc::ty::{self, TyCtxt, AdtDef, Ty, GeneratorInterior}; -use rustc::ty::subst::{Kind, Substs}; +use rustc::ty::subst::Substs; use util::dump_mir; use util::liveness::{self, LivenessMode}; use rustc_const_math::ConstInt; @@ -858,8 +858,8 @@ impl MirPass for StateTransform { // Compute GeneratorState let state_did = tcx.lang_items().gen_state().unwrap(); let state_adt_ref = tcx.adt_def(state_did); - let state_substs = tcx.mk_substs([Kind::from(yield_ty), - Kind::from(mir.return_ty())].iter()); + let state_substs = tcx.mk_substs([yield_ty.into(), + mir.return_ty().into()].iter()); let ret_ty = tcx.mk_adt(state_adt_ref, state_substs); // We rename RETURN_PLACE which has type mir.return_ty to new_ret_local diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index 9e745c3a1f5..37bd225a7d9 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -28,7 +28,6 @@ use value::Value; use rustc::traits; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::layout::{HasDataLayout, LayoutOf}; -use rustc::ty::subst::Kind; use rustc::hir; use libc::{c_uint, c_char}; @@ -413,8 +412,8 @@ pub fn ty_fn_sig<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, sig.map_bound(|sig| { let state_did = tcx.lang_items().gen_state().unwrap(); let state_adt_ref = tcx.adt_def(state_did); - let state_substs = tcx.mk_substs([Kind::from(sig.yield_ty), - Kind::from(sig.return_ty)].iter()); + let state_substs = tcx.mk_substs([sig.yield_ty.into(), + sig.return_ty.into()].iter()); let ret_ty = tcx.mk_adt(state_adt_ref, state_substs); tcx.mk_fn_sig(iter::once(env_ty), diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 1139ea5fbd3..650e5305198 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -19,7 +19,7 @@ use hir::def::Def; use hir::def_id::DefId; use middle::resolve_lifetime as rl; use namespace::Namespace; -use rustc::ty::subst::{Kind, Subst, Substs}; +use rustc::ty::subst::{Kind, UnpackedKind, Subst, Substs}; use rustc::traits; use rustc::ty::{self, RegionKind, Ty, TyCtxt, ToPredicate, TypeFoldable}; use rustc::ty::wf::object_region_bounds; @@ -1136,7 +1136,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { // Replace all lifetimes with 'static for subst in &mut substs { - if let Some(_) = subst.as_region() { + if let UnpackedKind::Lifetime(_) = subst.unpack() { *subst = Kind::from(&RegionKind::ReStatic); } } @@ -1146,8 +1146,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { // Fill in our own generics with the resolved lifetimes assert_eq!(lifetimes.len(), generics.own_count()); - substs.extend(lifetimes.iter().map(|lt| - Kind::from(self.ast_region_to_region(lt, None)))); + substs.extend(lifetimes.iter().map(|lt| Kind::from(self.ast_region_to_region(lt, None)))); debug!("impl_trait_ty_to_ty: final substs = {:?}", substs); diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 4aed688027f..039669a62e1 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -14,7 +14,7 @@ use hir::def_id::DefId; use rustc::infer::{self, InferOk}; use rustc::infer::outlives::env::OutlivesEnvironment; use rustc::middle::region; -use rustc::ty::subst::{Subst, Substs}; +use rustc::ty::subst::{Subst, Substs, UnpackedKind}; use rustc::ty::{self, Ty, TyCtxt}; use rustc::traits::{self, Reveal, ObligationCause}; use util::common::ErrorReported; @@ -331,10 +331,9 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'gcx, 'tcx>( } for outlive in outlives { - if let Some(r) = outlive.as_region() { - rcx.sub_regions(origin(), parent_scope, r); - } else if let Some(ty) = outlive.as_type() { - rcx.type_must_outlive(origin(), ty, parent_scope); + match outlive.unpack() { + UnpackedKind::Lifetime(lt) => rcx.sub_regions(origin(), parent_scope, lt), + UnpackedKind::Type(ty) => rcx.type_must_outlive(origin(), ty, parent_scope), } } } diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index f7e10a4a47d..44ac7a10e82 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -14,7 +14,7 @@ //! We walk the set of items and, for each member, generate new constraints. use hir::def_id::DefId; -use rustc::ty::subst::Substs; +use rustc::ty::subst::{Substs, UnpackedKind}; use rustc::ty::{self, Ty, TyCtxt}; use syntax::ast; use rustc::hir; @@ -381,12 +381,13 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { debug!("add_constraints_from_substs: variance_decl={:?} variance_i={:?}", variance_decl, variance_i); - if let Some(ty) = k.as_type() { - self.add_constraints_from_ty(current, ty, variance_i); - } else if let Some(r) = k.as_region() { - self.add_constraints_from_region(current, r, variance_i); - } else { - bug!(); + match k.unpack() { + UnpackedKind::Lifetime(lt) => { + self.add_constraints_from_region(current, lt, variance_i) + } + UnpackedKind::Type(ty) => { + self.add_constraints_from_ty(current, ty, variance_i) + } } } }