Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions crates/perry-codegen/src/collectors/segview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>) -> Expr {
Expand Down
24 changes: 24 additions & 0 deletions crates/perry-codegen/src/collectors/segview_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}