levkk
November 18, 2018, 11:26pm
1
I have a question about advanced macros: I'm trying to achieve a substitution where both module::StructName
and StructName
could be accepted (so I think both a tt
and a path
). Is it possible?
Example:
macro_rules! my_macro {
($this_new_token:tt) => (
let constant = $this_new_token::from("Hello world!");
)
}
my_macro!(module::StructName);
The above example gives me:
$this_new_token::from("Hello world!");
^^ expected one of `.`, `;`, `?`, or an operator here
Thanks!
CAD97
November 18, 2018, 11:34pm
2
Unfortunately I don't think it's possible to graft onto a $:path
matcher, which seems to be what you want.
If you're ok accepting a subset of paths (that is, ones without generic qualification), you can match $($:ident)::+
:
macro_rules! m {
($($i:ident)::+) => ($($i)::+ ::default());
}
fn main() {
let x: u32 = m!(std::default::Default);
println!("{}", x);
}
1 Like
dtolnay
November 19, 2018, 1:02am
3
If you need something that matches both module::StructName
and StructName
I would recommend using $:path
.
macro_rules! my_macro {
($p:path) => {
let constant = <$p>::from("Hello world!");
println!("{}", constant);
};
}
fn main() {
my_macro!(String);
my_macro!(std::string::String);
}
2 Likes
levkk
November 19, 2018, 1:50am
4
Worked perfectly, thank you!