about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2023-09-12 23:10:03 +0200
committerLukas Wirth <lukastw97@gmail.com>2023-09-12 23:10:03 +0200
commitaffe5a731525e5e8ce401248a2ead0e85cc5f7a9 (patch)
treed206a73f4a17cf580b060718f50e07d9dfbff77e
parent326f37ef1f53575fd38e768065b6bcfcebdce462 (diff)
downloadrust-affe5a731525e5e8ce401248a2ead0e85cc5f7a9.tar.gz
rust-affe5a731525e5e8ce401248a2ead0e85cc5f7a9.zip
fix: Temporarily skip decl check in derive expansions
-rw-r--r--crates/hir-ty/src/diagnostics/decl_check.rs67
-rw-r--r--crates/hir/src/lib.rs10
-rw-r--r--crates/ide-diagnostics/src/lib.rs9
3 files changed, 62 insertions, 24 deletions
diff --git a/crates/hir-ty/src/diagnostics/decl_check.rs b/crates/hir-ty/src/diagnostics/decl_check.rs
index a94a962c1f8..36d69edf9d5 100644
--- a/crates/hir-ty/src/diagnostics/decl_check.rs
+++ b/crates/hir-ty/src/diagnostics/decl_check.rs
@@ -163,25 +163,56 @@ impl<'a> DeclValidator<'a> {
                         || allows.contains(allow::NONSTANDARD_STYLE)
                 })
         };
+        let db = self.db.upcast();
+        let file_id_is_derive = || {
+            match id {
+                AttrDefId::ModuleId(m) => {
+                    m.def_map(db)[m.local_id].origin.file_id().map(Into::into)
+                }
+                AttrDefId::FunctionId(f) => Some(f.lookup(db).id.file_id()),
+                AttrDefId::StaticId(sid) => Some(sid.lookup(db).id.file_id()),
+                AttrDefId::ConstId(cid) => Some(cid.lookup(db).id.file_id()),
+                AttrDefId::TraitId(tid) => Some(tid.lookup(db).id.file_id()),
+                AttrDefId::TraitAliasId(taid) => Some(taid.lookup(db).id.file_id()),
+                AttrDefId::ImplId(iid) => Some(iid.lookup(db).id.file_id()),
+                AttrDefId::ExternBlockId(id) => Some(id.lookup(db).id.file_id()),
+                AttrDefId::ExternCrateId(id) => Some(id.lookup(db).id.file_id()),
+                AttrDefId::UseId(id) => Some(id.lookup(db).id.file_id()),
+                // These warnings should not explore macro definitions at all
+                AttrDefId::MacroId(_) => None,
+                AttrDefId::AdtId(aid) => match aid {
+                    AdtId::StructId(sid) => Some(sid.lookup(db).id.file_id()),
+                    AdtId::EnumId(eid) => Some(eid.lookup(db).id.file_id()),
+                    // Unions aren't yet supported
+                    AdtId::UnionId(_) => None,
+                },
+                AttrDefId::FieldId(_) => None,
+                AttrDefId::EnumVariantId(_) => None,
+                AttrDefId::TypeAliasId(_) => None,
+                AttrDefId::GenericParamId(_) => None,
+            }
+            .map_or(false, |file_id| {
+                file_id.is_custom_derive(db.upcast()) || file_id.is_builtin_derive(db.upcast())
+            })
+        };
 
-        is_allowed(id)
-            // go upwards one step or give up
-            || match id {
-                AttrDefId::ModuleId(m) => m.containing_module(self.db.upcast()).map(|v| v.into()),
-                AttrDefId::FunctionId(f) => Some(f.lookup(self.db.upcast()).container.into()),
-                AttrDefId::StaticId(sid) => Some(sid.lookup(self.db.upcast()).container.into()),
-                AttrDefId::ConstId(cid) => Some(cid.lookup(self.db.upcast()).container.into()),
-                AttrDefId::TraitId(tid) => Some(tid.lookup(self.db.upcast()).container.into()),
-                AttrDefId::TraitAliasId(taid) => Some(taid.lookup(self.db.upcast()).container.into()),
-                AttrDefId::ImplId(iid) => Some(iid.lookup(self.db.upcast()).container.into()),
-                AttrDefId::ExternBlockId(id) => Some(id.lookup(self.db.upcast()).container.into()),
-                AttrDefId::ExternCrateId(id) =>  Some(id.lookup(self.db.upcast()).container.into()),
-                AttrDefId::UseId(id) =>  Some(id.lookup(self.db.upcast()).container.into()),
+        let parent = || {
+            match id {
+                AttrDefId::ModuleId(m) => m.containing_module(db).map(|v| v.into()),
+                AttrDefId::FunctionId(f) => Some(f.lookup(db).container.into()),
+                AttrDefId::StaticId(sid) => Some(sid.lookup(db).container.into()),
+                AttrDefId::ConstId(cid) => Some(cid.lookup(db).container.into()),
+                AttrDefId::TraitId(tid) => Some(tid.lookup(db).container.into()),
+                AttrDefId::TraitAliasId(taid) => Some(taid.lookup(db).container.into()),
+                AttrDefId::ImplId(iid) => Some(iid.lookup(db).container.into()),
+                AttrDefId::ExternBlockId(id) => Some(id.lookup(db).container.into()),
+                AttrDefId::ExternCrateId(id) => Some(id.lookup(db).container.into()),
+                AttrDefId::UseId(id) => Some(id.lookup(db).container.into()),
                 // These warnings should not explore macro definitions at all
                 AttrDefId::MacroId(_) => None,
                 AttrDefId::AdtId(aid) => match aid {
-                    AdtId::StructId(sid) => Some(sid.lookup(self.db.upcast()).container.into()),
-                    AdtId::EnumId(eid) => Some(eid.lookup(self.db.upcast()).container.into()),
+                    AdtId::StructId(sid) => Some(sid.lookup(db).container.into()),
+                    AdtId::EnumId(eid) => Some(eid.lookup(db).container.into()),
                     // Unions aren't yet supported
                     AdtId::UnionId(_) => None,
                 },
@@ -191,6 +222,12 @@ impl<'a> DeclValidator<'a> {
                 AttrDefId::GenericParamId(_) => None,
             }
             .is_some_and(|mid| self.allowed(mid, allow_name, true))
+        };
+        is_allowed(id)
+            // FIXME: this is a hack to avoid false positives in derive macros currently
+            || file_id_is_derive()
+            // go upwards one step or give up
+            || parent()
     }
 
     fn validate_func(&mut self, func: FunctionId) {
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 453f9b93737..b215ed38f28 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -564,8 +564,8 @@ impl Module {
             emit_def_diagnostic(db, acc, diag);
         }
 
-        for decl in self.declarations(db) {
-            match decl {
+        for def in self.declarations(db) {
+            match def {
                 ModuleDef::Module(m) => {
                     // Only add diagnostics from inline modules
                     if def_map[m.id.local_id].origin.is_inline() {
@@ -576,7 +576,7 @@ impl Module {
                     for diag in db.trait_data_with_diagnostics(t.id).1.iter() {
                         emit_def_diagnostic(db, acc, diag);
                     }
-                    acc.extend(decl.diagnostics(db))
+                    acc.extend(def.diagnostics(db))
                 }
                 ModuleDef::Adt(adt) => {
                     match adt {
@@ -600,10 +600,10 @@ impl Module {
                             }
                         }
                     }
-                    acc.extend(decl.diagnostics(db))
+                    acc.extend(def.diagnostics(db))
                 }
                 ModuleDef::Macro(m) => emit_macro_def_diagnostics(db, acc, m),
-                _ => acc.extend(decl.diagnostics(db)),
+                _ => acc.extend(def.diagnostics(db)),
             }
         }
         self.legacy_macros(db).into_iter().for_each(|m| emit_macro_def_diagnostics(db, acc, m));
diff --git a/crates/ide-diagnostics/src/lib.rs b/crates/ide-diagnostics/src/lib.rs
index 16ddb2aaf38..ebe197a6790 100644
--- a/crates/ide-diagnostics/src/lib.rs
+++ b/crates/ide-diagnostics/src/lib.rs
@@ -433,7 +433,8 @@ fn handle_lint_attributes(
     diagnostics_of_range: &mut FxHashMap<InFile<SyntaxNode>, &mut Diagnostic>,
 ) {
     let file_id = sema.hir_file_for(root);
-    for ev in root.preorder() {
+    let mut preorder = root.preorder();
+    while let Some(ev) = preorder.next() {
         match ev {
             syntax::WalkEvent::Enter(node) => {
                 for attr in node.children().filter_map(ast::Attr::cast) {
@@ -516,7 +517,7 @@ fn parse_lint_attribute(
     let Some((tag, args_tt)) = attr.as_simple_call() else {
         return;
     };
-    let serevity = match tag.as_str() {
+    let severity = match tag.as_str() {
         "allow" => Severity::Allow,
         "warn" => Severity::Warning,
         "forbid" | "deny" => Severity::Error,
@@ -524,12 +525,12 @@ fn parse_lint_attribute(
     };
     for lint in parse_tt_as_comma_sep_paths(args_tt).into_iter().flatten() {
         if let Some(lint) = lint.as_single_name_ref() {
-            job(rustc_stack.entry(lint.to_string()).or_default(), serevity);
+            job(rustc_stack.entry(lint.to_string()).or_default(), severity);
         }
         if let Some(tool) = lint.qualifier().and_then(|x| x.as_single_name_ref()) {
             if let Some(name_ref) = &lint.segment().and_then(|x| x.name_ref()) {
                 if tool.to_string() == "clippy" {
-                    job(clippy_stack.entry(name_ref.to_string()).or_default(), serevity);
+                    job(clippy_stack.entry(name_ref.to_string()).or_default(), severity);
                 }
             }
         }