rustc
treats macro definitions as some opaque piece of tokens and don't
do any check on them. For instance, the following macro definition is valid:
macro_rules! js_concat {
($left:expr, $right:expr) => {
$left ++ $right
};
}
However, any call to the js_concat
macro is invalid, as the ++
operator
does not exist in Rust. Luckily for us, this crate provides the
expandable::expr
macro, that checks that the macro expands to a valid
expression. Let's use it on js_concat
:
#[expandable::expr]
macro_rules! js_concat {
($left:expr, $right:expr) => {
$left ++ $right
};
}
This emits the following error 1:
error: Potentially invalid expansion. Expected an identifier.
--> tests/ui/fail/js_concat.rs:4:16
|
4 | $left ++ $right
| ^
Macros can expand to different things depending on where they are called.
As a result, expandable
must know what the macro expands to. To do so,
multiple macros are available:
- Macros that expand to expressions are checked by
expandable::expr
, - Macros that expand to items are checked by
expandable::item
, - TODO: pattern, statements, type.
expandable
supports Rust 1.56 and above. Bumping the MSRV is
considered a breaking change.
Note that the embedded parser will support syntax that was introduced after Rust 1.56.
Adding support for newer syntax is not considered a breaking change.
The error messages generated by expandable
are not stable and may change
without notice.
Any change that may trigger errors on previously accepted code is considered a breaking change.
Footnotes
-
The Rust grammar is not fully implemented at the moment, leading to incomplete "expected xxx" list this will be fixed before the first non-alpha release of this crate. ↩