I am fairly new to Rust, and I am having trouble getting the following code to compile:
#![feature(trace_macros)]
fn main() {
#[derive(Debug)]
struct Inner {
value: u8
}
#[derive(Debug)]
struct Outer {
inner: Inner
}
let mut x = Outer { inner: Inner { value: 64 } };
/********/
macro_rules! my_macro {
($field_path:expr, $v:expr) => {
x.$field_path = $v;
}
}
trace_macros!(true);
// my_macro!(inner, Inner { value: 42 }); // only works with $field_path:ident
my_macro!(inner.value, 42); // expected output: x.inner.value = 42;
trace_macros!(false);
x . inner.value = 42; // works fine
assert_eq!(42, x.inner.value);
}
I am getting the following errors:
error: unexpected token: `inner.value`
--> src/main.rs:20:15
|
20 | x.$field_path = $v;
| ^^^^^^^^^^^
...
26 | my_macro!(inner.value, 42); // expected output: x.inner.value = 42;
| --------------------------- in this macro invocation
|
...
error: expected one of `.`, `;`, `?`, `}`, or an operator, found `inner.value`
--> src/main.rs:20:15
|
20 | x.$field_path = $v;
| ^^^^^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator
...
26 | my_macro!(inner.value, 42); // expected output: x.inner.value = 42;
| --------------------------- in this macro invocation
|
...
However, trace_macro
seems to be able to expand my_macro!
:
note: trace_macro
--> src/main.rs:26:5
|
26 | my_macro!(inner.value, 42); // expected output: x.inner.value = 42;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: expanding `my_macro! { inner . value, 42 }`
= note: to `x . inner.value = 42 ;` <<< exactly what I am looking for
If I keep $field_path
parameter as ident
, I am simply getting no rules expected the token `.`
, which I guess makes sense, because .
is an operator.
What am I missing?