//! Signature-level mode rejects added by spec 0062: borrow-return //! (`(ret (borrow T))`) and borrow-over-value (`(borrow value-type)`). //! CLI-boundary E2E (the project's reject-pin pattern): the diagnostic //! is the observable exit behaviour of `ail check`. use std::path::{Path, PathBuf}; use std::process::Command; fn repo_root() -> PathBuf { Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap().parent().unwrap().to_path_buf() } fn check_rejects_with(fixture: &str, code: &str) { let path = repo_root().join("examples").join(fixture); let out = Command::new(env!("CARGO_BIN_EXE_ail")) .arg("check").arg(&path).output().expect("ail check spawn"); assert!(!out.status.success(), "expected `ail check {fixture}` to REJECT, but it passed: stdout={}", String::from_utf8_lossy(&out.stdout)); let stderr = String::from_utf8_lossy(&out.stderr); assert!(stderr.contains(code), "expected code `{code}`, got: {stderr}"); } /// `(ret (borrow T))` is rejected with code `borrow-return-not-permitted`. #[test] fn borrow_return_is_rejected() { check_rejects_with("borrow_return_reject.ail", "borrow-return-not-permitted"); } /// `(borrow value-type)` is rejected with code `borrow-over-value`. #[test] fn borrow_over_value_is_rejected() { check_rejects_with("borrow_value_reject.ail", "borrow-over-value"); } /// The own-return-provenance / regime-A shapes stay rejected by /// `consume-while-borrowed` after the schema deletion (spec 0062 /// already-green pins — these are NOT new checks). #[test] fn own_return_provenance_still_rejected() { for f in [ "own_return_provenance_reject.ail", "own_return_provenance_let.ail", "own_return_provenance_ctor.ail", ] { check_rejects_with(f, "consume-while-borrowed"); } }