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