Skip to content

Commit 15e1356

Browse files
committed
Auto merge of #15601 - Veykril:diag-derive, r=Veykril
fix: Temporarily skip decl check in derive expansions "Fixes rust-lang/rust-analyzer#15344"
2 parents cc6c820 + affe5a7 commit 15e1356

File tree

3 files changed

+62
-24
lines changed

3 files changed

+62
-24
lines changed

crates/hir-ty/src/diagnostics/decl_check.rs

+52-15
Original file line numberDiff line numberDiff line change
@@ -163,25 +163,56 @@ impl<'a> DeclValidator<'a> {
163163
|| allows.contains(allow::NONSTANDARD_STYLE)
164164
})
165165
};
166+
let db = self.db.upcast();
167+
let file_id_is_derive = || {
168+
match id {
169+
AttrDefId::ModuleId(m) => {
170+
m.def_map(db)[m.local_id].origin.file_id().map(Into::into)
171+
}
172+
AttrDefId::FunctionId(f) => Some(f.lookup(db).id.file_id()),
173+
AttrDefId::StaticId(sid) => Some(sid.lookup(db).id.file_id()),
174+
AttrDefId::ConstId(cid) => Some(cid.lookup(db).id.file_id()),
175+
AttrDefId::TraitId(tid) => Some(tid.lookup(db).id.file_id()),
176+
AttrDefId::TraitAliasId(taid) => Some(taid.lookup(db).id.file_id()),
177+
AttrDefId::ImplId(iid) => Some(iid.lookup(db).id.file_id()),
178+
AttrDefId::ExternBlockId(id) => Some(id.lookup(db).id.file_id()),
179+
AttrDefId::ExternCrateId(id) => Some(id.lookup(db).id.file_id()),
180+
AttrDefId::UseId(id) => Some(id.lookup(db).id.file_id()),
181+
// These warnings should not explore macro definitions at all
182+
AttrDefId::MacroId(_) => None,
183+
AttrDefId::AdtId(aid) => match aid {
184+
AdtId::StructId(sid) => Some(sid.lookup(db).id.file_id()),
185+
AdtId::EnumId(eid) => Some(eid.lookup(db).id.file_id()),
186+
// Unions aren't yet supported
187+
AdtId::UnionId(_) => None,
188+
},
189+
AttrDefId::FieldId(_) => None,
190+
AttrDefId::EnumVariantId(_) => None,
191+
AttrDefId::TypeAliasId(_) => None,
192+
AttrDefId::GenericParamId(_) => None,
193+
}
194+
.map_or(false, |file_id| {
195+
file_id.is_custom_derive(db.upcast()) || file_id.is_builtin_derive(db.upcast())
196+
})
197+
};
166198

167-
is_allowed(id)
168-
// go upwards one step or give up
169-
|| match id {
170-
AttrDefId::ModuleId(m) => m.containing_module(self.db.upcast()).map(|v| v.into()),
171-
AttrDefId::FunctionId(f) => Some(f.lookup(self.db.upcast()).container.into()),
172-
AttrDefId::StaticId(sid) => Some(sid.lookup(self.db.upcast()).container.into()),
173-
AttrDefId::ConstId(cid) => Some(cid.lookup(self.db.upcast()).container.into()),
174-
AttrDefId::TraitId(tid) => Some(tid.lookup(self.db.upcast()).container.into()),
175-
AttrDefId::TraitAliasId(taid) => Some(taid.lookup(self.db.upcast()).container.into()),
176-
AttrDefId::ImplId(iid) => Some(iid.lookup(self.db.upcast()).container.into()),
177-
AttrDefId::ExternBlockId(id) => Some(id.lookup(self.db.upcast()).container.into()),
178-
AttrDefId::ExternCrateId(id) => Some(id.lookup(self.db.upcast()).container.into()),
179-
AttrDefId::UseId(id) => Some(id.lookup(self.db.upcast()).container.into()),
199+
let parent = || {
200+
match id {
201+
AttrDefId::ModuleId(m) => m.containing_module(db).map(|v| v.into()),
202+
AttrDefId::FunctionId(f) => Some(f.lookup(db).container.into()),
203+
AttrDefId::StaticId(sid) => Some(sid.lookup(db).container.into()),
204+
AttrDefId::ConstId(cid) => Some(cid.lookup(db).container.into()),
205+
AttrDefId::TraitId(tid) => Some(tid.lookup(db).container.into()),
206+
AttrDefId::TraitAliasId(taid) => Some(taid.lookup(db).container.into()),
207+
AttrDefId::ImplId(iid) => Some(iid.lookup(db).container.into()),
208+
AttrDefId::ExternBlockId(id) => Some(id.lookup(db).container.into()),
209+
AttrDefId::ExternCrateId(id) => Some(id.lookup(db).container.into()),
210+
AttrDefId::UseId(id) => Some(id.lookup(db).container.into()),
180211
// These warnings should not explore macro definitions at all
181212
AttrDefId::MacroId(_) => None,
182213
AttrDefId::AdtId(aid) => match aid {
183-
AdtId::StructId(sid) => Some(sid.lookup(self.db.upcast()).container.into()),
184-
AdtId::EnumId(eid) => Some(eid.lookup(self.db.upcast()).container.into()),
214+
AdtId::StructId(sid) => Some(sid.lookup(db).container.into()),
215+
AdtId::EnumId(eid) => Some(eid.lookup(db).container.into()),
185216
// Unions aren't yet supported
186217
AdtId::UnionId(_) => None,
187218
},
@@ -191,6 +222,12 @@ impl<'a> DeclValidator<'a> {
191222
AttrDefId::GenericParamId(_) => None,
192223
}
193224
.is_some_and(|mid| self.allowed(mid, allow_name, true))
225+
};
226+
is_allowed(id)
227+
// FIXME: this is a hack to avoid false positives in derive macros currently
228+
|| file_id_is_derive()
229+
// go upwards one step or give up
230+
|| parent()
194231
}
195232

196233
fn validate_func(&mut self, func: FunctionId) {

crates/hir/src/lib.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -564,8 +564,8 @@ impl Module {
564564
emit_def_diagnostic(db, acc, diag);
565565
}
566566

567-
for decl in self.declarations(db) {
568-
match decl {
567+
for def in self.declarations(db) {
568+
match def {
569569
ModuleDef::Module(m) => {
570570
// Only add diagnostics from inline modules
571571
if def_map[m.id.local_id].origin.is_inline() {
@@ -576,7 +576,7 @@ impl Module {
576576
for diag in db.trait_data_with_diagnostics(t.id).1.iter() {
577577
emit_def_diagnostic(db, acc, diag);
578578
}
579-
acc.extend(decl.diagnostics(db))
579+
acc.extend(def.diagnostics(db))
580580
}
581581
ModuleDef::Adt(adt) => {
582582
match adt {
@@ -600,10 +600,10 @@ impl Module {
600600
}
601601
}
602602
}
603-
acc.extend(decl.diagnostics(db))
603+
acc.extend(def.diagnostics(db))
604604
}
605605
ModuleDef::Macro(m) => emit_macro_def_diagnostics(db, acc, m),
606-
_ => acc.extend(decl.diagnostics(db)),
606+
_ => acc.extend(def.diagnostics(db)),
607607
}
608608
}
609609
self.legacy_macros(db).into_iter().for_each(|m| emit_macro_def_diagnostics(db, acc, m));

crates/ide-diagnostics/src/lib.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,8 @@ fn handle_lint_attributes(
433433
diagnostics_of_range: &mut FxHashMap<InFile<SyntaxNode>, &mut Diagnostic>,
434434
) {
435435
let file_id = sema.hir_file_for(root);
436-
for ev in root.preorder() {
436+
let mut preorder = root.preorder();
437+
while let Some(ev) = preorder.next() {
437438
match ev {
438439
syntax::WalkEvent::Enter(node) => {
439440
for attr in node.children().filter_map(ast::Attr::cast) {
@@ -516,20 +517,20 @@ fn parse_lint_attribute(
516517
let Some((tag, args_tt)) = attr.as_simple_call() else {
517518
return;
518519
};
519-
let serevity = match tag.as_str() {
520+
let severity = match tag.as_str() {
520521
"allow" => Severity::Allow,
521522
"warn" => Severity::Warning,
522523
"forbid" | "deny" => Severity::Error,
523524
_ => return,
524525
};
525526
for lint in parse_tt_as_comma_sep_paths(args_tt).into_iter().flatten() {
526527
if let Some(lint) = lint.as_single_name_ref() {
527-
job(rustc_stack.entry(lint.to_string()).or_default(), serevity);
528+
job(rustc_stack.entry(lint.to_string()).or_default(), severity);
528529
}
529530
if let Some(tool) = lint.qualifier().and_then(|x| x.as_single_name_ref()) {
530531
if let Some(name_ref) = &lint.segment().and_then(|x| x.name_ref()) {
531532
if tool.to_string() == "clippy" {
532-
job(clippy_stack.entry(name_ref.to_string()).or_default(), serevity);
533+
job(clippy_stack.entry(name_ref.to_string()).or_default(), severity);
533534
}
534535
}
535536
}

0 commit comments

Comments
 (0)