fix: mono pass seeds env.imports for qualified cross-module refs in class workspace

This commit is contained in:
2026-05-10 01:23:07 +02:00
parent 2bf827f600
commit a9c685ded8
2 changed files with 36 additions and 0 deletions
+8
View File
@@ -2466,6 +2466,14 @@ pub struct Env {
/// Top-level symbol table per module of the workspace. /// Top-level symbol table per module of the workspace.
/// `check_in_workspace` populates this from `build_module_globals`. /// `check_in_workspace` populates this from `build_module_globals`.
pub module_globals: BTreeMap<String, IndexMap<String, Type>>, pub module_globals: BTreeMap<String, IndexMap<String, Type>>,
/// 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<String, BTreeMap<String, String>>,
/// Iter 15a: ADT type definitions per module of the workspace. Used /// Iter 15a: ADT type definitions per module of the workspace. Used
/// to resolve qualified type references (`module.Type` in /// to resolve qualified type references (`module.Type` in
/// `Type::Con.name`) and qualified `Term::Ctor.type_name`, and to /// `Type::Con.name`) and qualified `Term::Ctor.type_name`, and to
+28
View File
@@ -385,6 +385,21 @@ pub fn build_workspace_env(ws: &Workspace) -> crate::Env {
.map(|(mname, g)| (mname.clone(), g.fns.clone())) .map(|(mname, g)| (mname.clone(), g.fns.clone()))
.collect(); .collect();
env.module_types = crate::build_module_types(ws); 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<String, String> = 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 // Workspace-wide class-method table: merge per module's
// ModuleGlobals.class_methods. // ModuleGlobals.class_methods.
@@ -477,6 +492,14 @@ pub fn collect_mono_targets(
env.globals.insert(n, t); 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<String, Type> = IndexMap::new(); let mut locals: IndexMap<String, Type> = IndexMap::new();
for (n, t) in f.params.iter().zip(param_tys.iter()) { 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); 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<String, Type> = IndexMap::new(); let mut locals: IndexMap<String, Type> = IndexMap::new();
for (n, t) in f.params.iter().zip(param_tys.iter()) { for (n, t) in f.params.iter().zip(param_tys.iter()) {