aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/nameres/collector.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src/nameres/collector.rs')
-rw-r--r--crates/hir_def/src/nameres/collector.rs30
1 files changed, 22 insertions, 8 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::{
16 FragmentKind, HirFileId, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, 16 FragmentKind, HirFileId, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind,
17}; 17};
18use hir_expand::{InFile, MacroCallLoc}; 18use hir_expand::{InFile, MacroCallLoc};
19use itertools::Itertools;
19use rustc_hash::{FxHashMap, FxHashSet}; 20use rustc_hash::{FxHashMap, FxHashSet};
20use syntax::ast; 21use syntax::ast;
21 22
@@ -1516,14 +1517,27 @@ impl ModCollector<'_, '_> {
1516 fn resolve_attributes(&mut self, attrs: &Attrs, mod_item: ModItem) -> Result<(), ()> { 1517 fn resolve_attributes(&mut self, attrs: &Attrs, mod_item: ModItem) -> Result<(), ()> {
1517 let mut ignore_up_to = 1518 let mut ignore_up_to =
1518 self.def_collector.skip_attrs.get(&InFile::new(self.file_id, mod_item)).copied(); 1519 self.def_collector.skip_attrs.get(&InFile::new(self.file_id, mod_item)).copied();
1519 for attr in attrs.iter().skip_while(|attr| match ignore_up_to { 1520 let iter = attrs
1520 Some(id) if attr.id == id => { 1521 .iter()
1521 ignore_up_to = None; 1522 .dedup_by(|a, b| {
1522 true 1523 // FIXME: this should not be required, all attributes on an item should have a
1523 } 1524 // unique ID!
1524 Some(_) => true, 1525 // Still, this occurs because `#[cfg_attr]` can "expand" to multiple attributes:
1525 None => false, 1526 // #[cfg_attr(not(off), unresolved, unresolved)]
1526 }) { 1527 // struct S;
1528 // We should come up with a different way to ID attributes.
1529 a.id == b.id
1530 })
1531 .skip_while(|attr| match ignore_up_to {
1532 Some(id) if attr.id == id => {
1533 ignore_up_to = None;
1534 true
1535 }
1536 Some(_) => true,
1537 None => false,
1538 });
1539
1540 for attr in iter {
1527 if attr.path.as_ident() == Some(&hir_expand::name![derive]) { 1541 if attr.path.as_ident() == Some(&hir_expand::name![derive]) {
1528 self.collect_derive(attr, mod_item); 1542 self.collect_derive(attr, mod_item);
1529 } else if self.is_builtin_or_registered_attr(&attr.path) { 1543 } else if self.is_builtin_or_registered_attr(&attr.path) {