Folding revamp.
This commit makes type folding more like the way chalk does it. Currently, `TypeFoldable` has `fold_with` and `super_fold_with` methods. - `fold_with` is the standard entry point, and defaults to calling `super_fold_with`. - `super_fold_with` does the actual work of traversing a type. - For a few types of interest (`Ty`, `Region`, etc.) `fold_with` instead calls into a `TypeFolder`, which can then call back into `super_fold_with`. With the new approach, `TypeFoldable` has `fold_with` and `TypeSuperFoldable` has `super_fold_with`. - `fold_with` is still the standard entry point, *and* it does the actual work of traversing a type, for all types except types of interest. - `super_fold_with` is only implemented for the types of interest. Benefits of the new model. - I find it easier to understand. The distinction between types of interest and other types is clearer, and `super_fold_with` doesn't exist for most types. - With the current model is easy to get confused and implement a `super_fold_with` method that should be left defaulted. (Some of the precursor commits fixed such cases.) - With the current model it's easy to call `super_fold_with` within `TypeFolder` impls where `fold_with` should be called. The new approach makes this mistake impossible, and this commit fixes a number of such cases. - It's potentially faster, because it avoids the `fold_with` -> `super_fold_with` call in all cases except types of interest. A lot of the time the compile would inline those away, but not necessarily always.
This commit is contained in:
parent
7480b501b4
commit
90db033955
47 changed files with 292 additions and 337 deletions
|
@ -12,7 +12,7 @@ use rustc_data_structures::sso::SsoHashMap;
|
|||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_infer::traits::Normalized;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder};
|
||||
use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable};
|
||||
use rustc_middle::ty::subst::Subst;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor};
|
||||
|
||||
|
@ -205,7 +205,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
|||
Reveal::UserFacing => ty.try_super_fold_with(self),
|
||||
|
||||
Reveal::All => {
|
||||
let substs = substs.try_super_fold_with(self)?;
|
||||
let substs = substs.try_fold_with(self)?;
|
||||
let recursion_limit = self.tcx().recursion_limit();
|
||||
if !recursion_limit.value_within_limit(self.anon_depth) {
|
||||
let obligation = Obligation::with_depth(
|
||||
|
@ -242,7 +242,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
|||
// we don't need to replace them with placeholders (see branch below).
|
||||
|
||||
let tcx = self.infcx.tcx;
|
||||
let data = data.try_super_fold_with(self)?;
|
||||
let data = data.try_fold_with(self)?;
|
||||
|
||||
let mut orig_values = OriginalQueryValues::default();
|
||||
// HACK(matthewjasper) `'static` is special-cased in selection,
|
||||
|
@ -281,7 +281,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
|||
&mut self.universes,
|
||||
data,
|
||||
);
|
||||
let data = data.try_super_fold_with(self)?;
|
||||
let data = data.try_fold_with(self)?;
|
||||
|
||||
let mut orig_values = OriginalQueryValues::default();
|
||||
// HACK(matthewjasper) `'static` is special-cased in selection,
|
||||
|
@ -334,7 +334,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
|||
&mut self,
|
||||
constant: mir::ConstantKind<'tcx>,
|
||||
) -> Result<mir::ConstantKind<'tcx>, Self::Error> {
|
||||
let constant_kind = match constant {
|
||||
Ok(match constant {
|
||||
mir::ConstantKind::Ty(c) => {
|
||||
let const_folded = c.try_fold_with(self)?;
|
||||
match const_folded.val() {
|
||||
|
@ -347,8 +347,6 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
|||
}
|
||||
}
|
||||
mir::ConstantKind::Val(_, _) => constant.try_super_fold_with(self)?,
|
||||
};
|
||||
|
||||
Ok(constant_kind)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue