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.
This commit is contained in:
varkor 2018-02-23 01:13:54 +00:00
parent b1f8e6fb06
commit 8b2037c6fe
17 changed files with 175 additions and 154 deletions

View File

@ -56,8 +56,19 @@ for ty::subst::Kind<'gcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'gcx>,
hasher: &mut StableHasher<W>) {
self.as_type().hash_stable(hcx, hasher);
self.as_region().hash_stable(hcx, hasher);
self.unpack().hash_stable(hcx, hasher);
}
}
impl<'gcx> HashStable<StableHashingContext<'gcx>>
for ty::subst::UnpackedKind<'gcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'gcx>,
hasher: &mut StableHasher<W>) {
match self {
ty::subst::UnpackedKind::Lifetime(lt) => lt.hash_stable(hcx, hasher),
ty::subst::UnpackedKind::Type(ty) => ty.hash_stable(hcx, hasher),
}
}
}

View File

@ -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<AnonTypeDecl<'tcx>>;
@ -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

View File

@ -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
}

View File

@ -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 }

View File

@ -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!()
}
});

View File

@ -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<Item=Ty<'tcx>> + '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,
}

View File

@ -39,15 +39,29 @@ const TAG_MASK: usize = 0b11;
const TYPE_TAG: usize = 0b00;
const REGION_TAG: usize = 0b01;
impl<'tcx> From<Ty<'tcx>> 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<Ty<'tcx>> for Kind<'tcx> {
impl<'tcx> From<ty::Region<'tcx>> 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<Ty<'tcx>> for Kind<'tcx> {
fn from(ty: Ty<'tcx>) -> Kind<'tcx> {
UnpackedKind::Type(ty).pack()
}
}
impl<'tcx> Kind<'tcx> {
#[inline]
unsafe fn downcast<T>(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<Ty<'tcx>> {
unsafe {
self.downcast(TYPE_TAG)
}
}
#[inline]
pub fn as_region(self) -> Option<ty::Region<'tcx>> {
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, "<unknown @ {:p}>", 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<V: TypeVisitor<'tcx>>(&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<E: Encoder>(&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<Item=Ty<'tcx>> + '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<Item=ty::Region<'tcx>> + '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()))
}
})
}

View File

@ -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![],
}),

View File

@ -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<T>.
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()

View File

@ -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)

View File

@ -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()
}

View File

@ -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()
}

View File

@ -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<yield_ty, return_ty>
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

View File

@ -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),

View File

@ -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);

View File

@ -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),
}
}
}

View File

@ -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)
}
}
}
}