chalk_ir/visit/
boring_impls.rs

1//! This module contains "rote and uninteresting" impls of `TypeVisitable` for
2//! various types. In general, we prefer to derive `TypeVisitable`, but
3//! sometimes that doesn't work for whatever reason.
4//!
5//! The more interesting impls of `TypeVisitable` remain in the `visit` module.
6
7use 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
16/// Convenience function to visit all the items in the iterator it.
17pub 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}