use std::process::Command;
use std::sync::atomic::{AtomicU64, Ordering};
use std::time::{SystemTime, UNIX_EPOCH};
fn run_jit(src: &str) -> String {
static SEQ: AtomicU64 = AtomicU64::new(0);
let nanos = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_nanos();
let seq = SEQ.fetch_add(1, Ordering::Relaxed);
let path = std::env::temp_dir().join(format!(
"cljrs_variadic_jit_{}_{nanos}_{seq}.cljrs",
std::process::id()
));
std::fs::write(&path, src).expect("write script");
let output = Command::new(env!("CARGO_BIN_EXE_cljrs"))
.args(["--jit-threshold", "50", "run"])
.arg(&path)
.env("CLJRS_EAGER_LOWER", "1")
.output()
.expect("spawn cljrs");
let _ = std::fs::remove_file(&path);
assert!(
output.status.success(),
"cljrs exited with {:?}\nstderr:\n{}",
output.status,
String::from_utf8_lossy(&output.stderr)
);
String::from_utf8(output.stdout).expect("utf8 stdout")
}
#[test]
fn variadic_fn_dispatches_correctly_under_jit() {
let src = r#"
(defn mixed [a b & xs] [a b (count xs) (first xs)])
(defn novar [& xs] (count xs))
(dotimes [i 10000]
(let [m (mixed 10 20 30 40 50)
z (novar)]
(when (= i 9999)
(println "mixed=" m "empty=" z))))
"#;
let out = run_jit(src);
assert!(
out.contains("mixed= [10 20 3 30]"),
"variadic rest args were not packed correctly; got:\n{out}"
);
assert!(
out.contains("empty= 0"),
"empty varargs did not bind an empty rest; got:\n{out}"
);
}