When calling an unsafe function or performing an unsafe operation, it has to be in an unsafe block or function, so you can find potentially dangerous code by searching for the unsafe keyword.
However, this is not true for macro_rules!. For example:
When looking at the foo function, you don't know if the dangerous! macro contains unsafe code. This is practically the same argumentation as with unsafe functions. If I were to replace the dangerous! macro with a dangerous function, I'd have to mark it as unsafe.
That's because functions declare their interface in their signature, properly encapsulating the implementation details - macros don't. If you really want to provide an unsafe macro in your public API, then you have to describe that it's only usable inside unsafe in its documentation. Just like you have to describe a lot of other way more important things in the documentation like what kind of arguments or what custom syntax is accepted.
macros in unsafe code already need to be carefully checked because macros can affect control flow in non-trivial ways, so adding this modifier does little to improve the situation.
There is an optional TODO about “make unsafe and lints hygienic” in the macros 2.0 tracking issue. I don't know what they mean by this. I just noticed this, I was going to suggest that your idea, if it has any value, then probably most so in the context of macros 2.0 syntax, hence I looked up that issue for you.