Skip to content

Unsafe derives and attributes #3715

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Changes from 2 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
0530e44
Unsafe derives and attributes
joshtriplett Oct 22, 2024
aaeab26
RFC 3715
joshtriplett Oct 22, 2024
41b758b
Mention alternative syntax and explain why we don't use it
joshtriplett Oct 23, 2024
6e054cc
Unresolved question for unsafe placement
joshtriplett Nov 20, 2024
7a3e7ab
Resolve the unresolved question about unsafe placement, and document …
joshtriplett Mar 13, 2025
09fd6b2
Fix SAFETY comments to be non-doc comments
joshtriplett Mar 14, 2025
82c2ad5
Add another rationale for `derive(unsafe(UnsafeTrait))`, from TC
joshtriplett Mar 14, 2025
962e17c
Switch language to reference derive macros rather than traits
joshtriplett Mar 16, 2025
2ecc61d
More wording updates from "trait" to "derive macro"
joshtriplett Mar 16, 2025
0c7684f
Add alternative for restricting to one derive macro per `unsafe(deriv…
joshtriplett Mar 16, 2025
dfad26f
Flag order-dependent derives as an unusual case
joshtriplett Mar 16, 2025
309cb97
Add alternative for declaring with `proc_macro_derive(unsafe(Dangerou…
joshtriplett Mar 16, 2025
bbed33f
Rewrite descriptions of SAFETY comments
joshtriplett Mar 19, 2025
6b5499c
Add note about rustfmt
joshtriplett Mar 19, 2025
04caa41
Mention and discuss alternative of unsafe supertrait
joshtriplett Mar 19, 2025
2b4e22b
Change syntax to `proc_macro_derive(unsafe(DangerousDeriveMacro))`
joshtriplett Apr 16, 2025
dd1c9f0
Expand motivation
joshtriplett Apr 16, 2025
102223a
Reorder attributes before derives
joshtriplett Apr 16, 2025
fcc7e78
Add unsafe helper attributes
joshtriplett Apr 16, 2025
0549114
Fix typo
joshtriplett Apr 27, 2025
0c8a3cb
RFC 3715: Expand motivation
joshtriplett May 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions text/3715-unsafe-derives-and-attrs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
- Feature Name: `unsafe_derives_and_attrs`
- Start Date: 2024-10-22
- RFC PR: [rust-lang/rfcs#3715](https://github.com/rust-lang/rfcs/pull/3715)
- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000)

# Summary
[summary]: #summary

Allow declaring proc macro attributes and derive macros as unsafe, and
requiring `unsafe` to invoke them.

# Motivation
[motivation]: #motivation

Some traits place requirements on implementations that the Rust compiler cannot
verify. Those traits can mark themselves as unsafe, requiring `unsafe impl`
syntax to implement. However, trait `derive` macros cannot currently require
`unsafe`. This RFC defines a syntax for declaring and using unsafe `derive`
macros.

This RFC also defines a syntax for declaring proc macro attributes as unsafe.

# Guide-level explanation
[guide-level-explanation]: #guide-level-explanation

## Derives

When declaring a proc macro `derive`, you can add the `unsafe` parameter to the
`proc_macro_derive` attribute to indicate that the derive requires `unsafe`:

```rust
#[proc_macro_derive(DangerousTrait, unsafe)]
pub fn derive_helper_attr(_item: TokenStream) -> TokenStream {
TokenStream::new()
}
```

Invoking this derive requires writing either
`#[unsafe(derive(DangerousTrait))]` or `#[derive(unsafe(DangerousTrait))]`.
(The latter syntax allows isolating the `unsafe` to a single derive within a
list of derives.) Invoking an unsafe derive without the unsafe derive syntax
will produce a compiler error. Using the unsafe derive syntax without an unsafe
derive will trigger an "unused unsafe" lint.

A `proc_macro_derive` attribute can include both `attributes` for helper
attributes and `unsafe` to declare the derive unsafe, in any order.

## Attributes

When declaring a proc macro attribute, you can add the `unsafe` parameter to
the `proc_macro_attribute` attribute to indicate that the attribute requires
`unsafe`:

```rust
#[proc_macro_attribute(unsafe)]
pub fn dangerous(_attr: TokenStream, item: TokenStream) -> TokenStream {
item
}
```

Invoking an unsafe attribute requires the unsafe attribute syntax:
`#[unsafe(dangerous)]`.

# Rationale and alternatives
[rationale-and-alternatives]: #rationale-and-alternatives

Should we support the `#[unsafe(derive(DangerousTrait))]` syntax, or only
`#[derive(unsafe(DangerousTrait))]`? The former elevates the `unsafe` to be
more visible, and allows deriving several traits using one `unsafe`. The latter
isolates the `unsafe` to a specific trait. This RFC proposes supporting both,
but we could choose to only support the latter instead.

# Prior art
[prior-art]: #prior-art

RFC 3325 defined unsafe attributes. This RFC provides a natural extension of
that mechanism to derives.

# Future possibilities
[future-possibilities]: #future-possibilities

When we add support for `macro_rules!`-based attributes and derives, we should
provide a means for such attributes and derives to declare themselves unsafe as
well.

We could provide a syntax to declare specific helper attributes of a derive as
unsafe, without declaring the entire derive unsafe.