Rust macros cannot do this. Macros work at the syntactical level, and not at the semantic level. This means that although the compiler knows that it has an expression (syntax), it does not know what type of expression value (semantic) is at the time the macro expands.
A workaround would be to pass the expected type to the macro:
macro_rules! attribute { ($e:expr, f32) => { }; ($e:expr, i64) => { }; } fn main() { attribute!(2 + 2, i64); }
Or, more simply, define a few macros.
If you want to do static (compilation) mailing based on an expression type, you can use traits. Define the trait using the necessary methods, then implement the trait for the types you need. You can implement a trait for any type (including primitives and types from other libraries) if the impl block is in the same box as the trait definition.
trait Attribute { fn process(&self); } impl Attribute for f32 { fn process(&self) { } } impl Attribute for i64 { fn process(&self) { } } macro_rules! attribute { ($e:expr) => { Attribute::process(&$e) }; } fn main() { attribute!(2 + 2); }
Note. You can also write $e.process() in a macro $e.process() , but then the macro can call the unbound process method.
source share