iter ct.3.2: mono overlay narrowed to env.types only; rename to apply_per_module_types_overlay

This commit is contained in:
2026-05-11 09:37:07 +02:00
parent 05d0cce5c7
commit 91498016b2
+28 -51
View File
@@ -53,7 +53,7 @@
use ailang_core::ast::{Arm, ClassDef, ConstDef, Def, FnDef as AstFnDef, InstanceDef, Pattern, Term, Type}; use ailang_core::ast::{Arm, ClassDef, ConstDef, Def, FnDef as AstFnDef, InstanceDef, Pattern, Term, Type};
use ailang_core::workspace::Workspace; use ailang_core::workspace::Workspace;
use crate::{CtorRef, Result}; use crate::Result;
use indexmap::IndexMap; use indexmap::IndexMap;
use std::collections::{BTreeMap, BTreeSet}; use std::collections::{BTreeMap, BTreeSet};
@@ -157,14 +157,14 @@ pub fn monomorphise_workspace(ws: &Workspace) -> Result<Workspace> {
let env = build_workspace_env(&ws_owned); // re-build: ws_owned has new defs. let env = build_workspace_env(&ws_owned); // re-build: ws_owned has new defs.
let module_names: Vec<String> = ws_owned.modules.keys().cloned().collect(); let module_names: Vec<String> = ws_owned.modules.keys().cloned().collect();
for mname in &module_names { for mname in &module_names {
// Per-module ctor_index overlay — see // Per-module env.types overlay — see
// [`apply_per_module_ctor_index_overlay`] for rationale. // [`apply_per_module_types_overlay`] for rationale.
// Mirrors the overlay applied in // Mirrors the overlay applied in
// `collect_targets_workspace_wide` so the rewrite-phase // `collect_targets_workspace_wide` so the rewrite-phase
// residual replay produces the same residual list as the // residual replay produces the same residual list as the
// collection-phase walk (cursor alignment depends on it). // collection-phase walk (cursor alignment depends on it).
let mut env_mod = env.clone(); 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(); let n_defs = ws_owned.modules[mname].defs.len();
for i in 0..n_defs { for i in 0..n_defs {
let ordered: Vec<Option<MonoTarget>> = { let ordered: Vec<Option<MonoTarget>> = {
@@ -227,14 +227,14 @@ fn collect_targets_workspace_wide(
) -> Result<Vec<MonoTarget>> { ) -> Result<Vec<MonoTarget>> {
let mut out: Vec<MonoTarget> = Vec::new(); let mut out: Vec<MonoTarget> = Vec::new();
for (mname, m) in &ws.modules { for (mname, m) in &ws.modules {
// Per-module ctor_index overlay — see // Per-module env.types overlay — see
// [`apply_per_module_ctor_index_overlay`] for rationale. The // [`apply_per_module_types_overlay`] for rationale. The env
// env arriving here is workspace-flat (via `build_check_env`); // arriving here is workspace-flat (via `build_check_env`);
// synth's `Pattern::Ctor` resolution requires per-module // synth's `Term::Ctor` arm needs the per-module shape so a
// shape to keep the qualified-type-name comparison intact // bare canonical type-name resolves to the current module's
// for cross-module ctor patterns. // TypeDef rather than a same-named entry from another module.
let mut env_mod = env.clone(); 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 { for d in &m.defs {
match d { match d {
Def::Fn(f) => { 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 /// (`collect_mono_targets`, `collect_residuals_ordered`) clone the env
/// and apply per-fn overlay (current_module, globals from /// and apply per-fn overlay (current_module, globals from
/// module_globals, imports from module_imports, rigid_vars) plus the /// module_globals, imports from module_imports, rigid_vars) plus the
/// per-module ctor/type overlay /// per-module env.types overlay
/// (see [`apply_per_module_ctor_index_overlay`]). /// (see [`apply_per_module_types_overlay`]).
pub fn build_workspace_env(ws: &Workspace) -> crate::Env { pub fn build_workspace_env(ws: &Workspace) -> crate::Env {
crate::build_check_env(ws) crate::build_check_env(ws)
} }
/// Iter 22c (sibling of commit 5c5180f for `env.ctor_index`): /// Rebuild `env.types` to contain only the TypeDefs declared in
/// rebuild `env.types` AND `env.ctor_index` to contain ONLY the /// `module_name`'s `Def::Type`s, mirroring `check_in_workspace`'s
/// types and ctors declared in `module_name`'s `Def::Type`s, /// per-module overlay at `crates/ailang-check/src/lib.rs:1234`.
/// mirroring `check_in_workspace`'s per-module overlay at
/// `crates/ailang-check/src/lib.rs:1257-1287`.
/// ///
/// `build_workspace_env` (via `build_check_env`) leaves both fields /// The mono pass re-runs `crate::synth` on every fn body to
/// workspace-flat. Two synth paths need the per-module shape: /// 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 /// Caller-contract assumption: the workspace has already
/// local-first `ctor_index` lookup followed by an imports-fallback /// typechecked, so duplicate type names within a single module
/// that produces a *qualified* `resolved_type_name` (`Mod.Type`). /// cannot occur.
/// With a flat `ctor_index`, a cross-module ctor pattern resolves fn apply_per_module_types_overlay(env: &mut crate::Env, ws: &Workspace, module_name: &str) {
/// 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) {
env.types.clear(); env.types.clear();
env.ctor_index.clear();
if let Some(m) = ws.modules.get(module_name) { if let Some(m) = ws.modules.get(module_name) {
for d in &m.defs { for d in &m.defs {
if let Def::Type(td) = d { 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()); env.types.insert(td.name.clone(), td.clone());
} }
} }