Repository: rust-lang/rust-analyzer
Pull request #15202 (2023-07-03 12:24:26)

internal: Don't diagnose builtin derives


Patch:
diff --git a/crates/hir-expand/src/lib.rs b/crates/hir-expand/src/lib.rs
index 4c37ad3d15..b0dc8e1b5c 100644
--- a/crates/hir-expand/src/lib.rs
+++ b/crates/hir-expand/src/lib.rs
@@ -319,8 +319,10 @@ impl HirFileId {
         })
     }
 
-    /// Indicate it is macro file generated for builtin derive
-    pub fn is_builtin_derive(&self, db: &dyn db::ExpandDatabase) -> Option<InFile<ast::Attr>> {
+    pub fn as_builtin_derive_attr_node(
+        &self,
+        db: &dyn db::ExpandDatabase,
+    ) -> Option<InFile<ast::Attr>> {
         let macro_file = self.macro_file()?;
         let loc: MacroCallLoc = db.lookup_intern_macro_call(macro_file.macro_call_id);
         let attr = match loc.def.kind {
@@ -333,8 +335,22 @@ impl HirFileId {
     pub fn is_custom_derive(&self, db: &dyn db::ExpandDatabase) -> bool {
         match self.macro_file() {
             Some(macro_file) => {
-                let loc: MacroCallLoc = db.lookup_intern_macro_call(macro_file.macro_call_id);
-                matches!(loc.def.kind, MacroDefKind::ProcMacro(_, ProcMacroKind::CustomDerive, _))
+                matches!(
+                    db.lookup_intern_macro_call(macro_file.macro_call_id).def.kind,
+                    MacroDefKind::ProcMacro(_, ProcMacroKind::CustomDerive, _)
+                )
+            }
+            None => false,
+        }
+    }
+
+    pub fn is_builtin_derive(&self, db: &dyn db::ExpandDatabase) -> bool {
+        match self.macro_file() {
+            Some(macro_file) => {
+                matches!(
+                    db.lookup_intern_macro_call(macro_file.macro_call_id).def.kind,
+                    MacroDefKind::BuiltInDerive(..)
+                )
             }
             None => false,
         }
@@ -344,8 +360,7 @@ impl HirFileId {
     pub fn is_include_macro(&self, db: &dyn db::ExpandDatabase) -> bool {
         match self.macro_file() {
             Some(macro_file) => {
-                let loc: MacroCallLoc = db.lookup_intern_macro_call(macro_file.macro_call_id);
-                loc.def.is_include()
+                db.lookup_intern_macro_call(macro_file.macro_call_id).def.is_include()
             }
             _ => false,
         }
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 74eb9f6588..7d07e9cce4 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -614,15 +614,21 @@ impl Module {
         let inherent_impls = db.inherent_impls_in_crate(self.id.krate());
 
         for impl_def in self.impl_defs(db) {
+            let loc = impl_def.id.lookup(db.upcast());
+            let tree = loc.id.item_tree(db.upcast());
+            let node = &tree[loc.id.value];
+            let file_id = loc.id.file_id();
+            if file_id.is_builtin_derive(db.upcast()) {
+                // these expansion come from us, diagnosing them is a waste of resources
+                // FIXME: Once we diagnose the inputs to builtin derives, we should at least extract those diagnostics somehow
+                continue;
+            }
+
             for diag in db.impl_data_with_diagnostics(impl_def.id).1.iter() {
                 emit_def_diagnostic(db, acc, diag);
             }
 
             if inherent_impls.invalid_impls().contains(&impl_def.id) {
-                let loc = impl_def.id.lookup(db.upcast());
-                let tree = loc.id.item_tree(db.upcast());
-                let node = &tree[loc.id.value];
-                let file_id = loc.id.file_id();
                 let ast_id_map = db.ast_id_map(file_id);
 
                 acc.push(IncoherentImpl { impl_: ast_id_map.get(node.ast_id()), file_id }.into())
@@ -3278,9 +3284,9 @@ impl Impl {
         self.id.lookup(db.upcast()).container.into()
     }
 
-    pub fn is_builtin_derive(self, db: &dyn HirDatabase) -> Option<InFile<ast::Attr>> {
+    pub fn as_builtin_derive(self, db: &dyn HirDatabase) -> Option<InFile<ast::Attr>> {
         let src = self.source(db)?;
-        src.file_id.is_builtin_derive(db.upcast())
+        src.file_id.as_builtin_derive_attr_node(db.upcast())
     }
 }
 
diff --git a/crates/ide/src/navigation_target.rs b/crates/ide/src/navigation_target.rs
index 385c1b0c00..c7abecb4f1 100644
--- a/crates/ide/src/navigation_target.rs
+++ b/crates/ide/src/navigation_target.rs
@@ -357,13 +357,11 @@ impl ToNav for hir::Module {
 impl TryToNav for hir::Impl {
     fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
         let InFile { file_id, value } = self.source(db)?;
-        let derive_attr = self.is_builtin_derive(db);
+        let derive_attr = self.as_builtin_derive(db);
 
-        let focus = if derive_attr.is_some() { None } else { value.self_ty() };
-
-        let syntax = match &derive_attr {
-            Some(attr) => attr.value.syntax(),
-            None => value.syntax(),
+        let (focus, syntax) = match &derive_attr {
+            Some(attr) => (None, attr.value.syntax()),
+            None => (value.self_ty(), value.syntax()),
         };
 
         let (file_id, full_range, focus_range) = orig_range_with_focus(db, file_id, syntax, focus);


Test patch:
diff --git a/crates/hir-def/src/macro_expansion_tests/mod.rs b/crates/hir-def/src/macro_expansion_tests/mod.rs
index 4a62696df0..836f0afb1d 100644
--- a/crates/hir-def/src/macro_expansion_tests/mod.rs
+++ b/crates/hir-def/src/macro_expansion_tests/mod.rs
@@ -239,7 +239,7 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream
 
     for impl_id in def_map[local_id].scope.impls() {
         let src = impl_id.lookup(&db).source(&db);
-        if src.file_id.is_builtin_derive(&db).is_some() {
+        if src.file_id.is_builtin_derive(&db) {
             let pp = pretty_print_macro_expansion(src.value.syntax().clone(), None);
             format_to!(expanded_text, "\n{}", pp)
         }