From 0530e4420f74e922908e16338f29d25739ade013 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Tue, 22 Oct 2024 06:36:10 -0700 Subject: [PATCH 1/4] Unsafe derives and attributes --- text/0000-unsafe-derives-and-attrs.md | 87 +++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 text/0000-unsafe-derives-and-attrs.md diff --git a/text/0000-unsafe-derives-and-attrs.md b/text/0000-unsafe-derives-and-attrs.md new file mode 100644 index 00000000000..e95a52eb4af --- /dev/null +++ b/text/0000-unsafe-derives-and-attrs.md @@ -0,0 +1,87 @@ +- Feature Name: `unsafe_derives_and_attrs` +- Start Date: 2024-10-22 +- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000) +- 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. From aaeab26d4b1261d118317d3548c18201f8a39169 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Tue, 22 Oct 2024 08:41:09 -0700 Subject: [PATCH 2/4] RFC 3715 --- ...fe-derives-and-attrs.md => 3715-unsafe-derives-and-attrs.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename text/{0000-unsafe-derives-and-attrs.md => 3715-unsafe-derives-and-attrs.md} (97%) diff --git a/text/0000-unsafe-derives-and-attrs.md b/text/3715-unsafe-derives-and-attrs.md similarity index 97% rename from text/0000-unsafe-derives-and-attrs.md rename to text/3715-unsafe-derives-and-attrs.md index e95a52eb4af..5c3b8fb21d1 100644 --- a/text/0000-unsafe-derives-and-attrs.md +++ b/text/3715-unsafe-derives-and-attrs.md @@ -1,6 +1,6 @@ - Feature Name: `unsafe_derives_and_attrs` - Start Date: 2024-10-22 -- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000) +- 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 From 41b758bf9f5caa1eec2581c958cb292f50a60869 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Wed, 23 Oct 2024 02:34:47 -0700 Subject: [PATCH 3/4] Mention alternative syntax and explain why we don't use it --- text/3715-unsafe-derives-and-attrs.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/text/3715-unsafe-derives-and-attrs.md b/text/3715-unsafe-derives-and-attrs.md index 5c3b8fb21d1..693dcad0a16 100644 --- a/text/3715-unsafe-derives-and-attrs.md +++ b/text/3715-unsafe-derives-and-attrs.md @@ -70,6 +70,11 @@ 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. +We could use a different syntax for invoking unsafe derives, such as +`derive(unsafe Trait)`. However, that would be inconsistent with unsafe +attributes (which use parentheses), *and* it has the potential to look like a +modifier to `Trait` (e.g. an unsafe version of `Trait`). + # Prior art [prior-art]: #prior-art From 6e054cc3a4afd41593be7ae5a593595684133cba Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Wed, 20 Nov 2024 10:31:31 -0800 Subject: [PATCH 4/4] Unresolved question for unsafe placement --- text/3715-unsafe-derives-and-attrs.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/text/3715-unsafe-derives-and-attrs.md b/text/3715-unsafe-derives-and-attrs.md index 693dcad0a16..0621d9c8f2e 100644 --- a/text/3715-unsafe-derives-and-attrs.md +++ b/text/3715-unsafe-derives-and-attrs.md @@ -81,6 +81,14 @@ modifier to `Trait` (e.g. an unsafe version of `Trait`). RFC 3325 defined unsafe attributes. This RFC provides a natural extension of that mechanism to derives. +# Unresolved questions +[unresolved-questions]: #unresolved-questions + +This RFC proposes accepting both `#[unsafe(derive(MyTrait))]` and +`#[derive(unsafe(MyTrait))]`, among other reasons to make it easy to write +`#[derive(SafeTrait, unsafe(MyTrait))]`. Should we allow both, or only allow +the former? + # Future possibilities [future-possibilities]: #future-possibilities