1use 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}