mini-RFC: `#[diagnostic::unsafe_macro]`

Now that we have the #[diagnostic::] attribute namespace, I think it'd be helpful to add a #[diagnostic::unsafe_macro] hint. This would encourage tooling to, on a best-effort basis only, provide assists potentially including but not limited to:

  • When highlighting uses of unsafe constructs (e.g. unsafe impl, unsafe fn calls, etc.), highlight uses of the annotated macro. Potential users: IDEs, rustdoc, cargo-geiger[1]
  • When expanding an annotated macro, warn if it's not syntactically contained in another unsafe construction and is an expression/statement position expansion (thus could be so contained). Potential users: rustc, clippy

As a #[diagnostic], this is entirely best-effort; it should never cause hard errors (deny-by-default is permissable at the tool author's digression) and is not intended to be a substitute for actual unsafe macros — whenever possible such macros should still require the user to write unsafe[2] and avoid violating conceptual unsafe hygiene[3] — but merely a more lightweight intermediate assistance for improving things incrementally.

  1. Likely limited to seeing decls and not calls, since it isn't doing any name resolution. ↩ī¸Ž

  2. Expression position macros can ensure they expand to include a call to some unsafe fn not in an expansion-providedunsafe block. Item position macros aren't so lucky and should ideally include e.g. unsafe impl in their input. (Alternatively, if no deliberately usable item names are defined, only impls, make it an expression position macro and require the caller to call as const _: () = unsafe { m!() };... which is likely just more annoying than pseudo-beneficial.) Attribute macros have some options, ↩ī¸Ž

  3. If a macro uses unsafe blocks internally, avoid expanding captured expressions inside of the block, as then the caller is permitted to do unsafe things covered by your unsafe block, this without writing unsafe themselves. This can be desirable in select cases — e.g. a private ffi! macro in an FFI adapter crate could be considered a valid unsafe introducer, as FFI is an "obviously" unsafe behavior — but generally isn't. ↩ī¸Ž