Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/nameres/collector.rs')
| -rw-r--r-- | crates/hir-def/src/nameres/collector.rs | 159 |
1 files changed, 66 insertions, 93 deletions
diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs index 587997c473..6d2eb71549 100644 --- a/crates/hir-def/src/nameres/collector.rs +++ b/crates/hir-def/src/nameres/collector.rs @@ -10,18 +10,19 @@ use cfg::{CfgExpr, CfgOptions}; use either::Either; use hir_expand::{ attrs::{Attr, AttrId}, - builtin_attr_macro::{find_builtin_attr, BuiltinAttrExpander}, + builtin_attr_macro::find_builtin_attr, builtin_derive_macro::find_builtin_derive, builtin_fn_macro::find_builtin_macro, name::{name, AsName, Name}, proc_macro::CustomProcMacroExpander, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, }; +use intern::Interned; use itertools::{izip, Itertools}; use la_arena::Idx; use limit::Limit; use rustc_hash::{FxHashMap, FxHashSet}; -use span::{Edition, ErasedFileAstId, FileAstId, Span, SyntaxContextId}; +use span::{Edition, ErasedFileAstId, FileAstId, SyntaxContextId}; use syntax::ast; use triomphe::Arc; @@ -75,36 +76,23 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, def_map: DefMap, tree_id: TreeI let proc_macros = if krate.is_proc_macro { match db.proc_macros().get(&def_map.krate) { - Some(Ok(proc_macros)) => { - Ok(proc_macros - .iter() - .enumerate() - .map(|(idx, it)| { - // FIXME: a hacky way to create a Name from string. - let name = tt::Ident { - text: it.name.clone(), - span: Span { - range: syntax::TextRange::empty(syntax::TextSize::new(0)), - anchor: span::SpanAnchor { - file_id: FileId::BOGUS, - ast_id: span::ROOT_ERASED_FILE_AST_ID, - }, - ctx: SyntaxContextId::ROOT, - }, - }; - ( - name.as_name(), - if it.disabled { - CustomProcMacroExpander::disabled() - } else { - CustomProcMacroExpander::new( - hir_expand::proc_macro::ProcMacroId::new(idx as u32), - ) - }, - ) - }) - .collect()) - } + Some(Ok(proc_macros)) => Ok(proc_macros + .iter() + .enumerate() + .map(|(idx, it)| { + let name = Name::new_text_dont_use(it.name.clone()); + ( + name, + if it.disabled { + CustomProcMacroExpander::disabled() + } else { + CustomProcMacroExpander::new(hir_expand::proc_macro::ProcMacroId::new( + idx as u32, + )) + }, + ) + }) + .collect()), Some(Err(e)) => Err(e.clone().into_boxed_str()), None => Err("No proc-macros present for crate".to_owned().into_boxed_str()), } @@ -270,12 +258,13 @@ struct DefCollector<'a> { /// /// This also stores the attributes to skip when we resolve derive helpers and non-macro /// non-builtin attributes in general. + // FIXME: There has to be a better way to do this skip_attrs: FxHashMap<InFile<ModItem>, AttrId>, } impl DefCollector<'_> { fn seed_with_top_level(&mut self) { - let _p = tracing::span!(tracing::Level::INFO, "seed_with_top_level").entered(); + let _p = tracing::info_span!("seed_with_top_level").entered(); let crate_graph = self.db.crate_graph(); let file_id = crate_graph[self.def_map.krate].root_file_id; @@ -410,17 +399,17 @@ impl DefCollector<'_> { } fn resolution_loop(&mut self) { - let _p = tracing::span!(tracing::Level::INFO, "DefCollector::resolution_loop").entered(); + let _p = tracing::info_span!("DefCollector::resolution_loop").entered(); // main name resolution fixed-point loop. let mut i = 0; 'resolve_attr: loop { - let _p = tracing::span!(tracing::Level::INFO, "resolve_macros loop").entered(); + let _p = tracing::info_span!("resolve_macros loop").entered(); 'resolve_macros: loop { self.db.unwind_if_cancelled(); { - let _p = tracing::span!(tracing::Level::INFO, "resolve_imports loop").entered(); + let _p = tracing::info_span!("resolve_imports loop").entered(); 'resolve_imports: loop { if self.resolve_imports() == ReachedFixedPoint::Yes { @@ -446,7 +435,7 @@ impl DefCollector<'_> { } fn collect(&mut self) { - let _p = tracing::span!(tracing::Level::INFO, "DefCollector::collect").entered(); + let _p = tracing::info_span!("DefCollector::collect").entered(); self.resolution_loop(); @@ -794,7 +783,7 @@ impl DefCollector<'_> { } fn resolve_import(&self, module_id: LocalModuleId, import: &Import) -> PartialResolvedImport { - let _p = tracing::span!(tracing::Level::INFO, "resolve_import", import_path = %import.path.display(self.db.upcast())) + let _p = tracing::info_span!("resolve_import", import_path = %import.path.display(self.db.upcast())) .entered(); tracing::debug!("resolving import: {:?} ({:?})", import, self.def_map.data.edition); match import.source { @@ -856,7 +845,7 @@ impl DefCollector<'_> { } fn record_resolved_import(&mut self, directive: &ImportDirective) { - let _p = tracing::span!(tracing::Level::INFO, "record_resolved_import").entered(); + let _p = tracing::info_span!("record_resolved_import").entered(); let module_id = directive.module_id; let import = &directive.import; @@ -1136,18 +1125,18 @@ impl DefCollector<'_> { MacroSubNs::Attr } }; - let resolver = |path| { + let resolver = |path: &_| { let resolved_res = self.def_map.resolve_path_fp_with_macro( self.db, ResolveMode::Other, directive.module_id, - &path, + path, BuiltinShadowMode::Module, Some(subns), ); resolved_res.resolved_def.take_macros().map(|it| (it, self.db.macro_def(it))) }; - let resolver_def_id = |path| resolver(path).map(|(_, it)| it); + let resolver_def_id = |path: &_| resolver(path).map(|(_, it)| it); match &directive.kind { MacroDirectiveKind::FnLike { ast_id, expand_to, ctxt: call_site } => { @@ -1250,22 +1239,28 @@ impl DefCollector<'_> { } } - let def = match resolver_def_id(path.clone()) { + let def = match resolver_def_id(path) { Some(def) if def.is_attribute() => def, _ => return Resolved::No, }; - let call_id = - attr_macro_as_call_id(self.db, file_ast_id, attr, self.def_map.krate, def); - if let MacroDefId { - kind: - MacroDefKind::BuiltInAttr( - BuiltinAttrExpander::Derive | BuiltinAttrExpander::DeriveConst, - _, - ), - .. - } = def - { + // Skip #[test]/#[bench] expansion, which would merely result in more memory usage + // due to duplicating functions into macro expansions + if matches!( + def.kind, + MacroDefKind::BuiltInAttr(_, expander) + if expander.is_test() || expander.is_bench() + ) { + return recollect_without(self); + } + + let call_id = || { + attr_macro_as_call_id(self.db, file_ast_id, attr, self.def_map.krate, def) + }; + if matches!(def, + MacroDefId { kind: MacroDefKind::BuiltInAttr(_, exp), .. } + if exp.is_derive() + ) { // Resolved to `#[derive]`, we don't actually expand this attribute like // normal (as that would just be an identity expansion with extra output) // Instead we treat derive attributes special and apply them separately. @@ -1290,9 +1285,14 @@ impl DefCollector<'_> { match attr.parse_path_comma_token_tree(self.db.upcast()) { Some(derive_macros) => { + let call_id = call_id(); let mut len = 0; for (idx, (path, call_site)) in derive_macros.enumerate() { - let ast_id = AstIdWithPath::new(file_id, ast_id.value, path); + let ast_id = AstIdWithPath::new( + file_id, + ast_id.value, + Interned::new(path), + ); self.unresolved_macros.push(MacroDirective { module_id: directive.module_id, depth: directive.depth + 1, @@ -1312,13 +1312,6 @@ impl DefCollector<'_> { // This is just a trick to be able to resolve the input to derives // as proper paths in `Semantics`. // Check the comment in [`builtin_attr_macro`]. - let call_id = attr_macro_as_call_id( - self.db, - file_ast_id, - attr, - self.def_map.krate, - def, - ); self.def_map.modules[directive.module_id] .scope .init_derive_attribute(ast_id, attr.id, call_id, len + 1); @@ -1336,17 +1329,8 @@ impl DefCollector<'_> { return recollect_without(self); } - // Skip #[test]/#[bench] expansion, which would merely result in more memory usage - // due to duplicating functions into macro expansions - if matches!( - def.kind, - MacroDefKind::BuiltInAttr(expander, _) - if expander.is_test() || expander.is_bench() - ) { - return recollect_without(self); - } - - if let MacroDefKind::ProcMacro(exp, ..) = def.kind { + let call_id = call_id(); + if let MacroDefKind::ProcMacro(_, exp, _) = def.kind { // If proc attribute macro expansion is disabled, skip expanding it here if !self.db.expand_proc_attr_macros() { self.def_map.diagnostics.push(DefDiagnostic::unresolved_proc_macro( @@ -1430,7 +1414,7 @@ impl DefCollector<'_> { fn finish(mut self) -> DefMap { // Emit diagnostics for all remaining unexpanded macros. - let _p = tracing::span!(tracing::Level::INFO, "DefCollector::finish").entered(); + let _p = tracing::info_span!("DefCollector::finish").entered(); for directive in &self.unresolved_macros { match &directive.kind { @@ -1447,7 +1431,7 @@ impl DefCollector<'_> { self.db, ResolveMode::Other, directive.module_id, - &path, + path, BuiltinShadowMode::Module, Some(MacroSubNs::Bang), ); @@ -1481,7 +1465,7 @@ impl DefCollector<'_> { derive_index: *derive_pos as u32, derive_macro_id: *derive_macro_id, }, - ast_id.path.clone(), + ast_id.path.as_ref().clone(), )); } // These are diagnosed by `reseed_with_unresolved_attribute`, as that function consumes them @@ -2116,7 +2100,7 @@ impl ModCollector<'_, '_> { let ast_id = AstIdWithPath::new( self.file_id(), mod_item.ast_id(self.item_tree), - attr.path.as_ref().clone(), + attr.path.clone(), ); self.def_collector.unresolved_macros.push(MacroDirective { module_id: self.module_id, @@ -2162,19 +2146,7 @@ impl ModCollector<'_, '_> { let name; let name = match attrs.by_key("rustc_builtin_macro").string_value() { Some(it) => { - // FIXME: a hacky way to create a Name from string. - name = tt::Ident { - text: it.into(), - span: Span { - range: syntax::TextRange::empty(syntax::TextSize::new(0)), - anchor: span::SpanAnchor { - file_id: FileId::BOGUS, - ast_id: span::ROOT_ERASED_FILE_AST_ID, - }, - ctx: SyntaxContextId::ROOT, - }, - } - .as_name(); + name = Name::new_text_dont_use(it.into()); &name } None => { @@ -2310,7 +2282,7 @@ impl ModCollector<'_, '_> { &MacroCall { ref path, ast_id, expand_to, ctxt }: &MacroCall, container: ItemContainerId, ) { - let ast_id = AstIdWithPath::new(self.file_id(), ast_id, ModPath::clone(path)); + let ast_id = AstIdWithPath::new(self.file_id(), ast_id, path.clone()); let db = self.def_collector.db; // FIXME: Immediately expanding in "Case 1" is insufficient since "Case 2" may also define @@ -2320,7 +2292,8 @@ impl ModCollector<'_, '_> { // Case 1: try to resolve macro calls with single-segment name and expand macro_rules if let Ok(res) = macro_call_as_call_id_with_eager( db.upcast(), - &ast_id, + ast_id.ast_id, + &ast_id.path, ctxt, expand_to, self.def_collector.def_map.krate, @@ -2347,7 +2320,7 @@ impl ModCollector<'_, '_> { db, ResolveMode::Other, self.module_id, - &path, + path, BuiltinShadowMode::Module, Some(MacroSubNs::Bang), ); |