From d077b8a7e080ffddda6c88c07d927dc54c8cde33 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sat, 22 May 2021 02:30:03 +0200 Subject: Work around non-unique AttrIds --- crates/hir_def/src/nameres/collector.rs | 30 ++++++++++++++++++++++-------- crates/hir_def/src/nameres/tests/macros.rs | 18 +++++++++++++++++- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index 9b108bfe7..014ea4de4 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs @@ -16,6 +16,7 @@ use hir_expand::{ FragmentKind, HirFileId, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, }; use hir_expand::{InFile, MacroCallLoc}; +use itertools::Itertools; use rustc_hash::{FxHashMap, FxHashSet}; use syntax::ast; @@ -1516,14 +1517,27 @@ impl ModCollector<'_, '_> { fn resolve_attributes(&mut self, attrs: &Attrs, mod_item: ModItem) -> Result<(), ()> { let mut ignore_up_to = self.def_collector.skip_attrs.get(&InFile::new(self.file_id, mod_item)).copied(); - for attr in attrs.iter().skip_while(|attr| match ignore_up_to { - Some(id) if attr.id == id => { - ignore_up_to = None; - true - } - Some(_) => true, - None => false, - }) { + let iter = attrs + .iter() + .dedup_by(|a, b| { + // FIXME: this should not be required, all attributes on an item should have a + // unique ID! + // Still, this occurs because `#[cfg_attr]` can "expand" to multiple attributes: + // #[cfg_attr(not(off), unresolved, unresolved)] + // struct S; + // We should come up with a different way to ID attributes. + a.id == b.id + }) + .skip_while(|attr| match ignore_up_to { + Some(id) if attr.id == id => { + ignore_up_to = None; + true + } + Some(_) => true, + None => false, + }); + + for attr in iter { if attr.path.as_ident() == Some(&hir_expand::name![derive]) { self.collect_derive(attr, mod_item); } else if self.is_builtin_or_registered_attr(&attr.path) { diff --git a/crates/hir_def/src/nameres/tests/macros.rs b/crates/hir_def/src/nameres/tests/macros.rs index 133b2d818..3065efd65 100644 --- a/crates/hir_def/src/nameres/tests/macros.rs +++ b/crates/hir_def/src/nameres/tests/macros.rs @@ -737,6 +737,7 @@ fn unresolved_attributes_fall_back_track_per_file_moditems() { #[test] fn unresolved_attrs_extern_block_hang() { + // Regression test for https://github.com/rust-analyzer/rust-analyzer/issues/8905 check( r#" #[unresolved] @@ -790,7 +791,22 @@ fn derive() {} crate S: t v "#]], - ) + ); +} + +#[test] +fn unresolved_attr_with_cfg_attr_hang() { + // Another regression test for https://github.com/rust-analyzer/rust-analyzer/issues/8905 + check( + r#" +#[cfg_attr(not(off), unresolved, unresolved)] +struct S; + "#, + expect![[r#" + crate + S: t v + "#]], + ); } #[test] -- cgit v1.2.3