> I know for sure that in the end the C macros will only do text replacement, whereas the Rust macros could do anything.
My impression is exactly the opposite: Rust macros are guaranteed to expand to syntactically valid code that still obeys the memory/type/lifetime-safety constraints, whereas C macros can expand to something that won't even compile, never mind have any guarantees about soundness. Not to mention all the hoops you have to jump through with extra parens and whatnot to avoid the footguns of C macro operator precedence.
That is only with procedural macros.
Normal macros operate just by token substitutions.
Procedural macros are also special in that they are the only macros that can be 'unhygenic': creating new identifiers in the current scope that were not passed as an argument to the macro.
(Although knowing if something is a procedural macro or not is not obvious when using one in code)
My impression is exactly the opposite: Rust macros are guaranteed to expand to syntactically valid code that still obeys the memory/type/lifetime-safety constraints, whereas C macros can expand to something that won't even compile, never mind have any guarantees about soundness. Not to mention all the hoops you have to jump through with extra parens and whatnot to avoid the footguns of C macro operator precedence.