makepad/libs/relax/compiler/tests/t8.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

100 lines
2 KiB
Rust

// Relax closures: captures by reference and by move, Fn-bound inference, impl Fn params,
// calls through references, nested closures, closures in generic instances.
fn apply<F: Fn(i64) -> i64>(f: F, x: i64) -> i64 {
f(x)
}
fn apply_mut<F>(mut f: F, n: i64)
where
F: FnMut(i64),
{
let mut i = 0;
while i < n {
f(i);
i += 1;
}
}
fn apply_ref(f: &dyn_free::Adder, x: i64) -> i64 {
f.add(x)
}
mod dyn_free {
pub struct Adder {
pub k: i64,
}
impl Adder {
pub fn add(&self, x: i64) -> i64 {
x + self.k
}
}
}
fn twice(f: impl Fn(i64) -> i64, x: i64) -> i64 {
f(f(x))
}
fn call_by_ref<F: Fn(i64) -> i64>(f: &F, x: i64) -> i64 {
f(x)
}
fn map_pair<T: Copy, U, F: Fn(T) -> U>(a: T, b: T, f: F) -> (U, U) {
(f(a), f(b))
}
fn make_adder(k: i64) -> i64 {
let add = move |x: i64| x + k;
add(1) + add(2)
}
#[test]
fn captures() {
let k = 10;
assert_eq!(apply(|x| x + k, 5), 15);
let mut sum = 0;
apply_mut(|i| sum += i, 5);
assert_eq!(sum, 10);
let a = dyn_free::Adder { k: 3 };
assert_eq!(apply_ref(&a, 4), 7);
assert_eq!(twice(|x| x * k, 2), 200);
let m = 7;
let f = |x: i64| x - m;
assert_eq!(call_by_ref(&f, 10), 3);
assert_eq!(f(1), -6);
let (p, q) = map_pair(2, 3, |v: i64| v * v + k);
assert_eq!(p, 14);
assert_eq!(q, 19);
assert_eq!(make_adder(100), 203);
}
#[test]
fn nested_and_mutation() {
let mut count = 0;
let mut bump = |n: i64| {
let mut inner = |m: i64| count += m;
inner(n);
inner(1);
};
bump(5);
bump(2);
assert_eq!(count, 9);
let base = 1000;
let g = |x: i64| {
let h = |y: i64| y + base;
h(x) * 2
};
assert_eq!(g(1), 2002);
}
#[test]
fn fn_items_and_pointers() {
fn sq(x: i64) -> i64 {
x * x
}
assert_eq!(apply(sq, 9), 81);
let p: fn(i64) -> i64 = sq;
assert_eq!(apply(p, 4), 16);
let c: fn(i64) -> i64 = |x| x + 1;
assert_eq!(c(1), 2);
}