39b674c1ec
Adds `ail migrate-modes <file>` (a throwaway CLI subcommand) and the AST walker `ailang_core::ast::for_each_fn_type_mut` it drives: parse a .ail, map every bare/Implicit fn-type slot to Own, preserve explicit Own/Borrow, print back. Semantically invisible today (PartialEq treats Implicit == Own), but it materialises the modes so the post-cutover parser — which will reject bare slots — accepts the migrated corpus. Both are throwaway: removed in task 4 once ParamMode::Implicit is deleted (the closure references Implicit and would not compile). RED-first: migrate_modes.rs failed to compile (missing walker) before for_each_fn_type_mut was added. Additive; full workspace suite green. refs #55
28 lines
1.2 KiB
Rust
28 lines
1.2 KiB
Rust
//! Throwaway migration-tool test (spec 0062). Asserts the
|
|
//! parse→Implicit↦Own→print pass materialises bare slots as `(own …)`
|
|
//! and leaves explicit `(borrow …)` untouched. Deleted in the cutover.
|
|
use ailang_surface::{parse, print};
|
|
use ailang_core::ast::ParamMode;
|
|
|
|
/// Re-implements the tool's core transform for the unit test so the
|
|
/// assertion does not depend on the CLI I/O wrapper.
|
|
fn migrate_text(src: &str) -> String {
|
|
let mut m = parse(src).expect("parse");
|
|
ailang_core::ast::for_each_fn_type_mut(&mut m, &mut |params_len, pm, rm| {
|
|
pm.resize(params_len, ParamMode::Own);
|
|
for x in pm.iter_mut() {
|
|
if matches!(x, ParamMode::Implicit) { *x = ParamMode::Own; }
|
|
}
|
|
if matches!(rm, ParamMode::Implicit) { *rm = ParamMode::Own; }
|
|
});
|
|
print(&m)
|
|
}
|
|
|
|
#[test]
|
|
fn bare_slot_becomes_own_borrow_preserved() {
|
|
let src = "(module m\n (fn f\n (doc \"d\")\n (type (fn-type (params (con Int) (borrow (con Int))) (ret (con Int))))\n (params x y)\n (body x)))\n";
|
|
let out = migrate_text(src);
|
|
assert!(out.contains("(params (own (con Int)) (borrow (con Int)))"), "got: {out}");
|
|
assert!(out.contains("(ret (own (con Int)))"), "got: {out}");
|
|
}
|