|  | 
|  | 1 | +- Feature Name: `unsafe_derives_and_attrs` | 
|  | 2 | +- Start Date: 2024-10-22 | 
|  | 3 | +- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000) | 
|  | 4 | +- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) | 
|  | 5 | + | 
|  | 6 | +# Summary | 
|  | 7 | +[summary]: #summary | 
|  | 8 | + | 
|  | 9 | +Allow declaring proc macro attributes and derive macros as unsafe, and | 
|  | 10 | +requiring `unsafe` to invoke them. | 
|  | 11 | + | 
|  | 12 | +# Motivation | 
|  | 13 | +[motivation]: #motivation | 
|  | 14 | + | 
|  | 15 | +Some traits place requirements on implementations that the Rust compiler cannot | 
|  | 16 | +verify. Those traits can mark themselves as unsafe, requiring `unsafe impl` | 
|  | 17 | +syntax to implement. However, trait `derive` macros cannot currently require | 
|  | 18 | +`unsafe`. This RFC defines a syntax for declaring and using unsafe `derive` | 
|  | 19 | +macros. | 
|  | 20 | + | 
|  | 21 | +This RFC also defines a syntax for declaring proc macro attributes as unsafe. | 
|  | 22 | + | 
|  | 23 | +# Guide-level explanation | 
|  | 24 | +[guide-level-explanation]: #guide-level-explanation | 
|  | 25 | + | 
|  | 26 | +## Derives | 
|  | 27 | + | 
|  | 28 | +When declaring a proc macro `derive`, you can add the `unsafe` parameter to the | 
|  | 29 | +`proc_macro_derive` attribute to indicate that the derive requires `unsafe`: | 
|  | 30 | + | 
|  | 31 | +```rust | 
|  | 32 | +#[proc_macro_derive(DangerousTrait, unsafe)] | 
|  | 33 | +pub fn derive_helper_attr(_item: TokenStream) -> TokenStream { | 
|  | 34 | +    TokenStream::new() | 
|  | 35 | +} | 
|  | 36 | +``` | 
|  | 37 | + | 
|  | 38 | +Invoking this derive requires writing either | 
|  | 39 | +`#[unsafe(derive(DangerousTrait))]` or `#[derive(unsafe(DangerousTrait))]`. | 
|  | 40 | +(The latter syntax allows isolating the `unsafe` to a single derive within a | 
|  | 41 | +list of derives.) Invoking an unsafe derive without the unsafe derive syntax | 
|  | 42 | +will produce a compiler error. Using the unsafe derive syntax without an unsafe | 
|  | 43 | +derive will trigger an "unused unsafe" lint. | 
|  | 44 | + | 
|  | 45 | +A `proc_macro_derive` attribute can include both `attributes` for helper | 
|  | 46 | +attributes and `unsafe` to declare the derive unsafe, in any order. | 
|  | 47 | + | 
|  | 48 | +## Attributes | 
|  | 49 | + | 
|  | 50 | +When declaring a proc macro attribute, you can add the `unsafe` parameter to | 
|  | 51 | +the `proc_macro_attribute` attribute to indicate that the attribute requires | 
|  | 52 | +`unsafe`: | 
|  | 53 | + | 
|  | 54 | +```rust | 
|  | 55 | +#[proc_macro_attribute(unsafe)] | 
|  | 56 | +pub fn dangerous(_attr: TokenStream, item: TokenStream) -> TokenStream { | 
|  | 57 | +    item | 
|  | 58 | +} | 
|  | 59 | +``` | 
|  | 60 | + | 
|  | 61 | +Invoking an unsafe attribute requires the unsafe attribute syntax: | 
|  | 62 | +`#[unsafe(dangerous)]`. | 
|  | 63 | + | 
|  | 64 | +# Rationale and alternatives | 
|  | 65 | +[rationale-and-alternatives]: #rationale-and-alternatives | 
|  | 66 | + | 
|  | 67 | +Should we support the `#[unsafe(derive(DangerousTrait))]` syntax, or only | 
|  | 68 | +`#[derive(unsafe(DangerousTrait))]`? The former elevates the `unsafe` to be | 
|  | 69 | +more visible, and allows deriving several traits using one `unsafe`. The latter | 
|  | 70 | +isolates the `unsafe` to a specific trait. This RFC proposes supporting both, | 
|  | 71 | +but we could choose to only support the latter instead. | 
|  | 72 | + | 
|  | 73 | +# Prior art | 
|  | 74 | +[prior-art]: #prior-art | 
|  | 75 | + | 
|  | 76 | +RFC 3325 defined unsafe attributes. This RFC provides a natural extension of | 
|  | 77 | +that mechanism to derives. | 
|  | 78 | + | 
|  | 79 | +# Future possibilities | 
|  | 80 | +[future-possibilities]: #future-possibilities | 
|  | 81 | + | 
|  | 82 | +When we add support for `macro_rules!`-based attributes and derives, we should | 
|  | 83 | +provide a means for such attributes and derives to declare themselves unsafe as | 
|  | 84 | +well. | 
|  | 85 | + | 
|  | 86 | +We could provide a syntax to declare specific helper attributes of a derive as | 
|  | 87 | +unsafe, without declaring the entire derive unsafe. | 
0 commit comments