# Explicitly marking unsafe macro expressions

**URL:** <https://internals.rust-lang.org/t/explicitly-marking-unsafe-macro-expressions/9425>\
**Category:** Unsafe Code Guidelines\
**Created:** [February 12, 2019, 6:25pm UTC](https://internals.rust-lang.org/t/explicitly-marking-unsafe-macro-expressions/9425 "2019-02-12T18:25:34Z")\
**Posts on this page:** 1\
**Showing post:** 10

<div class="post-metadata">

**Author:** ![dhm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/dhm/32/4879_2.png) [@dhm](https://internals.rust-lang.org/u/dhm)\
**Post date:** [February 13, 2019, 10:32am UTC](https://internals.rust-lang.org/t/explicitly-marking-unsafe-macro-expressions/9425/10 "2019-02-13T10:32:18Z")

</div>

There are multiple things to pay attention to, here:

- **Should a macro using `unsafe` become `unsafe` itself?** I don’t think this is desirable. See [`::std::await!`](https://doc.rust-lang.org/std/macro.await.html) or [`::pin-utils::pin_mut!`](https://docs.rs/pin-utils/0.1.0-alpha.4/pin_utils/macro.pin_mut.html) : **safe** constructions using underlying `unsafe`. It is the same as a non-`unsafe` function wrapping `unsafe` behavior in a (hopefully) safe manner, thus not needing to be `unsafe` itself.

- **unsafe hygiene** , i.e., an input argument `$macro_arg:expr` should not be allowed to “`unsafe`-ly evaluate” `$macro_arg` (e.g. feeding `*::std::ptr::null()` as `$macro_arg:expr` should raise an error since it requires "`unsafe` evaluation", but feeding `unsafe { *::std::ptr::null() }` as `$macro_arg:expr` should be allowed (`unsafe` being the keyword making all the evaluations in its scope be automagically tagged `safe`, hence its unsafety)). I’m not being very rigurous but you get the idea.

```rust
unsafe fn get_foo () {}

macro_rules! eq_to_foo {(
  $macro_arg:expr
) => (
  match $macro_arg { macro_arg => unsafe {
    // Look, no metavariables within the unsafe block !
    macro_arg == get_foo()
  }}
)}

// Note that for this very particular case, we could more simply write:
macro_rules! eq_to_foo {(
  $macro_arg:expr
) => (
  $macro_arg == unsafe { get_foo() }
)}

```

- **`unsafe` detection** : there are many talks about, as a library user, being able to detect / warn and even forbid `unsafe` usages. The problem is that current “solutions” **do not detect `unsafe` usage through macro invocations**. For instance:
  - [`::cargo-geiger`](https://crates.io/crates/cargo-geiger), a tool to walk through the dependency graph and count the number of `unsafe` usages encountered in each crate (imho counting is not the best metric, but that is out of topic here):
    - _Unsafe code inside macros are not detected. Needs macro expansion_

  - Using `#![forbid(unsafe_code)]` (or `RUSTFLAGS=-Funsafe_code`):
    - It detects if the macro was defined within the same crate. But a macro from a different crate, even when in the same workspace, will sneak its way past the `forbid(unsafe_code)` restriction (See [here](https://asciinema.org/a/tsHaAAncpnkj8ncABhgWAtyX7), look at the difference between 1m48 and the end).

---

_[View the full topic](https://internals.rust-lang.org/t/explicitly-marking-unsafe-macro-expressions/9425)._
