makepad/libs/relax/compiler/tests/extended_temp_order.rs
Admin b22a714840 makepad run: the Rust JIT (libs/relax) and makepad-remote
The JIT that runs makepad apps from source: lexer, front end, type checker,
lazy borrow checker (Gandalf; `--check-first` opts in), codegen, session and
warm/cold caches keyed by compiler stamp, provided crates bound late,
startup images, live patching. User-facing name is `makepad run` (binary
`makepad`, MAKEPAD_RUN_* env, ~/.makepad-run); libs/relax stays the internal
library name. `makepad check` reports rustc-style diagnostics with rustc
error codes and checks a whole workspace (`--workspace`). Runs on macOS,
Linux, Windows and Android. makepad-remote: one tool schema for apps and the
WM (app/1): grabs, captures, traces, frame profiles and tweaks.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 12:26:21 +02:00

75 lines
2.3 KiB
Rust

// `let`-extended temporaries (`let r = R { c: &D(..) };`, `let x = &D(..);`) drop in reverse
// declaration order together with the block's locals: after the locals declared later, before
// the `let`'s own bindings and earlier locals (rustc schedules the temporary's drop when the
// initializer makes it). Relax dropped them after every local of the block (silent order bug,
// tests/ui closures/2229_closure_analysis/preserve_field_drop_order2.rs). Sequences = rustc.
use std::cell::RefCell;
thread_local! { static LOG: RefCell<Vec<String>> = RefCell::new(Vec::new()); }
fn take() -> String { LOG.with(|l| std::mem::take(&mut *l.borrow_mut())).join(",") }
struct D(&'static str);
impl Drop for D { fn drop(&mut self) { LOG.with(|l| l.borrow_mut().push(self.0.to_string())); } }
struct R<'a> { c: &'a D, d: &'a D }
fn blocks() {
let _a = D("a");
let r = R { c: &D("ext1"), d: &D("ext1b") };
let _b = D("b");
let x = &D("ext2");
let _c = D("c");
{
let _i = D("i");
let y = &D("ext3");
let _j = D("j");
let _ = y.0;
}
let _ = (r.c.0, r.d.0, x.0);
}
fn early(n: u32) -> u32 {
let _a = D("ea");
let r = R { c: &D("e1"), d: &D("e2") };
let _b = D("eb");
if n == 1 { return 1; }
let x = &D("e3");
let _c = D("ec");
if n == 2 { return 2; }
let _ = (r.c.0, r.d.0, x.0);
0
}
fn in_loop() {
let mut i = 0;
loop {
let _l = D("l");
let y = &D("lt");
let _m = D("m");
i += 1;
if i == 2 { break; }
let _ = y.0;
}
}
fn unwinds() {
let _a = D("ua");
let _x = &D("ut");
let _b = D("ub");
panic!("p");
}
#[test]
fn extended_temps_in_declaration_order() {
blocks();
assert_eq!(take(), "j,ext3,i,c,ext2,b,ext1b,ext1,a");
let mut s = Vec::new();
for n in 0..3 { early(n); s.push(take()); }
assert_eq!(s, ["ec,e3,eb,e2,e1,ea", "eb,e2,e1,ea", "ec,e3,eb,e2,e1,ea"]);
in_loop();
assert_eq!(take(), "m,lt,l,m,lt,l");
std::panic::set_hook(Box::new(|_| {}));
let _ = std::panic::catch_unwind(|| unwinds());
assert_eq!(take(), "ub,ut,ua");
{
let (a, b) = (&D("t1"), D("v1"));
let s: &[D] = &[D("s1"), D("s2")];
let _k = D("k");
let _ = (a.0, b.0, s.len());
}
assert_eq!(take(), "k,s1,s2,v1,t1");
}