Shift free de Bruijn indices ≥ `cutoff` up by `shift`. Used when substituting an argument into a deeper context. Like `subst`, memoizes by content hash within a single call so shared sub-expressions are walked once per cutoff level.
( env: &mut InternTable<M>, e: &KExpr<M>, shift: u64, cutoff: u64, )
| 339 | /// Shift free de Bruijn indices ≥ `cutoff` up by `shift`. |
| 340 | /// |
| 341 | /// Used when substituting an argument into a deeper context. Like |
| 342 | /// `subst`, memoizes by content hash within a single call so shared |
| 343 | /// sub-expressions are walked once per cutoff level. |
| 344 | pub fn lift<M: KernelMode>( |
| 345 | env: &mut InternTable<M>, |
| 346 | e: &KExpr<M>, |
| 347 | shift: u64, |
| 348 | cutoff: u64, |
| 349 | ) -> KExpr<M> { |
| 350 | if shift == 0 || e.lbr() <= cutoff { |
| 351 | return e.clone(); |
| 352 | } |
| 353 | // Borrow the dedicated `lift_scratch`. `lift` is invoked from inside |
| 354 | // `subst_cached`, which already holds `subst_scratch`; using a separate |
| 355 | // buffer keeps both available simultaneously. `lift_cached` does not |
| 356 | // call back into `lift`/`subst`/`simul_subst`, so the scratch is safe |
| 357 | // to share across calls without nested-borrow risk. |
| 358 | let mut cache = std::mem::take(&mut env.lift_scratch); |
| 359 | cache.clear(); |
| 360 | let result = lift_cached(env, e, shift, cutoff, &mut cache); |
| 361 | env.lift_scratch = cache; |
| 362 | result |
| 363 | } |