diff options
-rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 46 |
1 files changed, 31 insertions, 15 deletions
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index 3896be25d..2c8f1b5b8 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs | |||
@@ -94,7 +94,7 @@ pub(super) fn collect_defs( | |||
94 | unresolved_imports: Vec::new(), | 94 | unresolved_imports: Vec::new(), |
95 | resolved_imports: Vec::new(), | 95 | resolved_imports: Vec::new(), |
96 | 96 | ||
97 | unexpanded_macros: Vec::new(), | 97 | unresolved_macros: Vec::new(), |
98 | mod_dirs: FxHashMap::default(), | 98 | mod_dirs: FxHashMap::default(), |
99 | cfg_options, | 99 | cfg_options, |
100 | proc_macros, | 100 | proc_macros, |
@@ -237,7 +237,7 @@ struct DefCollector<'a> { | |||
237 | glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, Visibility)>>, | 237 | glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, Visibility)>>, |
238 | unresolved_imports: Vec<ImportDirective>, | 238 | unresolved_imports: Vec<ImportDirective>, |
239 | resolved_imports: Vec<ImportDirective>, | 239 | resolved_imports: Vec<ImportDirective>, |
240 | unexpanded_macros: Vec<MacroDirective>, | 240 | unresolved_macros: Vec<MacroDirective>, |
241 | mod_dirs: FxHashMap<LocalModuleId, ModDir>, | 241 | mod_dirs: FxHashMap<LocalModuleId, ModDir>, |
242 | cfg_options: &'a CfgOptions, | 242 | cfg_options: &'a CfgOptions, |
243 | /// List of procedural macros defined by this crate. This is read from the dynamic library | 243 | /// List of procedural macros defined by this crate. This is read from the dynamic library |
@@ -374,8 +374,8 @@ impl DefCollector<'_> { | |||
374 | cov_mark::hit!(unresolved_attribute_fallback); | 374 | cov_mark::hit!(unresolved_attribute_fallback); |
375 | 375 | ||
376 | let mut added_items = false; | 376 | let mut added_items = false; |
377 | let unexpanded_macros = std::mem::replace(&mut self.unexpanded_macros, Vec::new()); | 377 | let unresolved_macros = std::mem::replace(&mut self.unresolved_macros, Vec::new()); |
378 | for directive in &unexpanded_macros { | 378 | for directive in &unresolved_macros { |
379 | if let MacroDirectiveKind::Attr { ast_id, mod_item, .. } = &directive.kind { | 379 | if let MacroDirectiveKind::Attr { ast_id, mod_item, .. } = &directive.kind { |
380 | // Make sure to only add such items once. | 380 | // Make sure to only add such items once. |
381 | if !self.ignore_attrs_on.insert(ast_id.ast_id.with_value(*mod_item)) { | 381 | if !self.ignore_attrs_on.insert(ast_id.ast_id.with_value(*mod_item)) { |
@@ -399,7 +399,7 @@ impl DefCollector<'_> { | |||
399 | } | 399 | } |
400 | 400 | ||
401 | // The collection above might add new unresolved macros (eg. derives), so merge the lists. | 401 | // The collection above might add new unresolved macros (eg. derives), so merge the lists. |
402 | self.unexpanded_macros.extend(unexpanded_macros); | 402 | self.unresolved_macros.extend(unresolved_macros); |
403 | 403 | ||
404 | if added_items { | 404 | if added_items { |
405 | // Continue name resolution with the new data. | 405 | // Continue name resolution with the new data. |
@@ -873,7 +873,7 @@ impl DefCollector<'_> { | |||
873 | } | 873 | } |
874 | 874 | ||
875 | fn resolve_macros(&mut self) -> ReachedFixedPoint { | 875 | fn resolve_macros(&mut self) -> ReachedFixedPoint { |
876 | let mut macros = std::mem::replace(&mut self.unexpanded_macros, Vec::new()); | 876 | let mut macros = std::mem::replace(&mut self.unresolved_macros, Vec::new()); |
877 | let mut resolved = Vec::new(); | 877 | let mut resolved = Vec::new(); |
878 | let mut res = ReachedFixedPoint::Yes; | 878 | let mut res = ReachedFixedPoint::Yes; |
879 | macros.retain(|directive| { | 879 | macros.retain(|directive| { |
@@ -929,7 +929,7 @@ impl DefCollector<'_> { | |||
929 | 929 | ||
930 | true | 930 | true |
931 | }); | 931 | }); |
932 | self.unexpanded_macros = macros; | 932 | self.unresolved_macros = macros; |
933 | 933 | ||
934 | for (module_id, macro_call_id, depth) in resolved { | 934 | for (module_id, macro_call_id, depth) in resolved { |
935 | self.collect_macro_expansion(module_id, macro_call_id, depth); | 935 | self.collect_macro_expansion(module_id, macro_call_id, depth); |
@@ -1000,7 +1000,7 @@ impl DefCollector<'_> { | |||
1000 | fn finish(mut self) -> DefMap { | 1000 | fn finish(mut self) -> DefMap { |
1001 | // Emit diagnostics for all remaining unexpanded macros. | 1001 | // Emit diagnostics for all remaining unexpanded macros. |
1002 | 1002 | ||
1003 | for directive in &self.unexpanded_macros { | 1003 | for directive in &self.unresolved_macros { |
1004 | match &directive.kind { | 1004 | match &directive.kind { |
1005 | MacroDirectiveKind::FnLike { ast_id, fragment } => match macro_call_as_call_id( | 1005 | MacroDirectiveKind::FnLike { ast_id, fragment } => match macro_call_as_call_id( |
1006 | ast_id, | 1006 | ast_id, |
@@ -1137,7 +1137,7 @@ impl ModCollector<'_, '_> { | |||
1137 | } | 1137 | } |
1138 | } | 1138 | } |
1139 | 1139 | ||
1140 | if let Err(()) = self.resolve_attributes(&attrs, item) { | 1140 | if let Err(()) = self.resolve_attributes(&attrs, None, item) { |
1141 | // Do not process the item. It has at least one non-builtin attribute, so the | 1141 | // Do not process the item. It has at least one non-builtin attribute, so the |
1142 | // fixed-point algorithm is required to resolve the rest of them. | 1142 | // fixed-point algorithm is required to resolve the rest of them. |
1143 | continue; | 1143 | continue; |
@@ -1453,7 +1453,12 @@ impl ModCollector<'_, '_> { | |||
1453 | /// | 1453 | /// |
1454 | /// Returns `Err` when some attributes could not be resolved to builtins and have been | 1454 | /// Returns `Err` when some attributes could not be resolved to builtins and have been |
1455 | /// registered as unresolved. | 1455 | /// registered as unresolved. |
1456 | fn resolve_attributes(&mut self, attrs: &Attrs, mod_item: ModItem) -> Result<(), ()> { | 1456 | fn resolve_attributes( |
1457 | &mut self, | ||
1458 | attrs: &Attrs, | ||
1459 | mut ignore_up_to: Option<AttrId>, | ||
1460 | mod_item: ModItem, | ||
1461 | ) -> Result<(), ()> { | ||
1457 | fn is_builtin_attr(path: &ModPath) -> bool { | 1462 | fn is_builtin_attr(path: &ModPath) -> bool { |
1458 | if path.kind == PathKind::Plain { | 1463 | if path.kind == PathKind::Plain { |
1459 | if let Some(tool_module) = path.segments().first() { | 1464 | if let Some(tool_module) = path.segments().first() { |
@@ -1484,7 +1489,18 @@ impl ModCollector<'_, '_> { | |||
1484 | return Ok(()); | 1489 | return Ok(()); |
1485 | } | 1490 | } |
1486 | 1491 | ||
1487 | match attrs.iter().find(|attr| !is_builtin_attr(&attr.path)) { | 1492 | match attrs |
1493 | .iter() | ||
1494 | .skip_while(|attr| match ignore_up_to { | ||
1495 | Some(id) if attr.id == id => { | ||
1496 | ignore_up_to = None; | ||
1497 | false | ||
1498 | } | ||
1499 | Some(_) => true, | ||
1500 | None => false, | ||
1501 | }) | ||
1502 | .find(|attr| !is_builtin_attr(&attr.path)) | ||
1503 | { | ||
1488 | Some(non_builtin_attr) => { | 1504 | Some(non_builtin_attr) => { |
1489 | log::debug!("non-builtin attribute {}", non_builtin_attr.path); | 1505 | log::debug!("non-builtin attribute {}", non_builtin_attr.path); |
1490 | 1506 | ||
@@ -1493,7 +1509,7 @@ impl ModCollector<'_, '_> { | |||
1493 | mod_item.ast_id(self.item_tree), | 1509 | mod_item.ast_id(self.item_tree), |
1494 | non_builtin_attr.path.as_ref().clone(), | 1510 | non_builtin_attr.path.as_ref().clone(), |
1495 | ); | 1511 | ); |
1496 | self.def_collector.unexpanded_macros.push(MacroDirective { | 1512 | self.def_collector.unresolved_macros.push(MacroDirective { |
1497 | module_id: self.module_id, | 1513 | module_id: self.module_id, |
1498 | depth: self.macro_depth + 1, | 1514 | depth: self.macro_depth + 1, |
1499 | kind: MacroDirectiveKind::Attr { ast_id, attr: non_builtin_attr.id, mod_item }, | 1515 | kind: MacroDirectiveKind::Attr { ast_id, attr: non_builtin_attr.id, mod_item }, |
@@ -1511,7 +1527,7 @@ impl ModCollector<'_, '_> { | |||
1511 | Some(derive_macros) => { | 1527 | Some(derive_macros) => { |
1512 | for path in derive_macros { | 1528 | for path in derive_macros { |
1513 | let ast_id = AstIdWithPath::new(self.file_id, ast_id, path); | 1529 | let ast_id = AstIdWithPath::new(self.file_id, ast_id, path); |
1514 | self.def_collector.unexpanded_macros.push(MacroDirective { | 1530 | self.def_collector.unresolved_macros.push(MacroDirective { |
1515 | module_id: self.module_id, | 1531 | module_id: self.module_id, |
1516 | depth: self.macro_depth + 1, | 1532 | depth: self.macro_depth + 1, |
1517 | kind: MacroDirectiveKind::Derive { ast_id, derive_attr: derive.id }, | 1533 | kind: MacroDirectiveKind::Derive { ast_id, derive_attr: derive.id }, |
@@ -1686,7 +1702,7 @@ impl ModCollector<'_, '_> { | |||
1686 | ast_id.path.kind = PathKind::Super(0); | 1702 | ast_id.path.kind = PathKind::Super(0); |
1687 | } | 1703 | } |
1688 | 1704 | ||
1689 | self.def_collector.unexpanded_macros.push(MacroDirective { | 1705 | self.def_collector.unresolved_macros.push(MacroDirective { |
1690 | module_id: self.module_id, | 1706 | module_id: self.module_id, |
1691 | depth: self.macro_depth + 1, | 1707 | depth: self.macro_depth + 1, |
1692 | kind: MacroDirectiveKind::FnLike { ast_id, fragment: mac.fragment }, | 1708 | kind: MacroDirectiveKind::FnLike { ast_id, fragment: mac.fragment }, |
@@ -1731,7 +1747,7 @@ mod tests { | |||
1731 | glob_imports: FxHashMap::default(), | 1747 | glob_imports: FxHashMap::default(), |
1732 | unresolved_imports: Vec::new(), | 1748 | unresolved_imports: Vec::new(), |
1733 | resolved_imports: Vec::new(), | 1749 | resolved_imports: Vec::new(), |
1734 | unexpanded_macros: Vec::new(), | 1750 | unresolved_macros: Vec::new(), |
1735 | mod_dirs: FxHashMap::default(), | 1751 | mod_dirs: FxHashMap::default(), |
1736 | cfg_options: &CfgOptions::default(), | 1752 | cfg_options: &CfgOptions::default(), |
1737 | proc_macros: Default::default(), | 1753 | proc_macros: Default::default(), |