iter 22b.2.8: fix — fold double-match, IndexMap parity, broader contract test
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
//! (class methods register into module globals) and is extended by
|
||||
//! Tasks 9 (`missing-constraint`) and 10 (`no-instance`).
|
||||
|
||||
use ailang_core::ast::Type;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
fn examples_dir() -> PathBuf {
|
||||
@@ -42,3 +43,87 @@ fn class_method_is_in_module_globals() {
|
||||
"class method `show` must remember its class is `Show`"
|
||||
);
|
||||
}
|
||||
|
||||
/// Property protected: the registered `ClassMethodEntry` carries the
|
||||
/// full metadata Tasks 9 / 10 need — the defining module (so the
|
||||
/// typecheck arms can find the matching `Registry` entries) and the
|
||||
/// declared method signature (so a residual class constraint can be
|
||||
/// built by instantiating the class param at the call site). The
|
||||
/// fixture declares `class Show a { show: a -> Str }`, so the
|
||||
/// recovered `method_ty` must be exactly `Type::Var "a" -> Type::Con
|
||||
/// "Str"` with empty effects.
|
||||
#[test]
|
||||
fn class_method_entry_carries_full_metadata() {
|
||||
let entry = examples_dir().join("test_22b2_class_method_lookup.ail.json");
|
||||
let ws = ailang_core::workspace::load_workspace(&entry)
|
||||
.expect("workspace must load");
|
||||
let globals = ailang_check::build_module_globals(&ws)
|
||||
.expect("globals build");
|
||||
let mod_globals = globals
|
||||
.get("test_22b2_class_method_lookup")
|
||||
.expect("module globals present");
|
||||
let cm_entry = mod_globals
|
||||
.class_method("show")
|
||||
.expect("class method `show` must be registered");
|
||||
|
||||
assert_eq!(
|
||||
cm_entry.defining_module, "test_22b2_class_method_lookup",
|
||||
"defining_module must point at the module that declared the class"
|
||||
);
|
||||
assert_eq!(
|
||||
cm_entry.class_param, "a",
|
||||
"class_param must be the class's single type parameter name"
|
||||
);
|
||||
|
||||
match &cm_entry.method_ty {
|
||||
Type::Fn {
|
||||
params,
|
||||
ret,
|
||||
effects,
|
||||
..
|
||||
} => {
|
||||
assert_eq!(
|
||||
params.len(),
|
||||
1,
|
||||
"method `show` must have exactly one parameter"
|
||||
);
|
||||
match ¶ms[0] {
|
||||
Type::Var { name } => assert_eq!(
|
||||
name, "a",
|
||||
"param type must be the class param `a`, not `{}`",
|
||||
name
|
||||
),
|
||||
other => panic!(
|
||||
"param type must be `Type::Var \"a\"`, got {:?}",
|
||||
other
|
||||
),
|
||||
}
|
||||
match ret.as_ref() {
|
||||
Type::Con { name, args } => {
|
||||
assert_eq!(
|
||||
name, "Str",
|
||||
"return type must be `Str`, got `{}`",
|
||||
name
|
||||
);
|
||||
assert!(
|
||||
args.is_empty(),
|
||||
"return type `Str` must take no args"
|
||||
);
|
||||
}
|
||||
other => panic!(
|
||||
"return type must be `Type::Con \"Str\"`, got {:?}",
|
||||
other
|
||||
),
|
||||
}
|
||||
assert!(
|
||||
effects.is_empty(),
|
||||
"method `show` must have empty effects, got {:?}",
|
||||
effects
|
||||
);
|
||||
}
|
||||
other => panic!(
|
||||
"method_ty must be `Type::Fn`, got {:?}",
|
||||
other
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user