From a9c685ded83f97adc105c08406ecdda6106eb167 Mon Sep 17 00:00:00 2001 From: Brummel Date: Sun, 10 May 2026 01:23:07 +0200 Subject: [PATCH] fix: mono pass seeds env.imports for qualified cross-module refs in class workspace --- crates/ailang-check/src/lib.rs | 8 ++++++++ crates/ailang-check/src/mono.rs | 28 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/crates/ailang-check/src/lib.rs b/crates/ailang-check/src/lib.rs index 295bb8b..4dcb9f4 100644 --- a/crates/ailang-check/src/lib.rs +++ b/crates/ailang-check/src/lib.rs @@ -2466,6 +2466,14 @@ pub struct Env { /// Top-level symbol table per module of the workspace. /// `check_in_workspace` populates this from `build_module_globals`. pub module_globals: BTreeMap>, + /// Per-module import map: module-name → (alias-or-module-name → + /// actual-module-name). Sibling-shape to [`Self::module_globals`]; + /// populated only by [`crate::mono::build_workspace_env`] so the + /// mono pass's per-fn entry points can re-seed the local + /// [`Self::imports`] before re-running [`synth`] on a body. + /// `check_in_workspace` does not populate this — it has the module + /// in hand and seeds [`Self::imports`] directly. + pub module_imports: BTreeMap>, /// Iter 15a: ADT type definitions per module of the workspace. Used /// to resolve qualified type references (`module.Type` in /// `Type::Con.name`) and qualified `Term::Ctor.type_name`, and to diff --git a/crates/ailang-check/src/mono.rs b/crates/ailang-check/src/mono.rs index f212c72..f6f471e 100644 --- a/crates/ailang-check/src/mono.rs +++ b/crates/ailang-check/src/mono.rs @@ -385,6 +385,21 @@ pub fn build_workspace_env(ws: &Workspace) -> crate::Env { .map(|(mname, g)| (mname.clone(), g.fns.clone())) .collect(); env.module_types = crate::build_module_types(ws); + // Iter 22c (sibling of commit 13b36cc): per-module import maps so + // `collect_mono_targets` / `collect_residuals_ordered` can seed + // `env.imports` before re-running `synth`. Mirrors + // `check_in_workspace` (lib.rs:1147-1152). Scoped per-module + // because import aliases collide across modules — same shape as + // `env.module_globals`, unlike the workspace-wide flat tables for + // user ADTs (5c5180f). + for m in ws.modules.values() { + let mut import_map: BTreeMap = BTreeMap::new(); + for imp in &m.imports { + let key = imp.alias.clone().unwrap_or_else(|| imp.module.clone()); + import_map.insert(key, imp.module.clone()); + } + env.module_imports.insert(m.name.clone(), import_map); + } // Workspace-wide class-method table: merge per module's // ModuleGlobals.class_methods. @@ -477,6 +492,14 @@ pub fn collect_mono_targets( env.globals.insert(n, t); } } + // Iter 22c (sibling of commit 13b36cc): seed `env.imports` from + // the current module's import list so `synth`'s qualified-var + // path (lib.rs:1697) resolves `Mod.fn` references. Mirrors + // `check_in_workspace` (lib.rs:1147-1152). Per-module because + // aliases collide across modules. + if let Some(im) = env.module_imports.get(module_name).cloned() { + env.imports = im; + } let mut locals: IndexMap = IndexMap::new(); for (n, t) in f.params.iter().zip(param_tys.iter()) { @@ -827,6 +850,11 @@ pub(crate) fn collect_residuals_ordered( env.globals.insert(n, t); } } + // Iter 22c: same `env.imports` seeding as `collect_mono_targets` + // — see the comment there for rationale. + if let Some(im) = env.module_imports.get(module_name).cloned() { + env.imports = im; + } let mut locals: IndexMap = IndexMap::new(); for (n, t) in f.params.iter().zip(param_tys.iter()) {