diff --git a/crates/perry-codegen/src/collectors/segview.rs b/crates/perry-codegen/src/collectors/segview.rs index 990f31b646..019b857ef2 100644 --- a/crates/perry-codegen/src/collectors/segview.rs +++ b/crates/perry-codegen/src/collectors/segview.rs @@ -958,10 +958,17 @@ fn describe(v: &SegViewVerdict) -> String { // labels correct and avoids duplicating any closure the body contains — a // duplicated `Expr::Closure` would carry a duplicate `FuncId`. -/// `PERRY_SEGVIEW=1`. **Default OFF**: the runtime's view entry points do not -/// exist yet, so an on-by-default rewrite would emit calls that fail to link. +/// **Default ON.** `PERRY_SEGVIEW=0` opts out. +/// +/// It shipped default OFF because the runtime's view entry points did not +/// exist; #9870 landed them on main, and on claude-code the tier with #9893's +/// levers is -14 % CPU and -30…-42 MB peak RSS with identical output. +/// +/// The opt-out stays: a program whose loops the tier declines pays nothing, +/// but a switch that changes emitted code needs an off position that does not +/// require a rebuild of the compiler. pub fn segview_lowering_enabled() -> bool { - matches!(std::env::var("PERRY_SEGVIEW"), Ok(v) if !v.is_empty() && v != "0") + !matches!(std::env::var("PERRY_SEGVIEW"), Ok(v) if v == "0") } fn extern_call(name: &str, args: Vec) -> Expr { diff --git a/crates/perry-codegen/src/collectors/segview_tests.rs b/crates/perry-codegen/src/collectors/segview_tests.rs index 9783faf640..da42520b79 100644 --- a/crates/perry-codegen/src/collectors/segview_tests.rs +++ b/crates/perry-codegen/src/collectors/segview_tests.rs @@ -552,3 +552,27 @@ fn the_cursor_is_cleared_at_loop_exit() { other => panic!("no cursor clear after the loop: {other:?}"), } } + +/// The default is ON, and `PERRY_SEGVIEW=0` is the opt-out. +/// +/// Asserted rather than assumed because the switch is read through the +/// environment: a typo in the predicate that made it always-false would leave +/// every test above passing (they call the rewrite directly) while the tier +/// silently never fired in a real compile — the #9824 shape. +#[test] +fn the_lowering_is_on_by_default_and_zero_opts_out() { + use super::segview::segview_lowering_enabled; + // These mutate process-wide state, so they live in one test rather than + // three; `cargo test` runs test fns concurrently and separate tests would + // race on the same variable. + std::env::remove_var("PERRY_SEGVIEW"); + assert!( + segview_lowering_enabled(), + "unset must mean ON — that is what 'default on' means" + ); + std::env::set_var("PERRY_SEGVIEW", "0"); + assert!(!segview_lowering_enabled(), "`0` is the opt-out"); + std::env::set_var("PERRY_SEGVIEW", "1"); + assert!(segview_lowering_enabled(), "`1` stays on"); + std::env::remove_var("PERRY_SEGVIEW"); +}