Repository: rust-lang/rust-analyzer
Pull request #15172 (2023-06-29 17:10:36)

Support #[derive_const(Trait)]
This is a nightly feature used in the standard library.

HKalbasi: @bors r+
bors: :pushpin: Commit edc52d360fc97fb3b62fe345ac6e07a0736ab15f has been approved by `HKalbasi`

It is now in the [queue](https://bors.rust-lang.org/homu/queue/rust-analyzer) for this repository.

<!-- @bors r=HKalbasi edc52d360fc97fb3b62fe345ac6e07a0736ab15f -->
<!-- homu: {"type":"Approved","sha":"edc52d360fc97fb3b62fe345ac6e07a0736ab15f","approver":"HKalbasi","queue":"https://bors.rust-lang.org/homu/queue/rust-analyzer"} -->
bors: :hourglass: Testing commit edc52d360fc97fb3b62fe345ac6e07a0736ab15f with merge d4820ce079597591803107dddea48fef6e49a549...
<!-- homu: {"type":"BuildStarted","head_sha":"edc52d360fc97fb3b62fe345ac6e07a0736ab15f","merge_sha":"d4820ce079597591803107dddea48fef6e49a549"} -->
bors: :broken_heart: Test failed - [checks-actions](https://github.com/rust-lang/rust-analyzer/actions/runs/5414940754/jobs/9842878253)
<!-- homu: {"type":"BuildFailed","builder_url":"https://github.com/rust-lang/rust-analyzer/actions/runs/5414940754/jobs/9842878253","builder_name":"checks-actions"} -->

Patch:
diff --git a/crates/hir-expand/src/builtin_attr_macro.rs b/crates/hir-expand/src/builtin_attr_macro.rs
index 80695bc065..4ee12e2f21 100644
--- a/crates/hir-expand/src/builtin_attr_macro.rs
+++ b/crates/hir-expand/src/builtin_attr_macro.rs
@@ -35,7 +35,7 @@ macro_rules! register_builtin {
 
 impl BuiltinAttrExpander {
     pub fn is_derive(self) -> bool {
-        matches!(self, BuiltinAttrExpander::Derive)
+        matches!(self, BuiltinAttrExpander::Derive | BuiltinAttrExpander::DeriveConst)
     }
     pub fn is_test(self) -> bool {
         matches!(self, BuiltinAttrExpander::Test)
@@ -50,6 +50,8 @@ register_builtin! {
     (cfg_accessible, CfgAccessible) => dummy_attr_expand,
     (cfg_eval, CfgEval) => dummy_attr_expand,
     (derive, Derive) => derive_attr_expand,
+    // derive const is equivalent to derive for our proposes.
+    (derive_const, DeriveConst) => derive_attr_expand,
     (global_allocator, GlobalAllocator) => dummy_attr_expand,
     (test, Test) => dummy_attr_expand,
     (test_case, TestCase) => dummy_attr_expand
diff --git a/crates/hir-expand/src/name.rs b/crates/hir-expand/src/name.rs
index f8dbb84277..100476044b 100644
--- a/crates/hir-expand/src/name.rs
+++ b/crates/hir-expand/src/name.rs
@@ -365,6 +365,7 @@ pub mod known {
         cfg_eval,
         crate_type,
         derive,
+        derive_const,
         global_allocator,
         no_core,
         no_std,


Test patch:
diff --git a/crates/hir-def/src/macro_expansion_tests/builtin_derive_macro.rs b/crates/hir-def/src/macro_expansion_tests/builtin_derive_macro.rs
index f41f971904..145cf8ddd4 100644
--- a/crates/hir-def/src/macro_expansion_tests/builtin_derive_macro.rs
+++ b/crates/hir-def/src/macro_expansion_tests/builtin_derive_macro.rs
@@ -278,6 +278,44 @@ impl < > core::cmp::Eq for Command< > where {}"#]],
     );
 }
 
+#[test]
+fn test_partial_eq_expand_with_derive_const() {
+    // FIXME: actually expand with const
+    check(
+        r#"
+//- minicore: derive, eq
+#[derive_const(PartialEq, Eq)]
+enum Command {
+    Move { x: i32, y: i32 },
+    Do(&'static str),
+    Jump,
+}
+"#,
+        expect![[r#"
+#[derive_const(PartialEq, Eq)]
+enum Command {
+    Move { x: i32, y: i32 },
+    Do(&'static str),
+    Jump,
+}
+
+impl < > core::cmp::PartialEq for Command< > where {
+    fn eq(&self , other: &Self ) -> bool {
+        match (self , other) {
+            (Command::Move {
+                x: x_self, y: y_self,
+            }
+            , Command::Move {
+                x: x_other, y: y_other,
+            }
+            )=>x_self.eq(x_other) && y_self.eq(y_other), (Command::Do(f0_self, ), Command::Do(f0_other, ))=>f0_self.eq(f0_other), (Command::Jump, Command::Jump)=>true , _unused=>false
+        }
+    }
+}
+impl < > core::cmp::Eq for Command< > where {}"#]],
+    );
+}
+
 #[test]
 fn test_partial_ord_expand() {
     check(
diff --git a/crates/ide-completion/src/tests/attribute.rs b/crates/ide-completion/src/tests/attribute.rs
index c97144b61b..1aaf395872 100644
--- a/crates/ide-completion/src/tests/attribute.rs
+++ b/crates/ide-completion/src/tests/attribute.rs
@@ -300,6 +300,7 @@ struct Foo;
             at deprecated
             at derive           macro derive
             at derive(…)
+            at derive_const     macro derive_const
             at doc = "…"
             at doc(alias = "…")
             at doc(hidden)
diff --git a/crates/test-utils/src/minicore.rs b/crates/test-utils/src/minicore.rs
index 200bb0e8a5..73a322389e 100644
--- a/crates/test-utils/src/minicore.rs
+++ b/crates/test-utils/src/minicore.rs
@@ -1311,6 +1311,11 @@ mod macros {
         pub macro derive($item:item) {
             /* compiler built-in */
         }
+
+        #[rustc_builtin_macro]
+        pub macro derive_const($item:item) {
+            /* compiler built-in */
+        }
     }
     // endregion:derive
 
@@ -1378,24 +1383,24 @@ pub mod error {
 pub mod prelude {
     pub mod v1 {
         pub use crate::{
-            clone::Clone,                       // :clone
-            cmp::{Eq, PartialEq},               // :eq
-            cmp::{Ord, PartialOrd},             // :ord
-            convert::AsRef,                     // :as_ref
-            convert::{From, Into},              // :from
-            default::Default,                   // :default
-            iter::{IntoIterator, Iterator},     // :iterator
-            macros::builtin::derive,            // :derive
-            marker::Copy,                       // :copy
-            marker::Send,                       // :send
-            marker::Sized,                      // :sized
-            marker::Sync,                       // :sync
-            mem::drop,                          // :drop
-            ops::Drop,                          // :drop
-            ops::{Fn, FnMut, FnOnce},           // :fn
-            option::Option::{self, None, Some}, // :option
-            panic,                              // :panic
-            result::Result::{self, Err, Ok},    // :result
+            clone::Clone,                            // :clone
+            cmp::{Eq, PartialEq},                    // :eq
+            cmp::{Ord, PartialOrd},                  // :ord
+            convert::AsRef,                          // :as_ref
+            convert::{From, Into},                   // :from
+            default::Default,                        // :default
+            iter::{IntoIterator, Iterator},          // :iterator
+            macros::builtin::{derive, derive_const}, // :derive
+            marker::Copy,                            // :copy
+            marker::Send,                            // :send
+            marker::Sized,                           // :sized
+            marker::Sync,                            // :sync
+            mem::drop,                               // :drop
+            ops::Drop,                               // :drop
+            ops::{Fn, FnMut, FnOnce},                // :fn
+            option::Option::{self, None, Some},      // :option
+            panic,                                   // :panic
+            result::Result::{self, Err, Ok},         // :result
         };
     }