makepad/libs/relax/base/tests/pm_bridge.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

50 lines
2.5 KiB
Rust

//! Exercise both sides of the actual proc-macro wire format, including non-current files.
#[allow(dead_code)]
#[path = "../../compiler/std/proc_macro/lib.rs"]
mod macro_side;
use relax_base::pm::{self, Delimiter, Group, Ident, LineColumn, Literal, Punct, Spacing, Span, TokenStream, TokenTree};
fn echo_with_call_site(input: macro_side::TokenStream) -> macro_side::TokenStream {
let mut trees: Vec<_> = input.into_iter().collect();
assert!(trees[0].span().join(trees[1].span()).is_none());
trees.push(macro_side::TokenTree::Ident(macro_side::Ident::new("call_site", macro_side::Span::call_site())));
trees.into_iter().collect()
}
#[test]
fn file_spans_survive_the_proc_macro_bridge() {
let call = Span { file: 17, lo: 11, hi: 19, start: LineColumn { line: 3, column: 5 }, end: LineColumn { line: 3, column: 13 } };
let ident_span = Span { file: 23, ..call };
let literal_span = Span { file: 42, ..call };
let stream = TokenStream { trees: vec![
TokenTree::Ident(Ident { name: "type".into(), raw: true, span: ident_span }),
TokenTree::Group(Group { delim: Delimiter::Brace, span: call, stream: TokenStream { trees: vec![
TokenTree::Punct(Punct { ch: ':', spacing: Spacing::Joint, span: call }),
TokenTree::Literal(Literal { text: "123u32".into(), span: literal_span }),
] } }),
] };
let input = pm::encode(call, &stream);
assert_eq!(&input[24..28], &17_u32.to_le_bytes());
let mut io = macro_side::__relax::BridgeIo {
f: echo_with_call_site as *const () as usize,
kind: 0,
inp: input.as_ptr(),
inp_len: input.len(),
attr: std::ptr::null(),
attr_len: 0,
out: std::ptr::null_mut(),
out_len: 0,
};
macro_side::__relax::bridge(&mut io);
// The macro bridge owns (and leaks) this allocation, just as it does in the JIT.
let bytes = unsafe { std::slice::from_raw_parts(io.out, io.out_len) };
let output = pm::decode_stream(bytes).expect("macro-side output must decode on the host");
let mut expected = stream;
expected.trees.push(TokenTree::Ident(Ident { name: "call_site".into(), raw: false, span: call }));
assert_eq!(pm::encode(call, &output), pm::encode(call, &expected));
assert_eq!(output.trees[0].span(), ident_span);
let TokenTree::Group(group) = &output.trees[1] else { panic!("expected nested group") };
assert_eq!(group.stream.trees[1].span(), literal_span);
assert_eq!(output.trees[2].span(), call);
}