iter 22b.3.3: collect_mono_targets — synth-replay residual gathering

This commit is contained in:
2026-05-09 20:31:12 +02:00
parent c77fd1b85e
commit 89311ee20b
3 changed files with 222 additions and 3 deletions
+48
View File
@@ -111,6 +111,54 @@ fn mono_symbol_primitive_types_use_surface_form() {
assert_eq!(ailang_check::mono::mono_symbol("foo", &unit_ty), "foo#Unit");
}
/// Property: collect_mono_targets returns exactly the set of
/// fully-concrete `(class, method, type)` triples observed at
/// class-method call sites in a fn body, with the registry's
/// `defining_module` attached to each. The fixture's `main` calls
/// `show 42` once with `Int`, and the workspace declares
/// `instance Show Int` in the same module — the expected output is
/// a single MonoTarget naming `Show`, `show`, `Int`, and that
/// module.
#[test]
fn collect_mono_targets_single_concrete_call_site() {
use ailang_check::mono::collect_mono_targets;
let entry = examples_dir().join("test_22b2_instance_present.ail.json");
let ws = ailang_core::load_workspace(&entry).expect("load");
let diags = ailang_check::check_workspace(&ws);
assert!(diags.is_empty(), "fixture must typecheck: {:?}", diags);
// Build the workspace-wide env (class_methods, registry, ...)
// exactly as `check_in_workspace` does. The mono pass exposes
// this via `build_workspace_env`.
let env = ailang_check::mono::build_workspace_env(&ws);
// The fixture has one user fn — `main`. Locate it.
let main_module = ws.modules.get("test_22b2_instance_present").expect("module");
let main_fn = main_module
.defs
.iter()
.find_map(|d| match d {
ailang_core::ast::Def::Fn(f) if f.name == "main" => Some(f),
_ => None,
})
.expect("main fn");
let targets = collect_mono_targets(main_fn, "test_22b2_instance_present", &env)
.expect("collect");
assert_eq!(targets.len(), 1, "one target expected: {:?}", targets);
let t = &targets[0];
assert_eq!(t.class, "Show");
assert_eq!(t.method, "show");
assert!(
matches!(&t.type_, ailang_core::ast::Type::Con { name, args } if name == "Int" && args.is_empty()),
"type must be Int, got {:?}",
t.type_
);
assert_eq!(t.defining_module, "test_22b2_instance_present");
}
#[test]
fn mono_symbol_compound_type_uses_hash_suffix() {
// Compound types fall through to canonical type_hash with an