iter 22b.3.3: fix — revert dead pub(crate), reuse build_module_types, drop defensive unwrap
Quality-review follow-up to 89311ee:
- Revert `substitute_rigids` to private. Task 3 does not call it; the
visibility bump was forward-looking for Task 4 (synthesise_mono_fn).
Task 4 will re-bump it in the same diff that uses it.
- Promote `build_module_types` to pub(crate); drop the inline
reimplementation in `mono::build_workspace_env`. Removes drift risk
between the two paths.
- Replace defensive `unwrap_or_default()` on `build_module_globals`
with `expect(...)` naming the pre-condition. Silent default violated
CLAUDE.md "no defensive validation in internal code paths".
- Add a one-line drift-risk reminder at the top of `build_workspace_env`
flagging that it and `check_in_workspace` both populate `Env`.
Build clean; all 5 typeclass_22b3 tests green; no workspace regressions.
This commit is contained in:
@@ -123,7 +123,7 @@ fn instantiate(forall_vars: &[String], body: &Type, counter: &mut u32) -> (Vec<T
|
||||
/// Substitutes named rigid vars throughout a type (used by
|
||||
/// `instantiate`). Unlike `Subst::apply`, this targets vars by name —
|
||||
/// it has no notion of metavar ids.
|
||||
pub(crate) fn substitute_rigids(t: &Type, mapping: &BTreeMap<String, Type>) -> Type {
|
||||
fn substitute_rigids(t: &Type, mapping: &BTreeMap<String, Type>) -> Type {
|
||||
match t {
|
||||
Type::Var { name } => mapping.get(name).cloned().unwrap_or_else(|| t.clone()),
|
||||
Type::Con { name, args } => Type::Con {
|
||||
@@ -874,7 +874,7 @@ pub fn check_and_lift(m: &Module) -> Result<(CheckedModule, Module)> {
|
||||
/// cross-module `Pattern::Ctor` fallback. Duplicate type / ctor errors
|
||||
/// inside a single module surface during the per-module body-check
|
||||
/// phase, not here.
|
||||
fn build_module_types(
|
||||
pub(crate) fn build_module_types(
|
||||
ws: &Workspace,
|
||||
) -> BTreeMap<String, IndexMap<String, TypeDef>> {
|
||||
let mut out: BTreeMap<String, IndexMap<String, TypeDef>> = BTreeMap::new();
|
||||
|
||||
@@ -171,6 +171,9 @@ pub(crate) fn mono_target_key(t: &MonoTarget) -> (String, String, String) {
|
||||
/// declared param types. Module-resident fns are still needed
|
||||
/// for non-class-method calls inside instance bodies.
|
||||
pub fn build_workspace_env(ws: &Workspace) -> crate::Env {
|
||||
// Drift risk: this fn and `crate::check_in_workspace` both
|
||||
// populate `crate::Env`. If `synth` starts reading a new `Env`
|
||||
// field, update both paths.
|
||||
let mut env = crate::Env::default();
|
||||
crate::builtins::install(&mut env);
|
||||
env.workspace_registry = ws.registry.clone();
|
||||
@@ -180,30 +183,14 @@ pub fn build_workspace_env(ws: &Workspace) -> crate::Env {
|
||||
// env shape is interchangeable. `build_module_globals` may
|
||||
// surface duplicate-def errors for malformed workspaces; the
|
||||
// mono pass's pre-condition is that typecheck has already
|
||||
// succeeded, so any error here means a caller violated that
|
||||
// contract — fall back to an empty per-module table to keep
|
||||
// this builder infallible.
|
||||
// succeeded, so a failure here is a caller-contract violation.
|
||||
let module_globals_index = crate::build_module_globals(ws)
|
||||
.unwrap_or_default();
|
||||
.expect("build_module_globals: pre-condition (typecheck succeeded) violated");
|
||||
env.module_globals = module_globals_index
|
||||
.iter()
|
||||
.map(|(mname, g)| (mname.clone(), g.fns.clone()))
|
||||
.collect();
|
||||
env.module_types = ws
|
||||
.modules
|
||||
.iter()
|
||||
.map(|(mname, m)| {
|
||||
let tys: IndexMap<String, ailang_core::ast::TypeDef> = m
|
||||
.defs
|
||||
.iter()
|
||||
.filter_map(|d| match d {
|
||||
Def::Type(td) => Some((td.name.clone(), td.clone())),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
(mname.clone(), tys)
|
||||
})
|
||||
.collect();
|
||||
env.module_types = crate::build_module_types(ws);
|
||||
|
||||
// Workspace-wide class-method table: merge per module's
|
||||
// ModuleGlobals.class_methods.
|
||||
|
||||
Reference in New Issue
Block a user