diff --git a/crates/ailang-core/src/workspace.rs b/crates/ailang-core/src/workspace.rs index d666140..841e6e7 100644 --- a/crates/ailang-core/src/workspace.rs +++ b/crates/ailang-core/src/workspace.rs @@ -900,8 +900,9 @@ mod tests { // it. Loading any well-formed workspace must result in // `ws.modules["prelude"]` being present with the Ordering // type def. + let manifest_dir = env!("CARGO_MANIFEST_DIR"); let workspace_root = - std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../.."); + Path::new(manifest_dir).parent().unwrap().parent().unwrap(); let entry = workspace_root.join("examples").join("ws_main.ail.json"); let ws = load_workspace(&entry).expect("load workspace"); @@ -921,6 +922,27 @@ mod tests { ); } + #[test] + fn user_module_named_prelude_is_rejected() { + // Iter 23.1: the loader auto-injects a module named "prelude", + // so a user module that also claims that name would collide + // silently. The collision is caught explicitly with + // `ReservedModuleName`. + let dir = tmp_dir("prelude_collision"); + write_module(&dir, "prelude", &[]); + let entry = dir.join("prelude.ail.json"); + + let err = load_workspace(&entry).expect_err("must reject user prelude"); + match err { + WorkspaceLoadError::ReservedModuleName { name } => { + assert_eq!(name, "prelude"); + } + other => panic!( + "expected ReservedModuleName, got: {other:?}" + ), + } + } + #[test] fn detects_import_cycle() { let dir = tmp_dir("cycle");