diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-05-22 01:31:17 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2021-05-22 01:31:17 +0100 |
commit | 3cfe2d0a5d663d29c3d196f9d16e91964780792a (patch) | |
tree | 17b90dabb92c14bdd227ed432aede029ba6b6490 /crates/hir_def/src/nameres/collector.rs | |
parent | ae24651e445444d4ed4275a717ac10980f2957a4 (diff) | |
parent | d077b8a7e080ffddda6c88c07d927dc54c8cde33 (diff) |
Merge #8918
8918: fix: fix hang caused by non-unique attribute IDs r=jonas-schievink a=jonas-schievink
Fixes https://github.com/rust-analyzer/rust-analyzer/issues/8905 (again)
bors r+
Co-authored-by: Jonas Schievink <[email protected]>
Diffstat (limited to 'crates/hir_def/src/nameres/collector.rs')
-rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 30 |
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 | }; |
18 | use hir_expand::{InFile, MacroCallLoc}; | 18 | use hir_expand::{InFile, MacroCallLoc}; |
19 | use itertools::Itertools; | ||
19 | use rustc_hash::{FxHashMap, FxHashSet}; | 20 | use rustc_hash::{FxHashMap, FxHashSet}; |
20 | use syntax::ast; | 21 | use 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) { |