1use crate::{
8 try_break, AdtId, AssocTypeId, ClausePriority, ClosureId, Constraints, ControlFlow,
9 CoroutineId, DebruijnIndex, FloatTy, FnDefId, ForeignDefId, GenericArg, Goals, ImplId, IntTy,
10 Interner, Mutability, OpaqueTyId, PlaceholderIndex, ProgramClause, ProgramClauses,
11 QuantifiedWhereClauses, QuantifierKind, Safety, Scalar, Substitution, TraitId,
12 TypeSuperVisitable, TypeVisitable, TypeVisitor, UintTy, UniverseIndex,
13};
14use std::{marker::PhantomData, sync::Arc};
15
16pub fn visit_iter<'i, T, I, B>(
18 it: impl Iterator<Item = T>,
19 visitor: &mut dyn TypeVisitor<I, BreakTy = B>,
20 outer_binder: DebruijnIndex,
21) -> ControlFlow<B>
22where
23 T: TypeVisitable<I>,
24 I: 'i + Interner,
25{
26 for e in it {
27 try_break!(e.visit_with(visitor, outer_binder));
28 }
29 ControlFlow::Continue(())
30}
31
32impl<T: TypeVisitable<I>, I: Interner> TypeVisitable<I> for &T {
33 fn visit_with<B>(
34 &self,
35 visitor: &mut dyn TypeVisitor<I, BreakTy = B>,
36 outer_binder: DebruijnIndex,
37 ) -> ControlFlow<B> {
38 T::visit_with(self, visitor, outer_binder)
39 }
40}
41
42impl<T: TypeVisitable<I>, I: Interner> TypeVisitable<I> for Vec<T> {
43 fn visit_with<B>(
44 &self,
45 visitor: &mut dyn TypeVisitor<I, BreakTy = B>,
46 outer_binder: DebruijnIndex,
47 ) -> ControlFlow<B> {
48 visit_iter(self.iter(), visitor, outer_binder)
49 }
50}
51
52impl<T: TypeVisitable<I>, I: Interner> TypeVisitable<I> for &[T] {
53 fn visit_with<B>(
54 &self,
55 visitor: &mut dyn TypeVisitor<I, BreakTy = B>,
56 outer_binder: DebruijnIndex,
57 ) -> ControlFlow<B> {
58 visit_iter(self.iter(), visitor, outer_binder)
59 }
60}
61
62impl<T: TypeVisitable<I>, I: Interner> TypeVisitable<I> for Box<T> {
63 fn visit_with<B>(
64 &self,
65 visitor: &mut dyn TypeVisitor<I, BreakTy = B>,
66 outer_binder: DebruijnIndex,
67 ) -> ControlFlow<B> {
68 T::visit_with(self, visitor, outer_binder)
69 }
70}
71
72impl<T: TypeVisitable<I>, I: Interner> TypeVisitable<I> for Arc<T> {
73 fn visit_with<B>(
74 &self,
75 visitor: &mut dyn TypeVisitor<I, BreakTy = B>,
76 outer_binder: DebruijnIndex,
77 ) -> ControlFlow<B> {
78 T::visit_with(self, visitor, outer_binder)
79 }
80}
81
82macro_rules! tuple_visit {
83 ($($n:ident),*) => {
84 impl<$($n: TypeVisitable<I>,)* I: Interner> TypeVisitable<I> for ($($n,)*) {
85 fn visit_with<BT>(&self, visitor: &mut dyn TypeVisitor<I, BreakTy = BT>, outer_binder: DebruijnIndex) -> ControlFlow<BT> {
86 #[allow(non_snake_case)]
87 let &($(ref $n),*) = self;
88 $(
89 try_break!($n.visit_with(visitor, outer_binder));
90 )*
91 ControlFlow::Continue(())
92 }
93 }
94 }
95}
96
97tuple_visit!(A, B);
98tuple_visit!(A, B, C);
99tuple_visit!(A, B, C, D);
100tuple_visit!(A, B, C, D, E);
101
102impl<T: TypeVisitable<I>, I: Interner> TypeVisitable<I> for Option<T> {
103 fn visit_with<B>(
104 &self,
105 visitor: &mut dyn TypeVisitor<I, BreakTy = B>,
106 outer_binder: DebruijnIndex,
107 ) -> ControlFlow<B> {
108 match self {
109 Some(e) => e.visit_with(visitor, outer_binder),
110 None => ControlFlow::Continue(()),
111 }
112 }
113}
114
115impl<I: Interner> TypeVisitable<I> for GenericArg<I> {
116 fn visit_with<B>(
117 &self,
118 visitor: &mut dyn TypeVisitor<I, BreakTy = B>,
119 outer_binder: DebruijnIndex,
120 ) -> ControlFlow<B> {
121 let interner = visitor.interner();
122 self.data(interner).visit_with(visitor, outer_binder)
123 }
124}
125
126impl<I: Interner> TypeVisitable<I> for Substitution<I> {
127 fn visit_with<B>(
128 &self,
129 visitor: &mut dyn TypeVisitor<I, BreakTy = B>,
130 outer_binder: DebruijnIndex,
131 ) -> ControlFlow<B> {
132 let interner = visitor.interner();
133 visit_iter(self.iter(interner), visitor, outer_binder)
134 }
135}
136
137impl<I: Interner> TypeVisitable<I> for Goals<I> {
138 fn visit_with<B>(
139 &self,
140 visitor: &mut dyn TypeVisitor<I, BreakTy = B>,
141 outer_binder: DebruijnIndex,
142 ) -> ControlFlow<B> {
143 let interner = visitor.interner();
144 visit_iter(self.iter(interner), visitor, outer_binder)
145 }
146}
147
148#[doc(hidden)]
149#[macro_export]
150macro_rules! const_visit {
151 ($t:ty) => {
152 impl<I: Interner> $crate::visit::TypeVisitable<I> for $t {
153 fn visit_with<B>(
154 &self,
155 _visitor: &mut dyn ($crate::visit::TypeVisitor<I, BreakTy = B>),
156 _outer_binder: DebruijnIndex,
157 ) -> ControlFlow<B> {
158 ControlFlow::Continue(())
159 }
160 }
161 };
162}
163
164const_visit!(bool);
165const_visit!(usize);
166const_visit!(UniverseIndex);
167const_visit!(PlaceholderIndex);
168const_visit!(QuantifierKind);
169const_visit!(DebruijnIndex);
170const_visit!(ClausePriority);
171const_visit!(());
172const_visit!(Scalar);
173const_visit!(UintTy);
174const_visit!(IntTy);
175const_visit!(FloatTy);
176const_visit!(Mutability);
177const_visit!(Safety);
178
179#[doc(hidden)]
180#[macro_export]
181macro_rules! id_visit {
182 ($t:ident) => {
183 impl<I: Interner> $crate::visit::TypeVisitable<I> for $t<I> {
184 fn visit_with<B>(
185 &self,
186 _visitor: &mut dyn ($crate::visit::TypeVisitor<I, BreakTy = B>),
187 _outer_binder: DebruijnIndex,
188 ) -> ControlFlow<B> {
189 ControlFlow::Continue(())
190 }
191 }
192 };
193}
194
195id_visit!(ImplId);
196id_visit!(AdtId);
197id_visit!(TraitId);
198id_visit!(OpaqueTyId);
199id_visit!(AssocTypeId);
200id_visit!(FnDefId);
201id_visit!(ClosureId);
202id_visit!(CoroutineId);
203id_visit!(ForeignDefId);
204
205impl<I: Interner> TypeSuperVisitable<I> for ProgramClause<I> {
206 fn super_visit_with<B>(
207 &self,
208 visitor: &mut dyn TypeVisitor<I, BreakTy = B>,
209 outer_binder: DebruijnIndex,
210 ) -> ControlFlow<B> {
211 let interner = visitor.interner();
212
213 self.data(interner).0.visit_with(visitor, outer_binder)
214 }
215}
216
217impl<I: Interner> TypeVisitable<I> for ProgramClauses<I> {
218 fn visit_with<B>(
219 &self,
220 visitor: &mut dyn TypeVisitor<I, BreakTy = B>,
221 outer_binder: DebruijnIndex,
222 ) -> ControlFlow<B> {
223 let interner = visitor.interner();
224
225 visit_iter(self.iter(interner), visitor, outer_binder)
226 }
227}
228
229impl<I: Interner> TypeVisitable<I> for Constraints<I> {
230 fn visit_with<B>(
231 &self,
232 visitor: &mut dyn TypeVisitor<I, BreakTy = B>,
233 outer_binder: DebruijnIndex,
234 ) -> ControlFlow<B> {
235 let interner = visitor.interner();
236
237 visit_iter(self.iter(interner), visitor, outer_binder)
238 }
239}
240
241impl<I: Interner> TypeVisitable<I> for QuantifiedWhereClauses<I> {
242 fn visit_with<B>(
243 &self,
244 visitor: &mut dyn TypeVisitor<I, BreakTy = B>,
245 outer_binder: DebruijnIndex,
246 ) -> ControlFlow<B> {
247 let interner = visitor.interner();
248
249 visit_iter(self.iter(interner), visitor, outer_binder)
250 }
251}
252
253impl<I: Interner> TypeVisitable<I> for PhantomData<I> {
254 fn visit_with<B>(
255 &self,
256 _visitor: &mut dyn TypeVisitor<I, BreakTy = B>,
257 _outer_binder: DebruijnIndex,
258 ) -> ControlFlow<B> {
259 ControlFlow::Continue(())
260 }
261}