From 324bc6b6790acc540bc2df6a267a2ba8aa04b72b Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 9 Jun 2025 16:57:54 -0700 Subject: [PATCH 1/9] Unwrap derive --- src/attributes/derive.md | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/attributes/derive.md b/src/attributes/derive.md index 18ba01ed33..35dccc6e20 100644 --- a/src/attributes/derive.md +++ b/src/attributes/derive.md @@ -2,16 +2,12 @@ r[attributes.derive] # Derive r[attributes.derive.intro] -The *`derive` attribute* allows new [items] to be automatically generated for -data structures. +The *`derive` attribute* allows new [items] to be automatically generated for data structures. r[attributes.derive.syntax] -It uses the [MetaListPaths] syntax to specify a list of -traits to implement or paths to [derive macros] to process. +It uses the [MetaListPaths] syntax to specify a list of traits to implement or paths to [derive macros] to process. -For example, the following will create an [`impl` item] for the -[`PartialEq`] and [`Clone`] traits for `Foo`, and the type parameter `T` will be -given the `PartialEq` or `Clone` constraints for the appropriate `impl`: +For example, the following will create an [`impl` item] for the [`PartialEq`] and [`Clone`] traits for `Foo`, and the type parameter `T` will be given the `PartialEq` or `Clone` constraints for the appropriate `impl`: ```rust #[derive(PartialEq, Clone)] From 55d946493b85a706dce4abe851f72344efe9ede8 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 9 Jun 2025 18:03:21 -0700 Subject: [PATCH 2/9] Move derive example into an example block --- src/attributes/derive.md | 42 +++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/attributes/derive.md b/src/attributes/derive.md index 35dccc6e20..658b18eaea 100644 --- a/src/attributes/derive.md +++ b/src/attributes/derive.md @@ -4,29 +4,31 @@ r[attributes.derive] r[attributes.derive.intro] The *`derive` attribute* allows new [items] to be automatically generated for data structures. +> [!EXAMPLE] +> The following example will create an [`impl` item] for the [`PartialEq`] and [`Clone`] traits for `Foo`, and the type parameter `T` will be given the `PartialEq` or `Clone` constraints for the appropriate `impl`: +> +> ```rust +> #[derive(PartialEq, Clone)] +> struct Foo { +> a: i32, +> b: T, +> } +> ``` +> +> The generated `impl` for `PartialEq` is equivalent to +> +> ```rust +> # struct Foo { a: i32, b: T } +> impl PartialEq for Foo { +> fn eq(&self, other: &Foo) -> bool { +> self.a == other.a && self.b == other.b +> } +> } +> ``` + r[attributes.derive.syntax] It uses the [MetaListPaths] syntax to specify a list of traits to implement or paths to [derive macros] to process. -For example, the following will create an [`impl` item] for the [`PartialEq`] and [`Clone`] traits for `Foo`, and the type parameter `T` will be given the `PartialEq` or `Clone` constraints for the appropriate `impl`: - -```rust -#[derive(PartialEq, Clone)] -struct Foo { - a: i32, - b: T, -} -``` - -The generated `impl` for `PartialEq` is equivalent to - -```rust -# struct Foo { a: i32, b: T } -impl PartialEq for Foo { - fn eq(&self, other: &Foo) -> bool { - self.a == other.a && self.b == other.b - } -} -``` r[attributes.derive.proc-macro] You can implement `derive` for your own traits through [procedural macros]. From 15961417b1d13e550afd243d45f01c0f58ac1da7 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 9 Jun 2025 18:05:02 -0700 Subject: [PATCH 3/9] Remove attributes.derive.proc-macro This moves the text into the intro. I think it's fine to have this be more of a high-level introduction. The details and rules of derive proc-macros are covered in the proc-macro chapter, so there doesn't need to be an explicit rule here. --- src/attributes/derive.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/attributes/derive.md b/src/attributes/derive.md index 658b18eaea..467afce7e4 100644 --- a/src/attributes/derive.md +++ b/src/attributes/derive.md @@ -2,7 +2,7 @@ r[attributes.derive] # Derive r[attributes.derive.intro] -The *`derive` attribute* allows new [items] to be automatically generated for data structures. +The *`derive` [attribute][attributes]* allows new [items] to be automatically generated for data structures. You can implement custom `derive` macros through [procedural macros]. > [!EXAMPLE] > The following example will create an [`impl` item] for the [`PartialEq`] and [`Clone`] traits for `Foo`, and the type parameter `T` will be given the `PartialEq` or `Clone` constraints for the appropriate `impl`: @@ -30,8 +30,6 @@ r[attributes.derive.syntax] It uses the [MetaListPaths] syntax to specify a list of traits to implement or paths to [derive macros] to process. -r[attributes.derive.proc-macro] -You can implement `derive` for your own traits through [procedural macros]. r[attributes.derive.automatically_derived] ## The `automatically_derived` attribute From 6b2a4af497665ae15941224d76da75efd0128783 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 9 Jun 2025 18:06:09 -0700 Subject: [PATCH 4/9] Reword attributes.derive.syntax This is a slight rewording of attributes.derive.syntax. This drops the "list of traits" since these are really list of derive macros, of which there just happens to be several built-in ones that have the same name as their corresponding trait. --- src/attributes/derive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/attributes/derive.md b/src/attributes/derive.md index 467afce7e4..d757f15395 100644 --- a/src/attributes/derive.md +++ b/src/attributes/derive.md @@ -27,7 +27,7 @@ The *`derive` [attribute][attributes]* allows new [items] to be automatically ge > ``` r[attributes.derive.syntax] -It uses the [MetaListPaths] syntax to specify a list of traits to implement or paths to [derive macros] to process. +The `derive` attribute uses the [MetaListPaths] syntax to specify a list of paths to [derive macros] to process. From fa6fc398d70e118197f77831c37585009447182f Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 9 Jun 2025 18:06:53 -0700 Subject: [PATCH 5/9] Add attribute template rules for derive --- src/attributes/derive.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/attributes/derive.md b/src/attributes/derive.md index d757f15395..a39798dd3b 100644 --- a/src/attributes/derive.md +++ b/src/attributes/derive.md @@ -29,6 +29,14 @@ The *`derive` [attribute][attributes]* allows new [items] to be automatically ge r[attributes.derive.syntax] The `derive` attribute uses the [MetaListPaths] syntax to specify a list of paths to [derive macros] to process. +r[attributes.derive.allowed-positions] +The `derive` attribute may be applied to [structs][items.struct], [enums][items.enum], and [unions][items.union]. + +r[attributes.derive.duplicates] +The `derive` attribute may be specified multiple times on an item, with all entries from all attributes being processed. + +r[attributes.derive.stdlib] +The `derive` attribute is exported in the standard library prelude as [`core::prelude::v1::derive`]. r[attributes.derive.automatically_derived] From c520969b45c3ada4b03df2709e394846b88f72ae Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 9 Jun 2025 18:07:15 -0700 Subject: [PATCH 6/9] Add attributes.derive.built-in cc https://github.com/rust-lang/reference/issues/540 --- src/attributes/derive.md | 13 +++++++++++++ src/names/preludes.md | 1 + 2 files changed, 14 insertions(+) diff --git a/src/attributes/derive.md b/src/attributes/derive.md index a39798dd3b..5fa55c424c 100644 --- a/src/attributes/derive.md +++ b/src/attributes/derive.md @@ -38,6 +38,19 @@ The `derive` attribute may be specified multiple times on an item, with all entr r[attributes.derive.stdlib] The `derive` attribute is exported in the standard library prelude as [`core::prelude::v1::derive`]. +r[attributes.derive.built-in] +Built-in derives are defined in the [language prelude][names.preludes.lang]. The list of built-in derives are: + +- [`Clone`] +- [`Copy`] +- [`Debug`] +- [`Default`] +- [`Eq`] +- [`Hash`] +- [`Ord`] +- [`PartialEq`] +- [`PartialOrd`] + r[attributes.derive.automatically_derived] ## The `automatically_derived` attribute diff --git a/src/names/preludes.md b/src/names/preludes.md index 97edc59fc3..97c1ba77df 100644 --- a/src/names/preludes.md +++ b/src/names/preludes.md @@ -124,6 +124,7 @@ It includes the following: * [floating-point types] --- `f32` and `f64` * [Macro namespace] * [Built-in attributes] + * [Built-in derive macros][attributes.derive.built-in] r[names.preludes.macro_use] ## `macro_use` prelude From 176c79b30d8cfdc790a62863b274d1479cb4a485 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 9 Jun 2025 18:08:28 -0700 Subject: [PATCH 7/9] Add attributes.derive.behavior This adds a basic rule for the behavior of derive. I think there is more to be said here, this is just a starting point. See things like https://github.com/rust-lang/reference/issues/540 and https://github.com/rust-lang/reference/issues/1074. --- src/attributes/derive.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/attributes/derive.md b/src/attributes/derive.md index 5fa55c424c..c360e9f42f 100644 --- a/src/attributes/derive.md +++ b/src/attributes/derive.md @@ -51,6 +51,8 @@ Built-in derives are defined in the [language prelude][names.preludes.lang]. The - [`PartialEq`] - [`PartialOrd`] +r[attributes.derive.behavior] +During macro expansion, for each element in the list of derives, the corresponding derive macro expands to zero or more [items]. r[attributes.derive.automatically_derived] ## The `automatically_derived` attribute From b9a4f3c78ac6c10070ca23d4206ea6057394f69e Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 9 Jun 2025 18:26:53 -0700 Subject: [PATCH 8/9] Add attributes.derive.built-in-automatically_derived I'm not sure if I should put it in as part of derive or part of automatically_derived. --- src/attributes/derive.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/attributes/derive.md b/src/attributes/derive.md index c360e9f42f..37d6acfe65 100644 --- a/src/attributes/derive.md +++ b/src/attributes/derive.md @@ -51,6 +51,9 @@ Built-in derives are defined in the [language prelude][names.preludes.lang]. The - [`PartialEq`] - [`PartialOrd`] +r[attributes.derive.built-in-automatically_derived] +The built-in derives include the [`automatically_derived` attribute][attributes.derive.automatically_derived] on the implementations they generate. + r[attributes.derive.behavior] During macro expansion, for each element in the list of derives, the corresponding derive macro expands to zero or more [items]. From 46f5c660bdac8385b8111025dd1a620817de55cf Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 28 Jul 2025 08:47:35 +0000 Subject: [PATCH 9/9] Revise editorially Let's be a bit more clear about the purpose of the `derive` attribute being to invoke derive macros, and let's talk about "invoking" these macros rather than "processing" them. --- src/attributes/derive.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/attributes/derive.md b/src/attributes/derive.md index 37d6acfe65..c38bf19c7a 100644 --- a/src/attributes/derive.md +++ b/src/attributes/derive.md @@ -2,10 +2,10 @@ r[attributes.derive] # Derive r[attributes.derive.intro] -The *`derive` [attribute][attributes]* allows new [items] to be automatically generated for data structures. You can implement custom `derive` macros through [procedural macros]. +The *`derive` [attribute][attributes]* invokes one or more [derive macros], allowing new [items] to be automatically generated for data structures. You can create `derive` macros with [procedural macros]. > [!EXAMPLE] -> The following example will create an [`impl` item] for the [`PartialEq`] and [`Clone`] traits for `Foo`, and the type parameter `T` will be given the `PartialEq` or `Clone` constraints for the appropriate `impl`: +> The [`PartialEq`][macro@PartialEq] derive macro emits an [implementation] of [`PartialEq`] for `Foo where T: PartialEq`. The [`Clone`][macro@Clone] derive macro does likewise for [`Clone`]. > > ```rust > #[derive(PartialEq, Clone)] @@ -15,7 +15,7 @@ The *`derive` [attribute][attributes]* allows new [items] to be automatically ge > } > ``` > -> The generated `impl` for `PartialEq` is equivalent to +> The generated `impl` items are equivalent to: > > ```rust > # struct Foo { a: i32, b: T } @@ -24,16 +24,22 @@ The *`derive` [attribute][attributes]* allows new [items] to be automatically ge > self.a == other.a && self.b == other.b > } > } +> +> impl Clone for Foo { +> fn clone(&self) -> Self { +> Foo { a: self.a.clone(), b: self.b.clone() } +> } +> } > ``` r[attributes.derive.syntax] -The `derive` attribute uses the [MetaListPaths] syntax to specify a list of paths to [derive macros] to process. +The `derive` attribute uses the [MetaListPaths] syntax to specify a list of paths to [derive macros] to invoke. r[attributes.derive.allowed-positions] The `derive` attribute may be applied to [structs][items.struct], [enums][items.enum], and [unions][items.union]. r[attributes.derive.duplicates] -The `derive` attribute may be specified multiple times on an item, with all entries from all attributes being processed. +The `derive` attribute may be specified multiple times on an item, with all derive macros listed in all attributes being invoked. r[attributes.derive.stdlib] The `derive` attribute is exported in the standard library prelude as [`core::prelude::v1::derive`]. @@ -65,7 +71,6 @@ The *`automatically_derived` attribute* is automatically added to has no direct effect, but it may be used by tools and diagnostic lints to detect these automatically generated implementations. -[`impl` item]: ../items/implementations.md [items]: ../items.md [derive macros]: ../procedural-macros.md#derive-macros [implementations]: ../items/implementations.md