makepad/tools/run/tests/builtins.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

107 lines
3.6 KiB
Rust

// Relax's native built-in macros (src/builtins.rs). Expected values come from rustc with the
// real proc macros (makepad-live-id / makepad-script-derive); the differential harness that
// produced them: local/agent_state/fast-rust/tools/builtins/diff.sh.
// run (the `makepad` loader links makepad's id! macros): MAKEPAD_RUN_STD=libs/relax/compiler/std makepad test tools/run/tests/builtins.rs
#[derive(Clone, Copy, PartialEq)]
pub struct LiveId(pub u64);
impl LiveId {
pub const fn from_num(seed: u64, num: u64) -> Self {
let b = num.to_be_bytes();
let mut x = seed;
let mut i = 0;
while i < 8 {
x = x.overflowing_add(b[i] as u64).0;
x ^= x >> 32;
x = x.overflowing_mul(0xd6e8_feb8_6659_fd93).0;
x ^= x >> 32;
x = x.overflowing_mul(0xd6e8_feb8_6659_fd93).0;
x ^= x >> 32;
i += 1;
}
Self(x & 0x0000_3fff_ffff_ffff)
}
}
fn pick(x: LiveId) -> u32 {
match x {
id!(apple) => 1,
id!(banana) => 2,
_ => 3,
}
}
mod inner {
pub fn mp() -> &'static str {
module_path!()
}
}
#[test]
fn id_family_matches_rustc() {
let xs: [LiveId; 14] = [
id!(apple), id!(), id!(r#type), id!($array), id!(a_b_c), id!(fn), id!(Self), id!(_),
live_id!(x0), live_id!(draw_bg), some_id!(foo).unwrap(), id!(z9),
live_id!(very_long_identifier_name_for_hashing), id!(0),
];
let want: [u64; 14] = [
24341239519098, 0, 30568617325874, 49353809276448, 49434654882476, 55012217286103, 47616252309034,
20723672253185, 60936781914028, 18320054578807, 21591109008026, 27308275125783, 585744625588, 45978426977841,
];
let mut i = 0;
while i < 14 {
assert!(xs[i].0 == want[i]);
i += 1;
}
let a = ids!(a.b.c);
assert!(a.len() == 3 && a[0].0 == 35342219466370 && a[1].0 == 24818598661546 && a[2].0 == 29102912674847);
let b = ids!(one.(id!(two)).three);
assert!(b[0].0 == 4139370007011 && b[1].0 == 10498904301581 && b[2].0 == 5363156162827);
let arr: &[&[LiveId]] = ids_array!(a.b, c, d.e.f);
assert!(arr.len() == 3 && arr[0].len() == 2 && arr[1].len() == 1 && arr[2].len() == 3);
assert!(arr[1][0].0 == 29102912674847 && arr[2][2].0 == 52354895671766);
assert!(live_id_num!(item, 5).0 == 52312143043854);
assert!(pick(id!(apple)) == 1 && pick(id!(banana)) == 2 && pick(live_id!(cherry)) == 3);
}
#[test]
fn std_builtins_match_rustc() {
assert!(stringify!(a + b * (c, d) . e) == "a + b * (c, d).e");
assert!(stringify!(vm.bx.threads.cur()) == "vm.bx.threads.cur()");
assert!(concat!("x", 1, "y", 2.5, true, 'c') == "x1y2.5truec");
assert!(line!() == 72);
assert!(column!() == 13);
assert!(inner::mp() == "test_crate::inner");
assert!(file!().len() > 0);
}
// `f as fn(..)` / `f as usize` on fn items and non-capturing closures (was a lowering ICE,
// reached through objc's add_method(sel!(..), f as extern "C" fn(..)))
pub struct Object {
x: u32,
}
pub trait Imp {
fn addr(self) -> usize;
}
impl Imp for extern "C" fn(&Object, u32) {
fn addr(self) -> usize {
self as usize
}
}
extern "C" fn plus1(x: u32) -> u32 {
x + 1
}
#[test]
fn fn_item_casts() {
extern "C" fn cb(_this: &Object, _v: u32) {}
let n = (cb as extern "C" fn(&Object, u32)).addr();
assert!(n != 0);
let p = plus1 as extern "C" fn(u32) -> u32;
assert!(p(41) == 42);
assert!(plus1 as usize != 0);
let c = (|x: u32| x * 2) as fn(u32) -> u32;
assert!(c(21) == 42);
let r = plus1 as *mut ();
assert!(r as usize != 0);
}