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:
parent
b1f8e6fb06
commit
8b2037c6fe
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 }
|
||||
|
@ -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!()
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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()))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -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![],
|
||||
}),
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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),
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user