1
Fork 0
This commit is contained in:
lcnr 2020-10-24 09:27:15 +02:00 committed by Bastian Kauschke
parent 80acfea5a7
commit a6cbd64dae
19 changed files with 87 additions and 105 deletions

View file

@ -13,7 +13,6 @@ use rustc_hir::def::Namespace;
use rustc_hir::def_id::CRATE_DEF_INDEX;
use rustc_index::vec::{Idx, IndexVec};
use smallvec::SmallVec;
use std::fmt;
use std::ops::ControlFlow;
use std::rc::Rc;
@ -275,7 +274,7 @@ impl fmt::Debug for ty::PredicateAtom<'tcx> {
// For things that don't carry any arena-allocated data (and are
// copy...), just add them to this list.
CloneTypeFoldableAndLiftImpls! {
TrivialTypeFoldableAndLiftImpls! {
(),
bool,
usize,
@ -846,7 +845,7 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<T> {
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::ExistentialPredicate<'tcx>> {
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
fold_list(self, folder, |tcx, v| tcx.intern_existential_predicates(v))
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_existential_predicates(v))
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<()> {
@ -856,7 +855,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::ExistentialPredicate<'tcx>>
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
fold_list(self, folder, |tcx, v| tcx.intern_type_list(v))
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_type_list(v))
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<()> {
@ -866,7 +865,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind> {
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
fold_list(self, folder, |tcx, v| tcx.intern_projs(v))
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_projs(v))
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<()> {
@ -928,25 +927,25 @@ impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> {
impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
let kind = match self.kind() {
let kind = match *self.kind() {
ty::RawPtr(tm) => ty::RawPtr(tm.fold_with(folder)),
ty::Array(typ, sz) => ty::Array(typ.fold_with(folder), sz.fold_with(folder)),
ty::Slice(typ) => ty::Slice(typ.fold_with(folder)),
ty::Adt(tid, substs) => ty::Adt(*tid, substs.fold_with(folder)),
ty::Dynamic(ref trait_ty, ref region) => {
ty::Adt(tid, substs) => ty::Adt(tid, substs.fold_with(folder)),
ty::Dynamic(trait_ty, region) => {
ty::Dynamic(trait_ty.fold_with(folder), region.fold_with(folder))
}
ty::Tuple(ts) => ty::Tuple(ts.fold_with(folder)),
ty::FnDef(def_id, substs) => ty::FnDef(*def_id, substs.fold_with(folder)),
ty::FnDef(def_id, substs) => ty::FnDef(def_id, substs.fold_with(folder)),
ty::FnPtr(f) => ty::FnPtr(f.fold_with(folder)),
ty::Ref(ref r, ty, mutbl) => ty::Ref(r.fold_with(folder), ty.fold_with(folder), *mutbl),
ty::Ref(r, ty, mutbl) => ty::Ref(r.fold_with(folder), ty.fold_with(folder), mutbl),
ty::Generator(did, substs, movability) => {
ty::Generator(*did, substs.fold_with(folder), *movability)
ty::Generator(did, substs.fold_with(folder), movability)
}
ty::GeneratorWitness(types) => ty::GeneratorWitness(types.fold_with(folder)),
ty::Closure(did, substs) => ty::Closure(*did, substs.fold_with(folder)),
ty::Projection(ref data) => ty::Projection(data.fold_with(folder)),
ty::Opaque(did, substs) => ty::Opaque(*did, substs.fold_with(folder)),
ty::Closure(did, substs) => ty::Closure(did, substs.fold_with(folder)),
ty::Projection(data) => ty::Projection(data.fold_with(folder)),
ty::Opaque(did, substs) => ty::Opaque(did, substs.fold_with(folder)),
ty::Bool
| ty::Char
@ -1060,7 +1059,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> {
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
fold_list(self, folder, |tcx, v| tcx.intern_predicates(v))
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_predicates(v))
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<()> {
@ -1140,34 +1139,3 @@ impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> {
ControlFlow::CONTINUE
}
}
// Does the equivalent of
// ```
// let v = self.iter().map(|p| p.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
// folder.tcx().intern_*(&v)
// ```
fn fold_list<'tcx, F, T>(
list: &'tcx ty::List<T>,
folder: &mut F,
intern: impl FnOnce(TyCtxt<'tcx>, &[T]) -> &'tcx ty::List<T>,
) -> &'tcx ty::List<T>
where
F: TypeFolder<'tcx>,
T: TypeFoldable<'tcx> + PartialEq + Copy,
{
let mut iter = list.iter();
// Look for the first element that changed
if let Some((i, new_t)) = iter.by_ref().enumerate().find_map(|(i, t)| {
let new_t = t.fold_with(folder);
if new_t == t { None } else { Some((i, new_t)) }
}) {
// An element changed, prepare to intern the resulting list
let mut new_list = SmallVec::<[_; 8]>::with_capacity(list.len());
new_list.extend_from_slice(&list[..i]);
new_list.push(new_t);
new_list.extend(iter.map(|t| t.fold_with(folder)));
intern(folder.tcx(), &new_list)
} else {
list
}
}