8888: fix: fix unresolved attribute fallback again r=jonas-schievink a=jonas-schievink

`ModItem`s are per-file, so we have to track the file if we store them in the crate-level `DefCollector`.

Fixes the remaining issue in https://github.com/rust-analyzer/rust-analyzer/pull/8882#issuecomment-844379170

bors r+

Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
This commit is contained in:
bors[bot] 2021-05-19 20:10:00 +00:00 committed by GitHub
commit 7cb5920372
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 4 deletions

View File

@ -246,7 +246,7 @@ struct DefCollector<'a> {
proc_macros: Vec<(Name, ProcMacroExpander)>,
exports_proc_macros: bool,
from_glob_import: PerNsGlobImports,
ignore_attrs_on: FxHashSet<ModItem>,
ignore_attrs_on: FxHashSet<InFile<ModItem>>,
}
impl DefCollector<'_> {
@ -372,9 +372,9 @@ impl DefCollector<'_> {
let mut added_items = false;
let unexpanded_macros = std::mem::replace(&mut self.unexpanded_macros, Vec::new());
for directive in &unexpanded_macros {
if let MacroDirectiveKind::Attr { mod_item, .. } = &directive.kind {
if let MacroDirectiveKind::Attr { ast_id, mod_item, .. } = &directive.kind {
// Make sure to only add such items once.
if !self.ignore_attrs_on.insert(*mod_item) {
if !self.ignore_attrs_on.insert(ast_id.ast_id.with_value(*mod_item)) {
continue;
}
@ -1463,7 +1463,7 @@ impl ModCollector<'_, '_> {
// We failed to resolve an attribute on this item earlier, and are falling back to treating
// the item as-is.
if self.def_collector.ignore_attrs_on.contains(&mod_item) {
if self.def_collector.ignore_attrs_on.contains(&InFile::new(self.file_id, mod_item)) {
return Ok(());
}

View File

@ -706,6 +706,35 @@ fn builtin_derive_with_unresolved_attributes_fall_back() {
assert_eq!(map.modules[map.root].scope.impls().len(), 1);
}
#[test]
fn unresolved_attributes_fall_back_track_per_file_moditems() {
// Tests that we track per-file ModItems when ignoring an unresolved attribute.
// Just tracking the `ModItem` leads to `Foo` getting ignored.
check(
r#"
//- /main.rs crate:main
mod submod;
#[unresolved]
struct Foo;
//- /submod.rs
#[unresolved]
struct Bar;
"#,
expect![[r#"
crate
Foo: t v
submod: t
crate::submod
Bar: t v
"#]],
);
}
#[test]
fn macro_expansion_overflow() {
cov_mark::check!(macro_expansion_overflow);