diff --git a/crates/ailang-check/src/mono.rs b/crates/ailang-check/src/mono.rs index 58116b7..b4ef2b1 100644 --- a/crates/ailang-check/src/mono.rs +++ b/crates/ailang-check/src/mono.rs @@ -53,7 +53,7 @@ use ailang_core::ast::{Arm, ClassDef, ConstDef, Def, FnDef as AstFnDef, InstanceDef, Pattern, Term, Type}; use ailang_core::workspace::Workspace; -use crate::{CtorRef, Result}; +use crate::Result; use indexmap::IndexMap; use std::collections::{BTreeMap, BTreeSet}; @@ -157,14 +157,14 @@ pub fn monomorphise_workspace(ws: &Workspace) -> Result { let env = build_workspace_env(&ws_owned); // re-build: ws_owned has new defs. let module_names: Vec = ws_owned.modules.keys().cloned().collect(); for mname in &module_names { - // Per-module ctor_index overlay — see - // [`apply_per_module_ctor_index_overlay`] for rationale. + // Per-module env.types overlay — see + // [`apply_per_module_types_overlay`] for rationale. // Mirrors the overlay applied in // `collect_targets_workspace_wide` so the rewrite-phase // residual replay produces the same residual list as the // collection-phase walk (cursor alignment depends on it). let mut env_mod = env.clone(); - apply_per_module_ctor_index_overlay(&mut env_mod, &ws_owned, mname); + apply_per_module_types_overlay(&mut env_mod, &ws_owned, mname); let n_defs = ws_owned.modules[mname].defs.len(); for i in 0..n_defs { let ordered: Vec> = { @@ -227,14 +227,14 @@ fn collect_targets_workspace_wide( ) -> Result> { let mut out: Vec = Vec::new(); for (mname, m) in &ws.modules { - // Per-module ctor_index overlay — see - // [`apply_per_module_ctor_index_overlay`] for rationale. The - // env arriving here is workspace-flat (via `build_check_env`); - // synth's `Pattern::Ctor` resolution requires per-module - // shape to keep the qualified-type-name comparison intact - // for cross-module ctor patterns. + // Per-module env.types overlay — see + // [`apply_per_module_types_overlay`] for rationale. The env + // arriving here is workspace-flat (via `build_check_env`); + // synth's `Term::Ctor` arm needs the per-module shape so a + // bare canonical type-name resolves to the current module's + // TypeDef rather than a same-named entry from another module. let mut env_mod = env.clone(); - apply_per_module_ctor_index_overlay(&mut env_mod, ws, mname); + apply_per_module_types_overlay(&mut env_mod, ws, mname); for d in &m.defs { match d { Def::Fn(f) => { @@ -377,56 +377,33 @@ pub(crate) fn mono_target_key(t: &MonoTarget) -> (String, String, String) { /// (`collect_mono_targets`, `collect_residuals_ordered`) clone the env /// and apply per-fn overlay (current_module, globals from /// module_globals, imports from module_imports, rigid_vars) plus the -/// per-module ctor/type overlay -/// (see [`apply_per_module_ctor_index_overlay`]). +/// per-module env.types overlay +/// (see [`apply_per_module_types_overlay`]). pub fn build_workspace_env(ws: &Workspace) -> crate::Env { crate::build_check_env(ws) } -/// Iter 22c (sibling of commit 5c5180f for `env.ctor_index`): -/// rebuild `env.types` AND `env.ctor_index` to contain ONLY the -/// types and ctors declared in `module_name`'s `Def::Type`s, -/// mirroring `check_in_workspace`'s per-module overlay at -/// `crates/ailang-check/src/lib.rs:1257-1287`. +/// Rebuild `env.types` to contain only the TypeDefs declared in +/// `module_name`'s `Def::Type`s, mirroring `check_in_workspace`'s +/// per-module overlay at `crates/ailang-check/src/lib.rs:1234`. /// -/// `build_workspace_env` (via `build_check_env`) leaves both fields -/// workspace-flat. Two synth paths need the per-module shape: +/// The mono pass re-runs `crate::synth` on every fn body to +/// recover residual class constraints. `synth`'s `Term::Ctor` arm +/// looks up bare canonical `type_name`s via `env.types.get(name)` +/// (lib.rs:1967); without this overlay, `env.types` would be the +/// workspace-flat map built by `build_workspace_env`, and a bare +/// `type_name` in module A could resolve to a same-named TypeDef +/// from module B. The overlay restores per-module bare-name +/// scoping. /// -/// * `Pattern::Ctor` resolution (lib.rs:2486-2526) does a -/// local-first `ctor_index` lookup followed by an imports-fallback -/// that produces a *qualified* `resolved_type_name` (`Mod.Type`). -/// With a flat `ctor_index`, a cross-module ctor pattern resolves -/// locally and yields a bare type name, mismatching the qualified -/// scrutinee type and firing `CheckError::PatternTypeMismatch`. -/// * `Term::Ctor` synth (lib.rs:1962-2026) does a local-first -/// `env.types` lookup followed by an imports-fallback that -/// produces a qualified `result_type_name`. With a flat `env.types`, -/// a `Term::Ctor` against a prelude (or imported) type resolves -/// locally and yields a bare scrutinee type — which then mismatches -/// the qualified `Pattern::Ctor` `resolved_type_name` produced by -/// the per-module-cleared `ctor_index`. -/// -/// Both fields must be cleared together so the two synth paths agree -/// on bare-vs-qualified naming. Mirrors the pattern in -/// `check_in_workspace`, which clears and rebuilds both for the -/// same reason. -/// -/// Caller-contract assumption: the workspace has already typechecked, -/// so duplicate type or ctor names within a single module cannot -/// occur (the fail-fast `DuplicateType` / `DuplicateCtor` diagnostics -/// in `check_in_workspace` would have surfaced). -fn apply_per_module_ctor_index_overlay(env: &mut crate::Env, ws: &Workspace, module_name: &str) { +/// Caller-contract assumption: the workspace has already +/// typechecked, so duplicate type names within a single module +/// cannot occur. +fn apply_per_module_types_overlay(env: &mut crate::Env, ws: &Workspace, module_name: &str) { env.types.clear(); - env.ctor_index.clear(); if let Some(m) = ws.modules.get(module_name) { for d in &m.defs { if let Def::Type(td) = d { - for c in &td.ctors { - env.ctor_index.insert( - c.name.clone(), - CtorRef { type_name: td.name.clone() }, - ); - } env.types.insert(td.name.clone(), td.clone()); } }