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 | |
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]>
-rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 30 | ||||
-rw-r--r-- | 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::{ | |||
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) { |
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() { | |||
737 | 737 | ||
738 | #[test] | 738 | #[test] |
739 | fn unresolved_attrs_extern_block_hang() { | 739 | fn unresolved_attrs_extern_block_hang() { |
740 | // Regression test for https://github.com/rust-analyzer/rust-analyzer/issues/8905 | ||
740 | check( | 741 | check( |
741 | r#" | 742 | r#" |
742 | #[unresolved] | 743 | #[unresolved] |
@@ -790,7 +791,22 @@ fn derive() {} | |||
790 | crate | 791 | crate |
791 | S: t v | 792 | S: t v |
792 | "#]], | 793 | "#]], |
793 | ) | 794 | ); |
795 | } | ||
796 | |||
797 | #[test] | ||
798 | fn unresolved_attr_with_cfg_attr_hang() { | ||
799 | // Another regression test for https://github.com/rust-analyzer/rust-analyzer/issues/8905 | ||
800 | check( | ||
801 | r#" | ||
802 | #[cfg_attr(not(off), unresolved, unresolved)] | ||
803 | struct S; | ||
804 | "#, | ||
805 | expect![[r#" | ||
806 | crate | ||
807 | S: t v | ||
808 | "#]], | ||
809 | ); | ||
794 | } | 810 | } |
795 | 811 | ||
796 | #[test] | 812 | #[test] |