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 | 90 |
1 files changed, 43 insertions, 47 deletions
diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs index 0a6cd0fe9e..262bc538b9 100644 --- a/crates/hir-def/src/nameres/collector.rs +++ b/crates/hir-def/src/nameres/collector.rs @@ -5,7 +5,7 @@ use std::{cmp::Ordering, iter, mem, ops::Not}; -use base_db::{CrateId, Dependency, FileId}; +use base_db::{CrateId, CrateOrigin, Dependency, FileId, LangCrateOrigin}; use cfg::{CfgExpr, CfgOptions}; use either::Either; use hir_expand::{ @@ -15,15 +15,13 @@ use hir_expand::{ builtin_fn_macro::find_builtin_macro, name::{name, AsName, Name}, proc_macro::CustomProcMacroExpander, - ExpandResult, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, MacroCallLoc, - MacroDefId, MacroDefKind, + ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, }; use itertools::{izip, Itertools}; use la_arena::Idx; use limit::Limit; use rustc_hash::{FxHashMap, FxHashSet}; use span::{Edition, ErasedFileAstId, FileAstId, Span, SyntaxContextId}; -use stdx::always; use syntax::ast; use triomphe::Arc; @@ -279,7 +277,8 @@ impl DefCollector<'_> { fn seed_with_top_level(&mut self) { let _p = tracing::span!(tracing::Level::INFO, "seed_with_top_level").entered(); - let file_id = self.db.crate_graph()[self.def_map.krate].root_file_id; + let crate_graph = self.db.crate_graph(); + let file_id = crate_graph[self.def_map.krate].root_file_id; let item_tree = self.db.file_item_tree(file_id.into()); let attrs = item_tree.top_level_attrs(self.db, self.def_map.krate); let crate_data = Arc::get_mut(&mut self.def_map.data).unwrap(); @@ -288,19 +287,14 @@ impl DefCollector<'_> { crate_data.proc_macro_loading_error = Some(e.clone()); } - for (name, dep) in &self.deps { - if dep.is_prelude() { - crate_data - .extern_prelude - .insert(name.clone(), (CrateRootModuleId { krate: dep.crate_id }, None)); - } - } + let mut process = true; // Process other crate-level attributes. for attr in &*attrs { if let Some(cfg) = attr.cfg() { if self.cfg_options.check(&cfg) == Some(false) { - return; + process = false; + break; } } let Some(attr_name) = attr.path.as_ident() else { continue }; @@ -350,9 +344,38 @@ impl DefCollector<'_> { } } - crate_data.shrink_to_fit(); + for (name, dep) in &self.deps { + if dep.is_prelude() { + // This is a bit confusing but the gist is that `no_core` and `no_std` remove the + // sysroot dependence on `core` and `std` respectively. Our `CrateGraph` is eagerly + // constructed with them in place no matter what though, since at that point we + // don't do pre-configured attribute resolution yet. + // So here check if we are no_core / no_std and we are trying to add the + // corresponding dep from the sysroot + let skip = match crate_graph[dep.crate_id].origin { + CrateOrigin::Lang(LangCrateOrigin::Core) => { + crate_data.no_core && dep.is_sysroot() + } + CrateOrigin::Lang(LangCrateOrigin::Std) => { + crate_data.no_std && dep.is_sysroot() + } + _ => false, + }; + if skip { + continue; + } + crate_data + .extern_prelude + .insert(name.clone(), (CrateRootModuleId { krate: dep.crate_id }, None)); + } + } + self.inject_prelude(); + if !process { + return; + } + ModCollector { def_collector: self, macro_depth: 0, @@ -362,6 +385,7 @@ impl DefCollector<'_> { mod_dir: ModDir::root(), } .collect_in_top_module(item_tree.top_level_items()); + Arc::get_mut(&mut self.def_map.data).unwrap().shrink_to_fit(); } fn seed_with_inner(&mut self, tree_id: TreeId) { @@ -519,15 +543,12 @@ impl DefCollector<'_> { let krate = if self.def_map.data.no_std { name![core] + } else if self.def_map.extern_prelude().any(|(name, _)| *name == name![std]) { + name![std] } else { - let std = name![std]; - if self.def_map.extern_prelude().any(|(name, _)| *name == std) { - std - } else { - // If `std` does not exist for some reason, fall back to core. This mostly helps - // keep r-a's own tests minimal. - name![core] - } + // If `std` does not exist for some reason, fall back to core. This mostly helps + // keep r-a's own tests minimal. + name![core] }; let edition = match self.def_map.data.edition { @@ -1389,31 +1410,6 @@ impl DefCollector<'_> { } let file_id = macro_call_id.as_file(); - // First, fetch the raw expansion result for purposes of error reporting. This goes through - // `parse_macro_expansion_error` to avoid depending on the full expansion result (to improve - // incrementality). - // FIXME: This kind of error fetching feels a bit odd? - let ExpandResult { value: errors, err } = - self.db.parse_macro_expansion_error(macro_call_id); - if let Some(err) = err { - let loc: MacroCallLoc = self.db.lookup_intern_macro_call(macro_call_id); - let diag = match err { - // why is this reported here? - hir_expand::ExpandError::UnresolvedProcMacro(krate) => { - always!(krate == loc.def.krate); - DefDiagnostic::unresolved_proc_macro(module_id, loc.kind.clone(), loc.def.krate) - } - _ => DefDiagnostic::macro_error(module_id, loc.kind, err.to_string()), - }; - - self.def_map.diagnostics.push(diag); - } - if !errors.is_empty() { - let loc: MacroCallLoc = self.db.lookup_intern_macro_call(macro_call_id); - let diag = DefDiagnostic::macro_expansion_parse_error(module_id, loc.kind, errors); - self.def_map.diagnostics.push(diag); - } - // Then, fetch and process the item tree. This will reuse the expansion result from above. let item_tree = self.db.file_item_tree(file_id); |