Compare two Lean expressions structurally for canonical ordering. Strips `Mdata` wrappers, compares by constructor tag, then recurses into subexpressions. Constants are compared by address (or mutual index).
( x: &LeanExpr, y: &LeanExpr, mut_ctx: &MutCtx, x_lvls: &[Name], y_lvls: &[Name], stt: &CompileState, )
| 2462 | rules, |
| 2463 | }; |
| 2464 | |
| 2465 | let all_addrs: Vec<Address> = |
| 2466 | rec.all.iter().map(|n| compile_name(n, stt)).collect(); |
| 2467 | let ctx_addrs: Vec<Address> = |
| 2468 | ctx_to_all(mut_ctx).iter().map(|n| compile_name(n, stt)).collect(); |
| 2469 | |
| 2470 | let mut meta = ConstantMeta::new(ConstantMetaInfo::Rec { |
| 2471 | name: name_addr, |
| 2472 | lvls: lvl_addrs, |
| 2473 | rules: rule_addrs, |
| 2474 | all: all_addrs, |
| 2475 | ctx: ctx_addrs, |
| 2476 | arena, |
| 2477 | type_root, |
| 2478 | rule_roots, |
| 2479 | }); |
| 2480 | meta.meta_sharing = surgery_sharing; |
| 2481 | meta.meta_univs = meta_univs; |
| 2482 | meta.univ_patches = univ_patches; |
| 2483 | |
| 2484 | Ok((data, meta)) |
| 2485 | } |
| 2486 | |
| 2487 | /// Compile a Constructor. |
| 2488 | /// Each constructor gets its own arena. |
| 2489 | fn compile_constructor( |
| 2490 | ctor: &ConstructorVal, |
| 2491 | mut_ctx: &MutCtx, |
| 2492 | cache: &mut BlockCache, |
| 2493 | stt: &CompileState, |
| 2494 | ) -> Result<(Constructor, ConstantMeta), CompileError> { |
| 2495 | cache.compiling = Some(ctor.cnst.name.clone()); |
| 2496 | let univ_params = &ctor.cnst.level_params; |
| 2497 | |
| 2498 | let typ = compile_expr(&ctor.cnst.typ, univ_params, mut_ctx, cache, stt)?; |
| 2499 | let type_root = |
| 2500 | *cache.arena_roots.last().expect("missing ctor type arena root"); |
| 2501 | |
| 2502 | // Take arena and surgery sharing for this constructor. A ctor's type |
| 2503 | // may contain surgered call-sites when the ctor's field types reference |
| 2504 | // alpha-collapsed auxiliaries, so drain here to attach to THIS ctor's |
| 2505 | // meta rather than leaking into whichever constant comes next. |
| 2506 | // Level-spelling channels (canonicity §10.6) drain on the same |
| 2507 | // boundary — the decompiler's ctor-scoped window installs them per |
| 2508 | // constructor. |
| 2509 | let arena = std::mem::take(&mut cache.arena); |
| 2510 | let surgery_sharing = std::mem::take(&mut cache.surgery_sharing); |
| 2511 | let meta_univs: Vec<Arc<Univ>> = |
| 2512 | std::mem::take(&mut cache.meta_univs).into_iter().collect(); |
| 2513 | let univ_patches = std::mem::take(&mut cache.univ_patches); |
| 2514 | cache.arena_roots.clear(); |
| 2515 | cache.exprs.clear(); |
| 2516 | |
| 2517 | let name_addr = compile_name(&ctor.cnst.name, stt); |
| 2518 | let lvl_addrs: Vec<Address> = |
| 2519 | univ_params.iter().map(|n| compile_name(n, stt)).collect(); |
| 2520 | let induct_addr = compile_name(&ctor.induct, stt); |
| 2521 |
no test coverage detected