mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-15 17:28:09 +00:00
Auto merge of #15601 - Veykril:diag-derive, r=Veykril
fix: Temporarily skip decl check in derive expansions "Fixes https://github.com/rust-lang/rust-analyzer/issues/15344"
This commit is contained in:
commit
15e1356149
3 changed files with 63 additions and 25 deletions
|
@ -163,25 +163,56 @@ impl<'a> DeclValidator<'a> {
|
||||||
|| allows.contains(allow::NONSTANDARD_STYLE)
|
|| allows.contains(allow::NONSTANDARD_STYLE)
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
let db = self.db.upcast();
|
||||||
is_allowed(id)
|
let file_id_is_derive = || {
|
||||||
// go upwards one step or give up
|
match id {
|
||||||
|| match id {
|
AttrDefId::ModuleId(m) => {
|
||||||
AttrDefId::ModuleId(m) => m.containing_module(self.db.upcast()).map(|v| v.into()),
|
m.def_map(db)[m.local_id].origin.file_id().map(Into::into)
|
||||||
AttrDefId::FunctionId(f) => Some(f.lookup(self.db.upcast()).container.into()),
|
}
|
||||||
AttrDefId::StaticId(sid) => Some(sid.lookup(self.db.upcast()).container.into()),
|
AttrDefId::FunctionId(f) => Some(f.lookup(db).id.file_id()),
|
||||||
AttrDefId::ConstId(cid) => Some(cid.lookup(self.db.upcast()).container.into()),
|
AttrDefId::StaticId(sid) => Some(sid.lookup(db).id.file_id()),
|
||||||
AttrDefId::TraitId(tid) => Some(tid.lookup(self.db.upcast()).container.into()),
|
AttrDefId::ConstId(cid) => Some(cid.lookup(db).id.file_id()),
|
||||||
AttrDefId::TraitAliasId(taid) => Some(taid.lookup(self.db.upcast()).container.into()),
|
AttrDefId::TraitId(tid) => Some(tid.lookup(db).id.file_id()),
|
||||||
AttrDefId::ImplId(iid) => Some(iid.lookup(self.db.upcast()).container.into()),
|
AttrDefId::TraitAliasId(taid) => Some(taid.lookup(db).id.file_id()),
|
||||||
AttrDefId::ExternBlockId(id) => Some(id.lookup(self.db.upcast()).container.into()),
|
AttrDefId::ImplId(iid) => Some(iid.lookup(db).id.file_id()),
|
||||||
AttrDefId::ExternCrateId(id) => Some(id.lookup(self.db.upcast()).container.into()),
|
AttrDefId::ExternBlockId(id) => Some(id.lookup(db).id.file_id()),
|
||||||
AttrDefId::UseId(id) => Some(id.lookup(self.db.upcast()).container.into()),
|
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
|
// These warnings should not explore macro definitions at all
|
||||||
AttrDefId::MacroId(_) => None,
|
AttrDefId::MacroId(_) => None,
|
||||||
AttrDefId::AdtId(aid) => match aid {
|
AttrDefId::AdtId(aid) => match aid {
|
||||||
AdtId::StructId(sid) => Some(sid.lookup(self.db.upcast()).container.into()),
|
AdtId::StructId(sid) => Some(sid.lookup(db).id.file_id()),
|
||||||
AdtId::EnumId(eid) => Some(eid.lookup(self.db.upcast()).container.into()),
|
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())
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
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(db).container.into()),
|
||||||
|
AdtId::EnumId(eid) => Some(eid.lookup(db).container.into()),
|
||||||
// Unions aren't yet supported
|
// Unions aren't yet supported
|
||||||
AdtId::UnionId(_) => None,
|
AdtId::UnionId(_) => None,
|
||||||
},
|
},
|
||||||
|
@ -191,6 +222,12 @@ impl<'a> DeclValidator<'a> {
|
||||||
AttrDefId::GenericParamId(_) => None,
|
AttrDefId::GenericParamId(_) => None,
|
||||||
}
|
}
|
||||||
.is_some_and(|mid| self.allowed(mid, allow_name, true))
|
.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) {
|
fn validate_func(&mut self, func: FunctionId) {
|
||||||
|
|
|
@ -564,8 +564,8 @@ impl Module {
|
||||||
emit_def_diagnostic(db, acc, diag);
|
emit_def_diagnostic(db, acc, diag);
|
||||||
}
|
}
|
||||||
|
|
||||||
for decl in self.declarations(db) {
|
for def in self.declarations(db) {
|
||||||
match decl {
|
match def {
|
||||||
ModuleDef::Module(m) => {
|
ModuleDef::Module(m) => {
|
||||||
// Only add diagnostics from inline modules
|
// Only add diagnostics from inline modules
|
||||||
if def_map[m.id.local_id].origin.is_inline() {
|
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() {
|
for diag in db.trait_data_with_diagnostics(t.id).1.iter() {
|
||||||
emit_def_diagnostic(db, acc, diag);
|
emit_def_diagnostic(db, acc, diag);
|
||||||
}
|
}
|
||||||
acc.extend(decl.diagnostics(db))
|
acc.extend(def.diagnostics(db))
|
||||||
}
|
}
|
||||||
ModuleDef::Adt(adt) => {
|
ModuleDef::Adt(adt) => {
|
||||||
match 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),
|
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));
|
self.legacy_macros(db).into_iter().for_each(|m| emit_macro_def_diagnostics(db, acc, m));
|
||||||
|
|
|
@ -433,7 +433,8 @@ fn handle_lint_attributes(
|
||||||
diagnostics_of_range: &mut FxHashMap<InFile<SyntaxNode>, &mut Diagnostic>,
|
diagnostics_of_range: &mut FxHashMap<InFile<SyntaxNode>, &mut Diagnostic>,
|
||||||
) {
|
) {
|
||||||
let file_id = sema.hir_file_for(root);
|
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 {
|
match ev {
|
||||||
syntax::WalkEvent::Enter(node) => {
|
syntax::WalkEvent::Enter(node) => {
|
||||||
for attr in node.children().filter_map(ast::Attr::cast) {
|
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 {
|
let Some((tag, args_tt)) = attr.as_simple_call() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let serevity = match tag.as_str() {
|
let severity = match tag.as_str() {
|
||||||
"allow" => Severity::Allow,
|
"allow" => Severity::Allow,
|
||||||
"warn" => Severity::Warning,
|
"warn" => Severity::Warning,
|
||||||
"forbid" | "deny" => Severity::Error,
|
"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() {
|
for lint in parse_tt_as_comma_sep_paths(args_tt).into_iter().flatten() {
|
||||||
if let Some(lint) = lint.as_single_name_ref() {
|
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(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 let Some(name_ref) = &lint.segment().and_then(|x| x.name_ref()) {
|
||||||
if tool.to_string() == "clippy" {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue