Skip to content

Commit

Permalink
Introduce UnpackedKind
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
varkor committed Feb 23, 2018
1 parent b1f8e6f commit 8b2037c
Show file tree
Hide file tree
Showing 17 changed files with 175 additions and 154 deletions.
15 changes: 13 additions & 2 deletions src/librustc/ich/impls_ty.rs
Expand Up @@ -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),
}
}
}

Expand Down
7 changes: 4 additions & 3 deletions src/librustc/infer/anon_types/mod.rs
Expand Up @@ -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>>;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/traits/select.rs
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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
}
Expand Down
5 changes: 1 addition & 4 deletions src/librustc/ty/instance.rs
Expand Up @@ -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 }
Expand Down
16 changes: 9 additions & 7 deletions src/librustc/ty/relate.rs
Expand Up @@ -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};
Expand Down Expand Up @@ -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!()
}
});

Expand Down
19 changes: 12 additions & 7 deletions src/librustc/ty/sty.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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..],
}
}
Expand All @@ -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
Expand Down Expand Up @@ -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()))
}
}
}
Expand Down Expand Up @@ -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,
}
Expand Down

0 comments on commit 8b2037c

Please sign in to comment.