|
87 | 87 | /// Top-level callback: invoked for each `Lifetime<I>` that is
|
88 | 88 | /// encountered when folding. By default, invokes
|
89 | 89 | /// `super_fold_with`, which will in turn invoke the more
|
90 |
| - /// specialized folding methods below, like `fold_free_lifetime_ty`. |
| 90 | + /// specialized folding methods below, like `fold_free_var_lifetime`. |
91 | 91 | fn fold_lifetime(
|
92 | 92 | &mut self,
|
93 | 93 | lifetime: &Lifetime<I>,
|
|
96 | 96 | lifetime.super_fold_with(self.as_dyn(), outer_binder)
|
97 | 97 | }
|
98 | 98 |
|
| 99 | + /// Top-level callback: invoked for each `Const<I>` that is |
| 100 | + /// encountered when folding. By default, invokes |
| 101 | + /// `super_fold_with`, which will in turn invoke the more |
| 102 | + /// specialized folding methods below, like `fold_free_var_const`. |
| 103 | + fn fold_const( |
| 104 | + &mut self, |
| 105 | + constant: &Const<I>, |
| 106 | + outer_binder: DebruijnIndex, |
| 107 | + ) -> Fallible<Const<TI>> { |
| 108 | + constant.super_fold_with(self.as_dyn(), outer_binder) |
| 109 | + } |
| 110 | + |
99 | 111 | /// Invoked for every program clause. By default, recursively folds the goals contents.
|
100 | 112 | fn fold_program_clause(
|
101 | 113 | &mut self,
|
@@ -159,8 +171,24 @@ where
|
159 | 171 | }
|
160 | 172 | }
|
161 | 173 |
|
162 |
| - /// If overriden to return true, we will panic when a free |
163 |
| - /// placeholder type/lifetime is encountered. |
| 174 | + fn fold_free_var_const( |
| 175 | + &mut self, |
| 176 | + bound_var: BoundVar, |
| 177 | + outer_binder: DebruijnIndex, |
| 178 | + ) -> Fallible<Const<TI>> { |
| 179 | + if self.forbid_free_vars() { |
| 180 | + panic!( |
| 181 | + "unexpected free variable with depth `{:?}` with outer binder {:?}", |
| 182 | + bound_var, outer_binder |
| 183 | + ) |
| 184 | + } else { |
| 185 | + let bound_var = bound_var.shifted_in_from(outer_binder); |
| 186 | + Ok(ConstData::<TI>::BoundVar(bound_var).intern(self.target_interner())) |
| 187 | + } |
| 188 | + } |
| 189 | + |
| 190 | + /// If overridden to return true, we will panic when a free |
| 191 | + /// placeholder type/lifetime/const is encountered. |
164 | 192 | fn forbid_free_placeholders(&self) -> bool {
|
165 | 193 | false
|
166 | 194 | }
|
@@ -199,6 +227,19 @@ where
|
199 | 227 | }
|
200 | 228 | }
|
201 | 229 |
|
| 230 | + #[allow(unused_variables)] |
| 231 | + fn fold_free_placeholder_const( |
| 232 | + &mut self, |
| 233 | + universe: PlaceholderIndex, |
| 234 | + outer_binder: DebruijnIndex, |
| 235 | + ) -> Fallible<Const<TI>> { |
| 236 | + if self.forbid_free_placeholders() { |
| 237 | + panic!("unexpected placeholder const `{:?}`", universe) |
| 238 | + } else { |
| 239 | + Ok(universe.to_const(self.target_interner())) |
| 240 | + } |
| 241 | + } |
| 242 | + |
202 | 243 | /// If overridden to return true, inference variables will trigger
|
203 | 244 | /// panics when folded. Used when inference variables are
|
204 | 245 | /// unexpected.
|
@@ -240,6 +281,19 @@ where
|
240 | 281 | }
|
241 | 282 | }
|
242 | 283 |
|
| 284 | + #[allow(unused_variables)] |
| 285 | + fn fold_inference_const( |
| 286 | + &mut self, |
| 287 | + var: InferenceVar, |
| 288 | + outer_binder: DebruijnIndex, |
| 289 | + ) -> Fallible<Const<TI>> { |
| 290 | + if self.forbid_inference_vars() { |
| 291 | + panic!("unexpected inference const `{:?}`", var) |
| 292 | + } else { |
| 293 | + Ok(var.to_const(self.target_interner())) |
| 294 | + } |
| 295 | + } |
| 296 | + |
243 | 297 | fn interner(&self) -> &'i I;
|
244 | 298 |
|
245 | 299 | fn target_interner(&self) -> &'i TI;
|
@@ -419,6 +473,60 @@ where
|
419 | 473 | }
|
420 | 474 | }
|
421 | 475 |
|
| 476 | +/// "Folding" a const invokes the `fold_const` method on the folder; this |
| 477 | +/// usually (in turn) invokes `super_fold_const` to fold the individual |
| 478 | +/// parts. |
| 479 | +impl<I: Interner, TI: TargetInterner<I>> Fold<I, TI> for Const<I> { |
| 480 | + type Result = Const<TI>; |
| 481 | + |
| 482 | + fn fold_with<'i>( |
| 483 | + &self, |
| 484 | + folder: &mut dyn Folder<'i, I, TI>, |
| 485 | + outer_binder: DebruijnIndex, |
| 486 | + ) -> Fallible<Self::Result> |
| 487 | + where |
| 488 | + I: 'i, |
| 489 | + TI: 'i, |
| 490 | + { |
| 491 | + folder.fold_const(self, outer_binder) |
| 492 | + } |
| 493 | +} |
| 494 | + |
| 495 | +impl<I, TI> SuperFold<I, TI> for Const<I> |
| 496 | +where |
| 497 | + I: Interner, |
| 498 | + TI: TargetInterner<I>, |
| 499 | +{ |
| 500 | + fn super_fold_with<'i>( |
| 501 | + &self, |
| 502 | + folder: &mut dyn Folder<'i, I, TI>, |
| 503 | + outer_binder: DebruijnIndex, |
| 504 | + ) -> Fallible<Const<TI>> |
| 505 | + where |
| 506 | + I: 'i, |
| 507 | + TI: 'i, |
| 508 | + { |
| 509 | + let interner = folder.interner(); |
| 510 | + match self.data(interner) { |
| 511 | + ConstData::BoundVar(bound_var) => { |
| 512 | + if let Some(bound_var1) = bound_var.shifted_out_to(outer_binder) { |
| 513 | + folder.fold_free_var_const(bound_var1, outer_binder) |
| 514 | + } else { |
| 515 | + Ok(ConstData::<TI>::BoundVar(*bound_var).intern(folder.target_interner())) |
| 516 | + } |
| 517 | + } |
| 518 | + ConstData::InferenceVar(var) => folder.fold_inference_const(*var, outer_binder), |
| 519 | + ConstData::Placeholder(universe) => { |
| 520 | + folder.fold_free_placeholder_const(*universe, outer_binder) |
| 521 | + } |
| 522 | + ConstData::Concrete(ev) => Ok(ConstData::Concrete(ConcreteConst { |
| 523 | + interned: folder.target_interner().transfer_const(&ev.interned), |
| 524 | + }) |
| 525 | + .intern(folder.target_interner())), |
| 526 | + } |
| 527 | + } |
| 528 | +} |
| 529 | + |
422 | 530 | /// Folding a goal invokes the `fold_goal` callback (which will, by
|
423 | 531 | /// default, invoke super-fold).
|
424 | 532 | impl<I: Interner, TI: TargetInterner<I>> Fold<I, TI> for Goal<I> {
|
|
0 commit comments