fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) {
    match parent_ty.sty {
        ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) |
        ty::Str | ty::Infer(_) | ty::Param(_) | ty::Never | ty::Error |
        ty::Foreign(..) => {
        }
        ty::Array(ty, len) => {
            push_const(stack, len);
            stack.push(ty);
        }
        ty::Slice(ty) => {
            stack.push(ty);
        }
        ty::RawPtr(ref mt) => {
            stack.push(mt.ty);
        }
        ty::Ref(_, ty, _) => {
            stack.push(ty);
        }
        ty::Projection(ref data) => {
            stack.extend(data.substs.types().rev());
        }
        ty::Dynamic(ref obj, ..) => {
            stack.extend(obj.iter().rev().flat_map(|predicate| {
                let (substs, opt_ty) = match *predicate.skip_binder() {
                    ty::ExistentialPredicate::Trait(tr) => (tr.substs, None),
                    ty::ExistentialPredicate::Projection(p) =>
                        (p.substs, Some(p.ty)),
                    ty::ExistentialPredicate::AutoTrait(_) =>
                        // Empty iterator
                        (ty::Substs::empty(), None),
                };

                substs.types().rev().chain(opt_ty)
            }));
        }
        ty::Adt(_, substs) | ty::Opaque(_, substs) => {
            stack.extend(substs.types().rev());
        }
        ty::Closure(_, ref substs) => {
            stack.extend(substs.substs.types().rev());
        }
        ty::Generator(_, ref substs, _) => {
            stack.extend(substs.substs.types().rev());
        }
        ty::GeneratorWitness(ts) => {
            stack.extend(ts.skip_binder().iter().cloned().rev());
        }
        ty::Tuple(ts) => {
            stack.extend(ts.iter().cloned().rev());
        }
        ty::FnDef(_, substs) => {
            stack.extend(substs.types().rev());
        }
        ty::FnPtr(sig) => {
            stack.push(sig.skip_binder().output());
            stack.extend(sig.skip_binder().inputs().iter().cloned().rev());
        }
    }
}
// We push types 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).
We push types 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).
We push types 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_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) {
    match parent_ty.sty {
        ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) |
        ty::Str | ty::Infer(_) | ty::Param(_) | ty::Never | ty::Error |
        ty::Foreign(..) => {
        }
        ty::Array(ty, len) => {
            push_const(stack, len);
            stack.push(ty);
        }
        ty::Slice(ty) => {
            stack.push(ty);
        }
        ty::RawPtr(ref mt) => {
            stack.push(mt.ty);
        }
        ty::Ref(_, ty, _) => {
            stack.push(ty);
        }
        ty::Projection(ref data) => {
            stack.extend(data.substs.types().rev());
        }
        ty::Dynamic(ref obj, ..) => {
            stack.extend(obj.iter().rev().flat_map(|predicate| {
                let (substs, opt_ty) = match *predicate.skip_binder() {
                    ty::ExistentialPredicate::Trait(tr) => (tr.substs, None),
                    ty::ExistentialPredicate::Projection(p) =>
                        (p.substs, Some(p.ty)),
                    ty::ExistentialPredicate::AutoTrait(_) =>
                        // Empty iterator
                        (ty::Substs::empty(), None),
                };
                substs.types().rev().chain(opt_ty)
            }));
        }
        ty::Adt(_, substs) | ty::Opaque(_, substs) => {
            stack.extend(substs.types().rev());
        }
        ty::Closure(_, ref substs) => {
            stack.extend(substs.substs.types().rev());
        }
        ty::Generator(_, ref substs, _) => {
            stack.extend(substs.substs.types().rev());
        }
        ty::GeneratorWitness(ts) => {
            stack.extend(ts.skip_binder().iter().cloned().rev());
        }
        ty::Tuple(ts) => {
            stack.extend(ts.iter().cloned().rev());
        }
        ty::FnDef(_, substs) => {
            stack.extend(substs.types().rev());
        }
        ty::FnPtr(sig) => {
            stack.push(sig.skip_binder().output());
            stack.extend(sig.skip_binder().inputs().iter().cloned().rev());
        }
    }
}
fn push_subtypes < ' tcx > ( stack : & mut TypeWalkerStack < ' tcx > , parent_ty : Ty < ' tcx > ) { match parent_ty . sty { ty :: Bool | ty :: Char | ty :: Int ( _ ) | ty :: Uint ( _ ) | ty :: Float ( _ ) | ty :: Str | ty :: Infer ( _ ) | ty :: Param ( _ ) | ty :: Never | ty :: Error | ty :: Foreign ( .. ) => { } ty :: Array ( ty , len ) => { push_const ( stack , len ) ; stack . push ( ty ) ; } ty :: Slice ( ty ) => { stack . push ( ty ) ; } ty :: RawPtr ( ref mt ) => { stack . push ( mt . ty ) ; } ty :: Ref ( _ , ty , _ ) => { stack . push ( ty ) ; } ty :: Projection ( ref data ) => { stack . extend ( data . substs . types ( ) . rev ( ) ) ; } ty :: Dynamic ( ref obj , .. ) => { stack . extend ( obj . iter ( ) . rev ( ) . flat_map ( | predicate | { let ( substs , opt_ty ) = match * predicate . skip_binder ( ) { ty :: ExistentialPredicate :: Trait ( tr ) => ( tr . substs , None ) , ty :: ExistentialPredicate :: Projection ( p ) => ( p . substs , Some ( p . ty ) ) , ty :: ExistentialPredicate :: AutoTrait ( _ ) => // Empty iterator ( ty :: Substs :: empty ( ) , None ) , } ; substs . types ( ) . rev ( ) . chain ( opt_ty ) } ) ) ; } ty :: Adt ( _ , substs ) | ty :: Opaque ( _ , substs ) => { stack . extend ( substs . types ( ) . rev ( ) ) ; } ty :: Closure ( _ , ref substs ) => { stack . extend ( substs . substs . types ( ) . rev ( ) ) ; } ty :: Generator ( _ , ref substs , _ ) => { stack . extend ( substs . substs . types ( ) . rev ( ) ) ; } ty :: GeneratorWitness ( ts ) => { stack . extend ( ts . skip_binder ( ) . iter ( ) . cloned ( ) . rev ( ) ) ; } ty :: Tuple ( ts ) => { stack . extend ( ts . iter ( ) . cloned ( ) . rev ( ) ) ; } ty :: FnDef ( _ , substs ) => { stack . extend ( substs . types ( ) . rev ( ) ) ; } ty :: FnPtr ( sig ) => { stack . push ( sig . skip_binder ( ) . output ( ) ) ; stack . extend ( sig . skip_binder ( ) . inputs ( ) . iter ( ) . cloned ( ) . rev ( ) ) ; } } }
We push types on the stack in reverse order so as to
maintain a pre-order traversal.
We push types on the stack in reverse order so as to maintain a pre - order traversal .
stack
&mut TypeWalkerStack<'tcx>
parent_ty
Ty<'tcx>
stack
&mut TypeWalkerStack<'tcx>
parent_ty
Ty<'tcx>