//! This module contains "rote and uninteresting" impls of `TypeVisitable` for //! various types. In general, we prefer to derive `TypeVisitable`, but //! sometimes that doesn't work for whatever reason. //! //! The more interesting impls of `TypeVisitable` remain in the `visit` module. use crate::{ try_break, AdtId, AssocTypeId, ClausePriority, ClosureId, Constraints, ControlFlow, DebruijnIndex, FloatTy, FnDefId, ForeignDefId, GeneratorId, GenericArg, Goals, ImplId, IntTy, Interner, Mutability, OpaqueTyId, PlaceholderIndex, ProgramClause, ProgramClauses, QuantifiedWhereClauses, QuantifierKind, Safety, Scalar, Substitution, TraitId, TypeSuperVisitable, TypeVisitable, TypeVisitor, UintTy, UniverseIndex, }; use std::{marker::PhantomData, sync::Arc}; /// Convenience function to visit all the items in the iterator it. pub fn visit_iter<'i, T, I, B>( it: impl Iterator, visitor: &mut dyn TypeVisitor, outer_binder: DebruijnIndex, ) -> ControlFlow where T: TypeVisitable, I: 'i + Interner, { for e in it { try_break!(e.visit_with(visitor, outer_binder)); } ControlFlow::Continue(()) } impl, I: Interner> TypeVisitable for &T { fn visit_with( &self, visitor: &mut dyn TypeVisitor, outer_binder: DebruijnIndex, ) -> ControlFlow { T::visit_with(self, visitor, outer_binder) } } impl, I: Interner> TypeVisitable for Vec { fn visit_with( &self, visitor: &mut dyn TypeVisitor, outer_binder: DebruijnIndex, ) -> ControlFlow { visit_iter(self.iter(), visitor, outer_binder) } } impl, I: Interner> TypeVisitable for &[T] { fn visit_with( &self, visitor: &mut dyn TypeVisitor, outer_binder: DebruijnIndex, ) -> ControlFlow { visit_iter(self.iter(), visitor, outer_binder) } } impl, I: Interner> TypeVisitable for Box { fn visit_with( &self, visitor: &mut dyn TypeVisitor, outer_binder: DebruijnIndex, ) -> ControlFlow { T::visit_with(self, visitor, outer_binder) } } impl, I: Interner> TypeVisitable for Arc { fn visit_with( &self, visitor: &mut dyn TypeVisitor, outer_binder: DebruijnIndex, ) -> ControlFlow { T::visit_with(self, visitor, outer_binder) } } macro_rules! tuple_visit { ($($n:ident),*) => { impl<$($n: TypeVisitable,)* I: Interner> TypeVisitable for ($($n,)*) { fn visit_with(&self, visitor: &mut dyn TypeVisitor, outer_binder: DebruijnIndex) -> ControlFlow { #[allow(non_snake_case)] let &($(ref $n),*) = self; $( try_break!($n.visit_with(visitor, outer_binder)); )* ControlFlow::Continue(()) } } } } tuple_visit!(A, B); tuple_visit!(A, B, C); tuple_visit!(A, B, C, D); tuple_visit!(A, B, C, D, E); impl, I: Interner> TypeVisitable for Option { fn visit_with( &self, visitor: &mut dyn TypeVisitor, outer_binder: DebruijnIndex, ) -> ControlFlow { match self { Some(e) => e.visit_with(visitor, outer_binder), None => ControlFlow::Continue(()), } } } impl TypeVisitable for GenericArg { fn visit_with( &self, visitor: &mut dyn TypeVisitor, outer_binder: DebruijnIndex, ) -> ControlFlow { let interner = visitor.interner(); self.data(interner).visit_with(visitor, outer_binder) } } impl TypeVisitable for Substitution { fn visit_with( &self, visitor: &mut dyn TypeVisitor, outer_binder: DebruijnIndex, ) -> ControlFlow { let interner = visitor.interner(); visit_iter(self.iter(interner), visitor, outer_binder) } } impl TypeVisitable for Goals { fn visit_with( &self, visitor: &mut dyn TypeVisitor, outer_binder: DebruijnIndex, ) -> ControlFlow { let interner = visitor.interner(); visit_iter(self.iter(interner), visitor, outer_binder) } } #[doc(hidden)] #[macro_export] macro_rules! const_visit { ($t:ty) => { impl $crate::visit::TypeVisitable for $t { fn visit_with( &self, _visitor: &mut dyn ($crate::visit::TypeVisitor), _outer_binder: DebruijnIndex, ) -> ControlFlow { ControlFlow::Continue(()) } } }; } const_visit!(bool); const_visit!(usize); const_visit!(UniverseIndex); const_visit!(PlaceholderIndex); const_visit!(QuantifierKind); const_visit!(DebruijnIndex); const_visit!(ClausePriority); const_visit!(()); const_visit!(Scalar); const_visit!(UintTy); const_visit!(IntTy); const_visit!(FloatTy); const_visit!(Mutability); const_visit!(Safety); #[doc(hidden)] #[macro_export] macro_rules! id_visit { ($t:ident) => { impl $crate::visit::TypeVisitable for $t { fn visit_with( &self, _visitor: &mut dyn ($crate::visit::TypeVisitor), _outer_binder: DebruijnIndex, ) -> ControlFlow { ControlFlow::Continue(()) } } }; } id_visit!(ImplId); id_visit!(AdtId); id_visit!(TraitId); id_visit!(OpaqueTyId); id_visit!(AssocTypeId); id_visit!(FnDefId); id_visit!(ClosureId); id_visit!(GeneratorId); id_visit!(ForeignDefId); impl TypeSuperVisitable for ProgramClause { fn super_visit_with( &self, visitor: &mut dyn TypeVisitor, outer_binder: DebruijnIndex, ) -> ControlFlow { let interner = visitor.interner(); self.data(interner).0.visit_with(visitor, outer_binder) } } impl TypeVisitable for ProgramClauses { fn visit_with( &self, visitor: &mut dyn TypeVisitor, outer_binder: DebruijnIndex, ) -> ControlFlow { let interner = visitor.interner(); visit_iter(self.iter(interner), visitor, outer_binder) } } impl TypeVisitable for Constraints { fn visit_with( &self, visitor: &mut dyn TypeVisitor, outer_binder: DebruijnIndex, ) -> ControlFlow { let interner = visitor.interner(); visit_iter(self.iter(interner), visitor, outer_binder) } } impl TypeVisitable for QuantifiedWhereClauses { fn visit_with( &self, visitor: &mut dyn TypeVisitor, outer_binder: DebruijnIndex, ) -> ControlFlow { let interner = visitor.interner(); visit_iter(self.iter(interner), visitor, outer_binder) } } impl TypeVisitable for PhantomData { fn visit_with( &self, _visitor: &mut dyn TypeVisitor, _outer_binder: DebruijnIndex, ) -> ControlFlow { ControlFlow::Continue(()) } }