add tcx
to fn walk
This commit is contained in:
parent
bfaf13af4e
commit
cc47998e28
29 changed files with 73 additions and 67 deletions
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue