1
Fork 0

add tcx to fn walk

This commit is contained in:
lcnr 2021-07-17 16:43:23 +02:00
parent bfaf13af4e
commit cc47998e28
29 changed files with 73 additions and 67 deletions

View file

@ -194,7 +194,7 @@ fn compute_components_recursive(
out: &mut SmallVec<[Component<'tcx>; 4]>,
visited: &mut SsoHashSet<GenericArg<'tcx>>,
) {
for child in parent.walk_shallow(visited) {
for child in parent.walk_shallow(tcx, visited) {
match child.unpack() {
GenericArgKind::Type(ty) => {
compute_components(tcx, ty, out, visited);

View file

@ -1,8 +1,8 @@
//! An iterator over the type substructure.
//! WARNING: this does not keep track of the region depth.
use crate::ty;
use crate::ty::subst::{GenericArg, GenericArgKind};
use crate::ty::{self, TyCtxt};
use rustc_data_structures::sso::SsoHashSet;
use smallvec::{self, SmallVec};
@ -11,6 +11,7 @@ use smallvec::{self, SmallVec};
type TypeWalkerStack<'tcx> = SmallVec<[GenericArg<'tcx>; 8]>;
pub struct TypeWalker<'tcx> {
tcx: TyCtxt<'tcx>,
stack: TypeWalkerStack<'tcx>,
last_subtree: usize,
pub visited: SsoHashSet<GenericArg<'tcx>>,
@ -25,8 +26,8 @@ pub struct TypeWalker<'tcx> {
/// It maintains a set of visited types and
/// skips any types that are already there.
impl<'tcx> TypeWalker<'tcx> {
pub fn new(root: GenericArg<'tcx>) -> Self {
Self { stack: smallvec![root], last_subtree: 1, visited: SsoHashSet::new() }
fn new(tcx: TyCtxt<'tcx>, root: GenericArg<'tcx>) -> Self {
Self { tcx, stack: smallvec![root], last_subtree: 1, visited: SsoHashSet::new() }
}
/// Skips the subtree corresponding to the last type
@ -55,7 +56,7 @@ impl<'tcx> Iterator for TypeWalker<'tcx> {
let next = self.stack.pop()?;
self.last_subtree = self.stack.len();
if self.visited.insert(next) {
push_inner(&mut self.stack, next);
push_inner(self.tcx, &mut self.stack, next);
debug!("next: stack={:?}", self.stack);
return Some(next);
}
@ -74,8 +75,8 @@ impl GenericArg<'tcx> {
/// Foo<Bar<isize>> => { Foo<Bar<isize>>, Bar<isize>, isize }
/// [isize] => { [isize], isize }
/// ```
pub fn walk(self) -> TypeWalker<'tcx> {
TypeWalker::new(self)
pub fn walk(self, tcx: TyCtxt<'tcx>) -> TypeWalker<'tcx> {
TypeWalker::new(tcx, self)
}
/// Iterator that walks the immediate children of `self`. Hence
@ -87,10 +88,11 @@ impl GenericArg<'tcx> {
/// and skips any types that are already there.
pub fn walk_shallow(
self,
tcx: TyCtxt<'tcx>,
visited: &mut SsoHashSet<GenericArg<'tcx>>,
) -> impl Iterator<Item = GenericArg<'tcx>> {
let mut stack = SmallVec::new();
push_inner(&mut stack, self);
push_inner(tcx, &mut stack, self);
stack.retain(|a| visited.insert(*a));
stack.into_iter()
}
@ -107,18 +109,22 @@ impl<'tcx> super::TyS<'tcx> {
/// Foo<Bar<isize>> => { Foo<Bar<isize>>, Bar<isize>, isize }
/// [isize] => { [isize], isize }
/// ```
pub fn walk(&'tcx self) -> TypeWalker<'tcx> {
TypeWalker::new(self.into())
pub fn walk(&'tcx self, tcx: TyCtxt<'tcx>) -> TypeWalker<'tcx> {
TypeWalker::new(tcx, self.into())
}
}
// We push `GenericArg`s on the stack in reverse order so as to
// maintain a pre-order traversal. As of the time of this
// writing, the fact that the traversal is pre-order is not
// known to be significant to any code, but it seems like the
// natural order one would expect (basically, the order of the
// types as they are written).
fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>) {
/// We push `GenericArg`s on the stack in reverse order so as to
/// maintain a pre-order traversal. As of the time of this
/// writing, the fact that the traversal is pre-order is not
/// known to be significant to any code, but it seems like the
/// natural order one would expect (basically, the order of the
/// types as they are written).
fn push_inner<'tcx>(
tcx: TyCtxt<'tcx>,
stack: &mut TypeWalkerStack<'tcx>,
parent: GenericArg<'tcx>,
) {
match parent.unpack() {
GenericArgKind::Type(parent_ty) => match *parent_ty.kind() {
ty::Bool
@ -196,8 +202,7 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
| ty::ConstKind::Error(_) => {}
ty::ConstKind::Unevaluated(ct) => {
// TODO
stack.extend(ct.substs_.unwrap().iter().rev());
stack.extend(ct.substs(tcx).iter().rev());
}
}
}