chalk_ir/fold/
boring_impls.rs

1//! This module contains "rote and uninteresting" impls of `TypeFoldable` for
2//! various types. In general, we prefer to derive `TypeFoldable`, but
3//! sometimes that doesn't work for whatever reason.
4//!
5//! The more interesting impls of `TypeFoldable` remain in the `fold` module.
6
7use super::in_place;
8use crate::*;
9use std::marker::PhantomData;
10
11impl<T: TypeFoldable<I>, I: Interner> TypeFoldable<I> for Vec<T> {
12    fn try_fold_with<E>(
13        self,
14        folder: &mut dyn FallibleTypeFolder<I, Error = E>,
15        outer_binder: DebruijnIndex,
16    ) -> Result<Self, E> {
17        in_place::fallible_map_vec(self, |e| e.try_fold_with(folder, outer_binder))
18    }
19}
20
21impl<T: TypeFoldable<I>, I: Interner> TypeFoldable<I> for Box<T> {
22    fn try_fold_with<E>(
23        self,
24        folder: &mut dyn FallibleTypeFolder<I, Error = E>,
25        outer_binder: DebruijnIndex,
26    ) -> Result<Self, E> {
27        in_place::fallible_map_box(self, |e| e.try_fold_with(folder, outer_binder))
28    }
29}
30
31macro_rules! tuple_fold {
32    ($($n:ident),*) => {
33        impl<$($n: TypeFoldable<I>,)* I: Interner> TypeFoldable<I> for ($($n,)*) {
34            fn try_fold_with<Error>(self, folder: &mut dyn FallibleTypeFolder<I, Error = Error>, outer_binder: DebruijnIndex) -> Result<Self, Error>
35            {
36                #[allow(non_snake_case)]
37                let ($($n),*) = self;
38                Ok(($($n.try_fold_with(folder, outer_binder)?,)*))
39            }
40        }
41    }
42}
43
44tuple_fold!(A, B);
45tuple_fold!(A, B, C);
46tuple_fold!(A, B, C, D);
47tuple_fold!(A, B, C, D, E);
48
49impl<T: TypeFoldable<I>, I: Interner> TypeFoldable<I> for Option<T> {
50    fn try_fold_with<E>(
51        self,
52        folder: &mut dyn FallibleTypeFolder<I, Error = E>,
53        outer_binder: DebruijnIndex,
54    ) -> Result<Self, E> {
55        match self {
56            None => Ok(None),
57            Some(e) => Ok(Some(e.try_fold_with(folder, outer_binder)?)),
58        }
59    }
60}
61
62impl<I: Interner> TypeFoldable<I> for GenericArg<I> {
63    fn try_fold_with<E>(
64        self,
65        folder: &mut dyn FallibleTypeFolder<I, Error = E>,
66        outer_binder: DebruijnIndex,
67    ) -> Result<Self, E> {
68        let interner = folder.interner();
69
70        let data = self
71            .data(interner)
72            .clone()
73            .try_fold_with(folder, outer_binder)?;
74        Ok(GenericArg::new(interner, data))
75    }
76}
77
78impl<I: Interner> TypeFoldable<I> for Substitution<I> {
79    fn try_fold_with<E>(
80        self,
81        folder: &mut dyn FallibleTypeFolder<I, Error = E>,
82        outer_binder: DebruijnIndex,
83    ) -> Result<Self, E> {
84        let interner = folder.interner();
85
86        let folded = self
87            .iter(interner)
88            .cloned()
89            .map(|p| p.try_fold_with(folder, outer_binder));
90        Substitution::from_fallible(interner, folded)
91    }
92}
93
94impl<I: Interner> TypeFoldable<I> for Goals<I> {
95    fn try_fold_with<E>(
96        self,
97        folder: &mut dyn FallibleTypeFolder<I, Error = E>,
98        outer_binder: DebruijnIndex,
99    ) -> Result<Self, E> {
100        let interner = folder.interner();
101        let folded = self
102            .iter(interner)
103            .cloned()
104            .map(|p| p.try_fold_with(folder, outer_binder));
105        Goals::from_fallible(interner, folded)
106    }
107}
108
109impl<I: Interner> TypeFoldable<I> for ProgramClauses<I> {
110    fn try_fold_with<E>(
111        self,
112        folder: &mut dyn FallibleTypeFolder<I, Error = E>,
113        outer_binder: DebruijnIndex,
114    ) -> Result<Self, E> {
115        let interner = folder.interner();
116        let folded = self
117            .iter(interner)
118            .cloned()
119            .map(|p| p.try_fold_with(folder, outer_binder));
120        ProgramClauses::from_fallible(interner, folded)
121    }
122}
123
124impl<I: Interner> TypeFoldable<I> for QuantifiedWhereClauses<I> {
125    fn try_fold_with<E>(
126        self,
127        folder: &mut dyn FallibleTypeFolder<I, Error = E>,
128        outer_binder: DebruijnIndex,
129    ) -> Result<Self, E> {
130        let interner = folder.interner();
131        let folded = self
132            .iter(interner)
133            .cloned()
134            .map(|p| p.try_fold_with(folder, outer_binder));
135        QuantifiedWhereClauses::from_fallible(interner, folded)
136    }
137}
138
139impl<I: Interner> TypeFoldable<I> for Constraints<I> {
140    fn try_fold_with<E>(
141        self,
142        folder: &mut dyn FallibleTypeFolder<I, Error = E>,
143        outer_binder: DebruijnIndex,
144    ) -> Result<Self, E> {
145        let interner = folder.interner();
146        let folded = self
147            .iter(interner)
148            .cloned()
149            .map(|p| p.try_fold_with(folder, outer_binder));
150        Constraints::from_fallible(interner, folded)
151    }
152}
153
154#[doc(hidden)]
155#[macro_export]
156macro_rules! copy_fold {
157    ($t:ty) => {
158        impl<I: Interner> $crate::fold::TypeFoldable<I> for $t {
159            fn try_fold_with<E>(
160                self,
161                _folder: &mut dyn ($crate::fold::FallibleTypeFolder<I, Error = E>),
162                _outer_binder: DebruijnIndex,
163            ) -> ::std::result::Result<Self, E> {
164                Ok(self)
165            }
166        }
167    };
168}
169
170copy_fold!(bool);
171copy_fold!(usize);
172copy_fold!(UniverseIndex);
173copy_fold!(PlaceholderIndex);
174copy_fold!(QuantifierKind);
175copy_fold!(DebruijnIndex);
176copy_fold!(());
177copy_fold!(UintTy);
178copy_fold!(IntTy);
179copy_fold!(FloatTy);
180copy_fold!(Scalar);
181copy_fold!(ClausePriority);
182copy_fold!(Mutability);
183copy_fold!(Safety);
184
185#[doc(hidden)]
186#[macro_export]
187macro_rules! id_fold {
188    ($t:ident) => {
189        impl<I: Interner> $crate::fold::TypeFoldable<I> for $t<I> {
190            fn try_fold_with<E>(
191                self,
192                _folder: &mut dyn ($crate::fold::FallibleTypeFolder<I, Error = E>),
193                _outer_binder: DebruijnIndex,
194            ) -> ::std::result::Result<Self, E> {
195                Ok(self)
196            }
197        }
198    };
199}
200
201id_fold!(ImplId);
202id_fold!(AdtId);
203id_fold!(TraitId);
204id_fold!(AssocTypeId);
205id_fold!(OpaqueTyId);
206id_fold!(FnDefId);
207id_fold!(ClosureId);
208id_fold!(CoroutineId);
209id_fold!(ForeignDefId);
210
211impl<I: Interner> TypeSuperFoldable<I> for ProgramClauseData<I> {
212    fn try_super_fold_with<E>(
213        self,
214        folder: &mut dyn FallibleTypeFolder<I, Error = E>,
215        outer_binder: DebruijnIndex,
216    ) -> ::std::result::Result<Self, E> {
217        Ok(ProgramClauseData(
218            self.0.try_fold_with(folder, outer_binder)?,
219        ))
220    }
221}
222
223impl<I: Interner> TypeSuperFoldable<I> for ProgramClause<I> {
224    fn try_super_fold_with<E>(
225        self,
226        folder: &mut dyn FallibleTypeFolder<I, Error = E>,
227        outer_binder: DebruijnIndex,
228    ) -> ::std::result::Result<Self, E> {
229        let clause = self.data(folder.interner()).clone();
230        Ok(clause
231            .try_super_fold_with(folder, outer_binder)?
232            .intern(folder.interner()))
233    }
234}
235
236impl<I: Interner> TypeFoldable<I> for PhantomData<I> {
237    fn try_fold_with<E>(
238        self,
239        _folder: &mut dyn FallibleTypeFolder<I, Error = E>,
240        _outer_binder: DebruijnIndex,
241    ) -> ::std::result::Result<Self, E> {
242        Ok(PhantomData)
243    }
244}