Skip to content

Commit 0530e44

Browse files
committed
Unsafe derives and attributes
1 parent ffb2c46 commit 0530e44

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed

text/0000-unsafe-derives-and-attrs.md

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
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

Comments
 (0)