iter 23.1.3 fixup: cover AmbiguousType branch with cross-module test
This commit is contained in:
@@ -3793,6 +3793,88 @@ mod tests {
|
||||
assert!(diags.is_empty(), "expected green; got {diags:?}");
|
||||
}
|
||||
|
||||
/// Iter 23.1: the new bare-type-name imports-fallback in
|
||||
/// `Term::Ctor` synth (symmetric to `Pattern::Ctor`'s Iter-15a
|
||||
/// fallback) must report `ambiguous-type` when two imported
|
||||
/// modules each declare a type with the same bare name, so that
|
||||
/// a future fixture importing two prelude-shaped modules cannot
|
||||
/// silently resolve to one of them.
|
||||
#[test]
|
||||
fn cross_module_term_ctor_ambiguous_type_errors() {
|
||||
// Two different libs, each declaring a type `T` (intentional clash)
|
||||
// with a single ctor each.
|
||||
let lib_a = Module {
|
||||
schema: SCHEMA.into(),
|
||||
name: "lib_a".into(),
|
||||
imports: vec![],
|
||||
defs: vec![Def::Type(TypeDef {
|
||||
name: "T".into(),
|
||||
vars: vec![],
|
||||
ctors: vec![Ctor { name: "MkA".into(), fields: vec![] }],
|
||||
doc: None,
|
||||
drop_iterative: false,
|
||||
})],
|
||||
};
|
||||
let lib_b = Module {
|
||||
schema: SCHEMA.into(),
|
||||
name: "lib_b".into(),
|
||||
imports: vec![],
|
||||
defs: vec![Def::Type(TypeDef {
|
||||
name: "T".into(),
|
||||
vars: vec![],
|
||||
ctors: vec![Ctor { name: "MkB".into(), fields: vec![] }],
|
||||
doc: None,
|
||||
drop_iterative: false,
|
||||
})],
|
||||
};
|
||||
let consumer = Module {
|
||||
schema: SCHEMA.into(),
|
||||
name: "use_both".into(),
|
||||
imports: vec![
|
||||
Import { module: "lib_a".into(), alias: None },
|
||||
Import { module: "lib_b".into(), alias: None },
|
||||
],
|
||||
defs: vec![fn_def(
|
||||
"f",
|
||||
Type::Fn {
|
||||
params: vec![],
|
||||
ret: Box::new(Type::int()),
|
||||
effects: vec![],
|
||||
param_modes: vec![],
|
||||
ret_mode: ParamMode::Implicit,
|
||||
},
|
||||
vec![],
|
||||
// Bare type_name `T` — both lib_a and lib_b match.
|
||||
Term::Match {
|
||||
scrutinee: Box::new(Term::Ctor {
|
||||
type_name: "T".into(),
|
||||
ctor: "MkA".into(),
|
||||
args: vec![],
|
||||
}),
|
||||
arms: vec![Arm {
|
||||
pat: Pattern::Wild,
|
||||
body: Term::Lit { lit: Literal::Int { value: 0 } },
|
||||
}],
|
||||
},
|
||||
)],
|
||||
};
|
||||
let mut modules = BTreeMap::new();
|
||||
modules.insert("lib_a".into(), lib_a);
|
||||
modules.insert("lib_b".into(), lib_b);
|
||||
modules.insert("use_both".into(), consumer);
|
||||
let ws = Workspace {
|
||||
entry: "use_both".into(),
|
||||
modules,
|
||||
root_dir: std::path::PathBuf::from("."),
|
||||
registry: ailang_core::workspace::Registry::default(),
|
||||
};
|
||||
let diags = check_workspace(&ws);
|
||||
assert!(
|
||||
diags.iter().any(|d| d.code == "ambiguous-type"),
|
||||
"expected ambiguous-type diagnostic; got {diags:?}"
|
||||
);
|
||||
}
|
||||
|
||||
/// Iter 23.1: the prelude module is implicitly imported into
|
||||
/// every user module. A user module that pattern-matches on
|
||||
/// `LT` / `EQ` / `GT` without an explicit
|
||||
|
||||
Reference in New Issue
Block a user