diff --git a/Cargo.lock b/Cargo.lock index 982468765b4f..607b831f01b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -71,7 +71,6 @@ version = "0.0.0" dependencies = [ "cfg", "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "profile", "rustc-hash", "salsa", "semver", @@ -501,7 +500,6 @@ dependencies = [ "hir-ty", "itertools", "once_cell", - "profile", "rustc-hash", "smallvec", "span", @@ -565,7 +563,6 @@ dependencies = [ "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "limit", "mbe", - "profile", "rustc-hash", "smallvec", "span", @@ -601,7 +598,6 @@ dependencies = [ "nohash-hasher", "once_cell", "oorandom", - "profile", "project-model", "ra-ap-rustc_abi", "ra-ap-rustc_index 0.35.0", @@ -673,7 +669,6 @@ dependencies = [ "hir", "ide-db", "itertools", - "profile", "smallvec", "sourcegen", "stdx", @@ -695,7 +690,6 @@ dependencies = [ "ide-db", "itertools", "once_cell", - "profile", "smallvec", "stdx", "syntax", @@ -753,7 +747,6 @@ dependencies = [ "ide-db", "itertools", "once_cell", - "profile", "serde_json", "sourcegen", "stdx", @@ -1233,6 +1226,7 @@ dependencies = [ "ra-ap-rustc_lexer", "sourcegen", "stdx", + "tracing", ] [[package]] @@ -1302,7 +1296,6 @@ dependencies = [ "memmap2", "object 0.32.0", "paths", - "profile", "rustc-hash", "serde", "serde_json", @@ -1386,7 +1379,6 @@ dependencies = [ "itertools", "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "paths", - "profile", "rustc-hash", "semver", "serde", @@ -1925,7 +1917,6 @@ dependencies = [ "once_cell", "parser", "proc-macro2", - "profile", "quote", "ra-ap-rustc_lexer", "rayon", diff --git a/crates/base-db/Cargo.toml b/crates/base-db/Cargo.toml index 801ba2d1f6c8..118abf5d6eb8 100644 --- a/crates/base-db/Cargo.toml +++ b/crates/base-db/Cargo.toml @@ -21,7 +21,6 @@ tracing.workspace = true # local deps cfg.workspace = true -profile.workspace = true stdx.workspace = true syntax.workspace = true vfs.workspace = true diff --git a/crates/hir-def/src/body.rs b/crates/hir-def/src/body.rs index ce8a9eab14a9..37d37fd33115 100644 --- a/crates/hir-def/src/body.rs +++ b/crates/hir-def/src/body.rs @@ -13,7 +13,6 @@ use cfg::{CfgExpr, CfgOptions}; use either::Either; use hir_expand::{name::Name, HirFileId, InFile}; use la_arena::{Arena, ArenaMap}; -use profile::Count; use rustc_hash::FxHashMap; use syntax::{ast, AstPtr, SyntaxNodePtr}; use triomphe::Arc; @@ -51,7 +50,6 @@ pub struct Body { pub body_expr: ExprId, /// Block expressions in this body that may contain inner items. block_scopes: Vec, - _c: Count, } pub type ExprPtr = AstPtr; @@ -216,7 +214,6 @@ impl Body { fn shrink_to_fit(&mut self) { let Self { - _c: _, body_expr: _, block_scopes, exprs, @@ -300,7 +297,6 @@ impl Default for Body { params: Default::default(), block_scopes: Default::default(), binding_owners: Default::default(), - _c: Default::default(), } } } diff --git a/crates/hir-def/src/body/lower.rs b/crates/hir-def/src/body/lower.rs index ad8782d3d1e3..c9300898b386 100644 --- a/crates/hir-def/src/body/lower.rs +++ b/crates/hir-def/src/body/lower.rs @@ -10,7 +10,6 @@ use hir_expand::{ ExpandError, InFile, }; use intern::Interned; -use profile::Count; use rustc_hash::FxHashMap; use smallvec::SmallVec; use span::AstIdMap; @@ -76,7 +75,6 @@ pub(super) fn lower( params: Vec::new(), body_expr: dummy_expr_id(), block_scopes: Vec::new(), - _c: Count::new(), }, expander, current_try_block_label: None, diff --git a/crates/hir-def/src/item_tree.rs b/crates/hir-def/src/item_tree.rs index c7cf611589b0..008fa7ef13af 100644 --- a/crates/hir-def/src/item_tree.rs +++ b/crates/hir-def/src/item_tree.rs @@ -50,7 +50,6 @@ use either::Either; use hir_expand::{attrs::RawAttrs, name::Name, ExpandTo, HirFileId, InFile}; use intern::Interned; use la_arena::{Arena, Idx, IdxRange, RawIdx}; -use profile::Count; use rustc_hash::FxHashMap; use smallvec::SmallVec; use span::{AstIdNode, FileAstId, Span}; @@ -94,8 +93,6 @@ impl fmt::Debug for RawVisibilityId { /// The item tree of a source file. #[derive(Debug, Default, Eq, PartialEq)] pub struct ItemTree { - _c: Count, - top_level: SmallVec<[ModItem; 1]>, attrs: FxHashMap, @@ -263,14 +260,6 @@ impl ItemVisibilities { } } -static VIS_PUB: RawVisibility = RawVisibility::Public; -static VIS_PRIV_IMPLICIT: RawVisibility = - RawVisibility::Module(ModPath::from_kind(PathKind::Super(0)), VisibilityExplicitness::Implicit); -static VIS_PRIV_EXPLICIT: RawVisibility = - RawVisibility::Module(ModPath::from_kind(PathKind::Super(0)), VisibilityExplicitness::Explicit); -static VIS_PUB_CRATE: RawVisibility = - RawVisibility::Module(ModPath::from_kind(PathKind::Crate), VisibilityExplicitness::Explicit); - #[derive(Default, Debug, Eq, PartialEq)] struct ItemTreeData { uses: Arena, @@ -562,6 +551,20 @@ impl_index!(fields: Field, variants: Variant, params: Param); impl Index for ItemTree { type Output = RawVisibility; fn index(&self, index: RawVisibilityId) -> &Self::Output { + static VIS_PUB: RawVisibility = RawVisibility::Public; + static VIS_PRIV_IMPLICIT: RawVisibility = RawVisibility::Module( + ModPath::from_kind(PathKind::Super(0)), + VisibilityExplicitness::Implicit, + ); + static VIS_PRIV_EXPLICIT: RawVisibility = RawVisibility::Module( + ModPath::from_kind(PathKind::Super(0)), + VisibilityExplicitness::Explicit, + ); + static VIS_PUB_CRATE: RawVisibility = RawVisibility::Module( + ModPath::from_kind(PathKind::Crate), + VisibilityExplicitness::Explicit, + ); + match index { RawVisibilityId::PRIV_IMPLICIT => &VIS_PRIV_IMPLICIT, RawVisibilityId::PRIV_EXPLICIT => &VIS_PRIV_EXPLICIT, @@ -871,25 +874,19 @@ impl UseTree { prefix: Option, path: &ModPath, ) -> Option<(ModPath, ImportKind)> { - match (prefix, &path.kind) { + match (prefix, path.kind) { (None, _) => Some((path.clone(), ImportKind::Plain)), (Some(mut prefix), PathKind::Plain) => { - for segment in path.segments() { - prefix.push_segment(segment.clone()); - } + prefix.extend(path.segments().iter().cloned()); Some((prefix, ImportKind::Plain)) } - (Some(mut prefix), PathKind::Super(n)) - if *n > 0 && prefix.segments().is_empty() => - { + (Some(mut prefix), PathKind::Super(n)) if n > 0 && prefix.segments().is_empty() => { // `super::super` + `super::rest` match &mut prefix.kind { PathKind::Super(m) => { cov_mark::hit!(concat_super_mod_paths); - *m += *n; - for segment in path.segments() { - prefix.push_segment(segment.clone()); - } + *m += n; + prefix.extend(path.segments().iter().cloned()); Some((prefix, ImportKind::Plain)) } _ => None, @@ -963,10 +960,10 @@ impl ModItem { | ModItem::Mod(_) | ModItem::MacroRules(_) | ModItem::Macro2(_) => None, - ModItem::MacroCall(call) => Some(AssocItem::MacroCall(*call)), - ModItem::Const(konst) => Some(AssocItem::Const(*konst)), - ModItem::TypeAlias(alias) => Some(AssocItem::TypeAlias(*alias)), - ModItem::Function(func) => Some(AssocItem::Function(*func)), + &ModItem::MacroCall(call) => Some(AssocItem::MacroCall(call)), + &ModItem::Const(konst) => Some(AssocItem::Const(konst)), + &ModItem::TypeAlias(alias) => Some(AssocItem::TypeAlias(alias)), + &ModItem::Function(func) => Some(AssocItem::Function(func)), } } diff --git a/crates/hir-def/src/nameres.rs b/crates/hir-def/src/nameres.rs index 270468ad0a62..764617eafb7b 100644 --- a/crates/hir-def/src/nameres.rs +++ b/crates/hir-def/src/nameres.rs @@ -65,7 +65,6 @@ use hir_expand::{ }; use itertools::Itertools; use la_arena::Arena; -use profile::Count; use rustc_hash::{FxHashMap, FxHashSet}; use span::FileAstId; use stdx::format_to; @@ -95,7 +94,6 @@ use crate::{ /// is computed by the `block_def_map` query. #[derive(Debug, PartialEq, Eq)] pub struct DefMap { - _c: Count, /// When this is a block def map, this will hold the block id of the block and module that /// contains this block. block: Option, @@ -154,6 +152,23 @@ struct DefMapCrateData { } impl DefMapCrateData { + fn new(edition: Edition) -> Self { + Self { + extern_prelude: FxHashMap::default(), + exported_derives: FxHashMap::default(), + fn_proc_macro_mapping: FxHashMap::default(), + proc_macro_loading_error: None, + registered_attrs: Vec::new(), + registered_tools: Vec::new(), + unstable_features: FxHashSet::default(), + rustc_coherence_is_core: false, + no_core: false, + no_std: false, + edition, + recursion_limit: None, + } + } + fn shrink_to_fit(&mut self) { let Self { extern_prelude, @@ -305,67 +320,67 @@ impl DefMap { /// The module id of a crate or block root. pub const ROOT: LocalModuleId = LocalModuleId::from_raw(la_arena::RawIdx::from_u32(0)); - pub(crate) fn crate_def_map_query(db: &dyn DefDatabase, krate: CrateId) -> Arc { + pub(crate) fn crate_def_map_query(db: &dyn DefDatabase, crate_id: CrateId) -> Arc { let crate_graph = db.crate_graph(); - let krate_name = crate_graph[krate].display_name.as_deref().unwrap_or_default(); + let krate = &crate_graph[crate_id]; + let name = krate.display_name.as_deref().unwrap_or_default(); + let _p = tracing::span!(tracing::Level::INFO, "crate_def_map_query", ?name).entered(); - let _p = tracing::span!(tracing::Level::INFO, "crate_def_map_query", ?krate_name).entered(); - - let crate_graph = db.crate_graph(); - - let edition = crate_graph[krate].edition; - let origin = ModuleOrigin::CrateRoot { definition: crate_graph[krate].root_file_id }; - let def_map = DefMap::empty(krate, edition, ModuleData::new(origin, Visibility::Public)); - let def_map = collector::collect_defs( - db, - def_map, - TreeId::new(crate_graph[krate].root_file_id.into(), None), + let module_data = ModuleData::new( + ModuleOrigin::CrateRoot { definition: krate.root_file_id }, + Visibility::Public, ); + let def_map = DefMap::empty( + crate_id, + Arc::new(DefMapCrateData::new(krate.edition)), + module_data, + None, + ); + let def_map = + collector::collect_defs(db, def_map, TreeId::new(krate.root_file_id.into(), None)); + Arc::new(def_map) } pub(crate) fn block_def_map_query(db: &dyn DefDatabase, block_id: BlockId) -> Arc { - let block: BlockLoc = block_id.lookup(db); + let BlockLoc { ast_id, module } = block_id.lookup(db); - let parent_map = block.module.def_map(db); - let krate = block.module.krate; - let local_id = LocalModuleId::from_raw(la_arena::RawIdx::from(0)); - // NB: we use `None` as block here, which would be wrong for implicit - // modules declared by blocks with items. At the moment, we don't use - // this visibility for anything outside IDE, so that's probably OK. let visibility = Visibility::Module( - ModuleId { krate, local_id, block: None }, + ModuleId { krate: module.krate, local_id: Self::ROOT, block: module.block }, VisibilityExplicitness::Implicit, ); - let module_data = ModuleData::new( - ModuleOrigin::BlockExpr { block: block.ast_id, id: block_id }, - visibility, + let module_data = + ModuleData::new(ModuleOrigin::BlockExpr { block: ast_id, id: block_id }, visibility); + + let parent_map = module.def_map(db); + let def_map = DefMap::empty( + module.krate, + parent_map.data.clone(), + module_data, + Some(BlockInfo { + block: block_id, + parent: BlockRelativeModuleId { block: module.block, local_id: module.local_id }, + }), ); - let mut def_map = DefMap::empty(krate, parent_map.data.edition, module_data); - def_map.data = parent_map.data.clone(); - def_map.block = Some(BlockInfo { - block: block_id, - parent: BlockRelativeModuleId { - block: block.module.block, - local_id: block.module.local_id, - }, - }); - let def_map = - collector::collect_defs(db, def_map, TreeId::new(block.ast_id.file_id, Some(block_id))); + collector::collect_defs(db, def_map, TreeId::new(ast_id.file_id, Some(block_id))); Arc::new(def_map) } - fn empty(krate: CrateId, edition: Edition, module_data: ModuleData) -> DefMap { + fn empty( + krate: CrateId, + crate_data: Arc, + module_data: ModuleData, + block: Option, + ) -> DefMap { let mut modules: Arena = Arena::default(); let root = modules.alloc(module_data); assert_eq!(root, Self::ROOT); DefMap { - _c: Count::new(), - block: None, + block, modules, krate, prelude: None, @@ -373,23 +388,36 @@ impl DefMap { derive_helpers_in_scope: FxHashMap::default(), diagnostics: Vec::new(), enum_definitions: FxHashMap::default(), - data: Arc::new(DefMapCrateData { - extern_prelude: FxHashMap::default(), - exported_derives: FxHashMap::default(), - fn_proc_macro_mapping: FxHashMap::default(), - proc_macro_loading_error: None, - registered_attrs: Vec::new(), - registered_tools: Vec::new(), - unstable_features: FxHashSet::default(), - rustc_coherence_is_core: false, - no_core: false, - no_std: false, - edition, - recursion_limit: None, - }), + data: crate_data, } } + fn shrink_to_fit(&mut self) { + // Exhaustive match to require handling new fields. + let Self { + macro_use_prelude, + diagnostics, + modules, + derive_helpers_in_scope, + block: _, + krate: _, + prelude: _, + data: _, + enum_definitions, + } = self; + macro_use_prelude.shrink_to_fit(); + diagnostics.shrink_to_fit(); + modules.shrink_to_fit(); + derive_helpers_in_scope.shrink_to_fit(); + enum_definitions.shrink_to_fit(); + for (_, module) in modules.iter_mut() { + module.children.shrink_to_fit(); + module.scope.shrink_to_fit(); + } + } +} + +impl DefMap { pub fn modules_for_file(&self, file_id: FileId) -> impl Iterator + '_ { self.modules .iter() @@ -440,6 +468,105 @@ impl DefMap { self.krate } + pub fn module_id(&self, local_id: LocalModuleId) -> ModuleId { + let block = self.block.map(|b| b.block); + ModuleId { krate: self.krate, local_id, block } + } + + pub fn crate_root(&self) -> CrateRootModuleId { + CrateRootModuleId { krate: self.krate } + } + + /// This is the same as [`Self::crate_root`] for crate def maps, but for block def maps, it + /// returns the root block module. + pub fn root_module_id(&self) -> ModuleId { + self.module_id(Self::ROOT) + } + + /// If this `DefMap` is for a block expression, returns the module containing the block (which + /// might again be a block, or a module inside a block). + pub fn parent(&self) -> Option { + let BlockRelativeModuleId { block, local_id } = self.block?.parent; + Some(ModuleId { krate: self.krate, block, local_id }) + } + + /// Returns the module containing `local_mod`, either the parent `mod`, or the module (or block) containing + /// the block, if `self` corresponds to a block expression. + pub fn containing_module(&self, local_mod: LocalModuleId) -> Option { + match self[local_mod].parent { + Some(parent) => Some(self.module_id(parent)), + None => { + self.block.map( + |BlockInfo { parent: BlockRelativeModuleId { block, local_id }, .. }| { + ModuleId { krate: self.krate, block, local_id } + }, + ) + } + } + } + + /// Get a reference to the def map's diagnostics. + pub fn diagnostics(&self) -> &[DefDiagnostic] { + self.diagnostics.as_slice() + } + + pub fn recursion_limit(&self) -> u32 { + // 128 is the default in rustc + self.data.recursion_limit.unwrap_or(128) + } + + // FIXME: this can use some more human-readable format (ideally, an IR + // even), as this should be a great debugging aid. + pub fn dump(&self, db: &dyn DefDatabase) -> String { + let mut buf = String::new(); + let mut arc; + let mut current_map = self; + while let Some(block) = current_map.block { + go(&mut buf, db, current_map, "block scope", Self::ROOT); + buf.push('\n'); + arc = block.parent.def_map(db, self.krate); + current_map = &arc; + } + go(&mut buf, db, current_map, "crate", Self::ROOT); + return buf; + + fn go( + buf: &mut String, + db: &dyn DefDatabase, + map: &DefMap, + path: &str, + module: LocalModuleId, + ) { + format_to!(buf, "{}\n", path); + + map.modules[module].scope.dump(db.upcast(), buf); + + for (name, child) in + map.modules[module].children.iter().sorted_by(|a, b| Ord::cmp(&a.0, &b.0)) + { + let path = format!("{path}::{}", name.display(db.upcast())); + buf.push('\n'); + go(buf, db, map, &path, *child); + } + } + } + + pub fn dump_block_scopes(&self, db: &dyn DefDatabase) -> String { + let mut buf = String::new(); + let mut arc; + let mut current_map = self; + while let Some(block) = current_map.block { + format_to!(buf, "{:?} in {:?}\n", block.block, block.parent); + arc = block.parent.def_map(db, self.krate); + current_map = &arc; + } + + format_to!(buf, "crate scope\n"); + buf + } +} + +impl DefMap { pub(crate) fn block_id(&self) -> Option { self.block.map(|block| block.block) } @@ -460,21 +587,6 @@ impl DefMap { self.macro_use_prelude.iter().map(|(name, &def)| (name, def)) } - pub fn module_id(&self, local_id: LocalModuleId) -> ModuleId { - let block = self.block.map(|b| b.block); - ModuleId { krate: self.krate, local_id, block } - } - - pub fn crate_root(&self) -> CrateRootModuleId { - CrateRootModuleId { krate: self.krate } - } - - /// This is the same as [`Self::crate_root`] for crate def maps, but for block def maps, it - /// returns the root block module. - pub fn root_module_id(&self) -> ModuleId { - self.module_id(Self::ROOT) - } - pub(crate) fn resolve_path( &self, db: &dyn DefDatabase, @@ -536,114 +648,6 @@ impl DefMap { None } - - /// If this `DefMap` is for a block expression, returns the module containing the block (which - /// might again be a block, or a module inside a block). - pub fn parent(&self) -> Option { - let BlockRelativeModuleId { block, local_id } = self.block?.parent; - Some(ModuleId { krate: self.krate, block, local_id }) - } - - /// Returns the module containing `local_mod`, either the parent `mod`, or the module (or block) containing - /// the block, if `self` corresponds to a block expression. - pub fn containing_module(&self, local_mod: LocalModuleId) -> Option { - match self[local_mod].parent { - Some(parent) => Some(self.module_id(parent)), - None => { - self.block.map( - |BlockInfo { parent: BlockRelativeModuleId { block, local_id }, .. }| { - ModuleId { krate: self.krate, block, local_id } - }, - ) - } - } - } - - // FIXME: this can use some more human-readable format (ideally, an IR - // even), as this should be a great debugging aid. - pub fn dump(&self, db: &dyn DefDatabase) -> String { - let mut buf = String::new(); - let mut arc; - let mut current_map = self; - while let Some(block) = current_map.block { - go(&mut buf, db, current_map, "block scope", Self::ROOT); - buf.push('\n'); - arc = block.parent.def_map(db, self.krate); - current_map = &arc; - } - go(&mut buf, db, current_map, "crate", Self::ROOT); - return buf; - - fn go( - buf: &mut String, - db: &dyn DefDatabase, - map: &DefMap, - path: &str, - module: LocalModuleId, - ) { - format_to!(buf, "{}\n", path); - - map.modules[module].scope.dump(db.upcast(), buf); - - for (name, child) in - map.modules[module].children.iter().sorted_by(|a, b| Ord::cmp(&a.0, &b.0)) - { - let path = format!("{path}::{}", name.display(db.upcast())); - buf.push('\n'); - go(buf, db, map, &path, *child); - } - } - } - - pub fn dump_block_scopes(&self, db: &dyn DefDatabase) -> String { - let mut buf = String::new(); - let mut arc; - let mut current_map = self; - while let Some(block) = current_map.block { - format_to!(buf, "{:?} in {:?}\n", block.block, block.parent); - arc = block.parent.def_map(db, self.krate); - current_map = &arc; - } - - format_to!(buf, "crate scope\n"); - buf - } - - fn shrink_to_fit(&mut self) { - // Exhaustive match to require handling new fields. - let Self { - _c: _, - macro_use_prelude, - diagnostics, - modules, - derive_helpers_in_scope, - block: _, - krate: _, - prelude: _, - data: _, - enum_definitions, - } = self; - - macro_use_prelude.shrink_to_fit(); - diagnostics.shrink_to_fit(); - modules.shrink_to_fit(); - derive_helpers_in_scope.shrink_to_fit(); - enum_definitions.shrink_to_fit(); - for (_, module) in modules.iter_mut() { - module.children.shrink_to_fit(); - module.scope.shrink_to_fit(); - } - } - - /// Get a reference to the def map's diagnostics. - pub fn diagnostics(&self) -> &[DefDiagnostic] { - self.diagnostics.as_slice() - } - - pub fn recursion_limit(&self) -> u32 { - // 128 is the default in rustc - self.data.recursion_limit.unwrap_or(128) - } } impl ModuleData { diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs index 538e735688ba..18aefbf332c8 100644 --- a/crates/hir-def/src/nameres/collector.rs +++ b/crates/hir-def/src/nameres/collector.rs @@ -64,19 +64,18 @@ static FIXED_POINT_LIMIT: Limit = Limit::new(8192); pub(super) fn collect_defs(db: &dyn DefDatabase, def_map: DefMap, tree_id: TreeId) -> DefMap { let crate_graph = db.crate_graph(); - let mut deps = FxHashMap::default(); - // populate external prelude and dependency list let krate = &crate_graph[def_map.krate]; + + // populate external prelude and dependency list + let mut deps = + FxHashMap::with_capacity_and_hasher(krate.dependencies.len(), Default::default()); for dep in &krate.dependencies { tracing::debug!("crate dep {:?} -> {:?}", dep.name, dep.crate_id); deps.insert(dep.as_name(), dep.clone()); } - let cfg_options = &krate.cfg_options; - - let is_proc_macro = krate.is_proc_macro; - let proc_macros = if is_proc_macro { + let proc_macros = if krate.is_proc_macro { match db.proc_macros().get(&def_map.krate) { Some(Ok(proc_macros)) => { Ok(proc_macros @@ -124,11 +123,11 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, def_map: DefMap, tree_id: TreeI indeterminate_imports: Vec::new(), unresolved_macros: Vec::new(), mod_dirs: FxHashMap::default(), - cfg_options, + cfg_options: &krate.cfg_options, proc_macros, from_glob_import: Default::default(), skip_attrs: Default::default(), - is_proc_macro, + is_proc_macro: krate.is_proc_macro, }; if tree_id.is_block() { collector.seed_with_inner(tree_id); @@ -302,71 +301,50 @@ impl DefCollector<'_> { return; } } - let attr_name = match attr.path.as_ident() { - Some(name) => name, - None => continue, - }; + let Some(attr_name) = attr.path.as_ident() else { continue }; - if *attr_name == hir_expand::name![recursion_limit] { - if let Some(limit) = attr.string_value() { - if let Ok(limit) = limit.parse() { - crate_data.recursion_limit = Some(limit); + match () { + () if *attr_name == hir_expand::name![recursion_limit] => { + if let Some(limit) = attr.string_value() { + if let Ok(limit) = limit.parse() { + crate_data.recursion_limit = Some(limit); + } } } - continue; - } - - if *attr_name == hir_expand::name![crate_type] { - if let Some("proc-macro") = attr.string_value().map(SmolStr::as_str) { - self.is_proc_macro = true; + () if *attr_name == hir_expand::name![crate_type] => { + if let Some("proc-macro") = attr.string_value().map(SmolStr::as_str) { + self.is_proc_macro = true; + } } - continue; - } - - if *attr_name == hir_expand::name![no_core] { - crate_data.no_core = true; - continue; - } - - if *attr_name == hir_expand::name![no_std] { - crate_data.no_std = true; - continue; - } - - if attr_name.as_text().as_deref() == Some("rustc_coherence_is_core") { - crate_data.rustc_coherence_is_core = true; - continue; - } - - if *attr_name == hir_expand::name![feature] { - let features = attr - .parse_path_comma_token_tree(self.db.upcast()) - .into_iter() - .flatten() - .filter_map(|(feat, _)| match feat.segments() { - [name] => Some(name.to_smol_str()), - _ => None, - }); - crate_data.unstable_features.extend(features); - } - - let attr_is_register_like = *attr_name == hir_expand::name![register_attr] - || *attr_name == hir_expand::name![register_tool]; - if !attr_is_register_like { - continue; - } - - let registered_name = match attr.single_ident_value() { - Some(ident) => ident.as_name(), - _ => continue, - }; - - if *attr_name == hir_expand::name![register_attr] { - crate_data.registered_attrs.push(registered_name.to_smol_str()); - cov_mark::hit!(register_attr); - } else { - crate_data.registered_tools.push(registered_name.to_smol_str()); - cov_mark::hit!(register_tool); + () if *attr_name == hir_expand::name![no_core] => crate_data.no_core = true, + () if *attr_name == hir_expand::name![no_std] => crate_data.no_std = true, + () if attr_name.as_text().as_deref() == Some("rustc_coherence_is_core") => { + crate_data.rustc_coherence_is_core = true; + } + () if *attr_name == hir_expand::name![feature] => { + let features = attr + .parse_path_comma_token_tree(self.db.upcast()) + .into_iter() + .flatten() + .filter_map(|(feat, _)| match feat.segments() { + [name] => Some(name.to_smol_str()), + _ => None, + }); + crate_data.unstable_features.extend(features); + } + () if *attr_name == hir_expand::name![register_attr] => { + if let Some(ident) = attr.single_ident_value() { + crate_data.registered_attrs.push(ident.text.clone()); + cov_mark::hit!(register_attr); + } + } + () if *attr_name == hir_expand::name![register_tool] => { + if let Some(ident) = attr.single_ident_value() { + crate_data.registered_tools.push(ident.text.clone()); + cov_mark::hit!(register_tool); + } + } + () => (), } } @@ -409,6 +387,7 @@ impl DefCollector<'_> { // main name resolution fixed-point loop. let mut i = 0; 'resolve_attr: loop { + let _p = tracing::span!(tracing::Level::INFO, "resolve_macros loop").entered(); 'resolve_macros: loop { self.db.unwind_if_cancelled(); @@ -466,9 +445,8 @@ impl DefCollector<'_> { // Additionally, while the proc macro entry points must be `pub`, they are not publicly // exported in type/value namespace. This function reduces the visibility of all items // in the crate root that aren't proc macros. - let root = DefMap::ROOT; - let module_id = self.def_map.module_id(root); - let root = &mut self.def_map.modules[root]; + let module_id = self.def_map.module_id(DefMap::ROOT); + let root = &mut self.def_map.modules[DefMap::ROOT]; root.scope.censor_non_proc_macros(module_id); } } @@ -828,12 +806,10 @@ impl DefCollector<'_> { return PartialResolvedImport::Unresolved; } - if let Some(krate) = res.krate { - if krate != self.def_map.krate { - return PartialResolvedImport::Resolved( - def.filter_visibility(|v| matches!(v, Visibility::Public)), - ); - } + if res.from_differing_crate { + return PartialResolvedImport::Resolved( + def.filter_visibility(|v| matches!(v, Visibility::Public)), + ); } // Check whether all namespaces are resolved. @@ -1920,7 +1896,7 @@ impl ModCollector<'_, '_> { } fn collect_module(&mut self, module_id: FileItemTreeId, attrs: &Attrs) { - let path_attr = attrs.by_key("path").string_value(); + let path_attr = attrs.by_key("path").string_value().map(SmolStr::as_str); let is_macro_use = attrs.by_key("macro_use").exists(); let module = &self.item_tree[module_id]; match &module.kind { @@ -1934,25 +1910,26 @@ impl ModCollector<'_, '_> { module_id, ); - if let Some(mod_dir) = self.mod_dir.descend_into_definition(&module.name, path_attr) - { - ModCollector { - def_collector: &mut *self.def_collector, - macro_depth: self.macro_depth, - module_id, - tree_id: self.tree_id, - item_tree: self.item_tree, - mod_dir, - } - .collect_in_top_module(items); - if is_macro_use { - self.import_all_legacy_macros(module_id); - } + let Some(mod_dir) = self.mod_dir.descend_into_definition(&module.name, path_attr) + else { + return; + }; + ModCollector { + def_collector: &mut *self.def_collector, + macro_depth: self.macro_depth, + module_id, + tree_id: self.tree_id, + item_tree: self.item_tree, + mod_dir, + } + .collect_in_top_module(items); + if is_macro_use { + self.import_all_legacy_macros(module_id); } } // out of line module, resolve, parse and recurse ModKind::Outline => { - let ast_id = AstId::new(self.tree_id.file_id(), module.ast_id); + let ast_id = AstId::new(self.file_id(), module.ast_id); let db = self.def_collector.db; match self.mod_dir.resolve_declaration(db, self.file_id(), &module.name, path_attr) { @@ -2445,7 +2422,7 @@ mod tests { use base_db::SourceDatabase; use test_fixture::WithFixture; - use crate::test_db::TestDB; + use crate::{nameres::DefMapCrateData, test_db::TestDB}; use super::*; @@ -2476,8 +2453,12 @@ mod tests { let edition = db.crate_graph()[krate].edition; let module_origin = ModuleOrigin::CrateRoot { definition: file_id }; - let def_map = - DefMap::empty(krate, edition, ModuleData::new(module_origin, Visibility::Public)); + let def_map = DefMap::empty( + krate, + Arc::new(DefMapCrateData::new(edition)), + ModuleData::new(module_origin, Visibility::Public), + None, + ); do_collect_defs(&db, def_map) } diff --git a/crates/hir-def/src/nameres/diagnostics.rs b/crates/hir-def/src/nameres/diagnostics.rs index 161b2c059909..b5a302dbcaf6 100644 --- a/crates/hir-def/src/nameres/diagnostics.rs +++ b/crates/hir-def/src/nameres/diagnostics.rs @@ -1,5 +1,7 @@ //! Diagnostics emitted during DefMap construction. +use std::ops::Not; + use base_db::CrateId; use cfg::{CfgExpr, CfgOptions}; use hir_expand::{attrs::AttrId, ErasedAstId, MacroCallKind}; @@ -16,27 +18,16 @@ use crate::{ #[derive(Debug, PartialEq, Eq)] pub enum DefDiagnosticKind { UnresolvedModule { ast: AstId, candidates: Box<[String]> }, - UnresolvedExternCrate { ast: AstId }, - UnresolvedImport { id: ItemTreeId, index: Idx }, - UnconfiguredCode { ast: ErasedAstId, cfg: CfgExpr, opts: CfgOptions }, - UnresolvedProcMacro { ast: MacroCallKind, krate: CrateId }, - UnresolvedMacroCall { ast: MacroCallKind, path: ModPath }, - MacroError { ast: MacroCallKind, message: String }, - MacroExpansionParseError { ast: MacroCallKind, errors: Box<[SyntaxError]> }, - UnimplementedBuiltinMacro { ast: AstId }, - InvalidDeriveTarget { ast: AstId, id: usize }, - MalformedDerive { ast: AstId, id: usize }, - MacroDefError { ast: AstId, message: String }, } @@ -45,11 +36,12 @@ pub struct DefDiagnostics(Option>>); impl DefDiagnostics { pub fn new(diagnostics: Vec) -> Self { - Self(if diagnostics.is_empty() { - None - } else { - Some(triomphe::Arc::new(diagnostics.into_boxed_slice())) - }) + Self( + diagnostics + .is_empty() + .not() + .then(|| triomphe::Arc::new(diagnostics.into_boxed_slice())), + ) } pub fn iter(&self) -> impl Iterator { diff --git a/crates/hir-def/src/nameres/mod_resolution.rs b/crates/hir-def/src/nameres/mod_resolution.rs index c45200e2de9d..696fb6a961cd 100644 --- a/crates/hir-def/src/nameres/mod_resolution.rs +++ b/crates/hir-def/src/nameres/mod_resolution.rs @@ -3,7 +3,6 @@ use arrayvec::ArrayVec; use base_db::{AnchoredPath, FileId}; use hir_expand::{name::Name, HirFileIdExt, MacroFileIdExt}; use limit::Limit; -use syntax::SmolStr; use crate::{db::DefDatabase, HirFileId}; @@ -29,9 +28,9 @@ impl ModDir { pub(super) fn descend_into_definition( &self, name: &Name, - attr_path: Option<&SmolStr>, + attr_path: Option<&str>, ) -> Option { - let path = match attr_path.map(SmolStr::as_str) { + let path = match attr_path { None => { let mut path = self.dir_path.clone(); path.push(&name.unescaped().to_smol_str()); @@ -63,10 +62,9 @@ impl ModDir { db: &dyn DefDatabase, file_id: HirFileId, name: &Name, - attr_path: Option<&SmolStr>, + attr_path: Option<&str>, ) -> Result<(FileId, bool, ModDir), Box<[String]>> { let name = name.unescaped(); - let orig_file_id = file_id.original_file_respecting_includes(db.upcast()); let mut candidate_files = ArrayVec::<_, 2>::new(); match attr_path { @@ -91,17 +89,19 @@ impl ModDir { } }; + let orig_file_id = file_id.original_file_respecting_includes(db.upcast()); for candidate in candidate_files.iter() { let path = AnchoredPath { anchor: orig_file_id, path: candidate.as_str() }; if let Some(file_id) = db.resolve_path(path) { let is_mod_rs = candidate.ends_with("/mod.rs"); - let (dir_path, root_non_dir_owner) = if is_mod_rs || attr_path.is_some() { - (DirPath::empty(), false) + let root_dir_owner = is_mod_rs || attr_path.is_some(); + let dir_path = if root_dir_owner { + DirPath::empty() } else { - (DirPath::new(format!("{}/", name.display(db.upcast()))), true) + DirPath::new(format!("{}/", name.display(db.upcast()))) }; - if let Some(mod_dir) = self.child(dir_path, root_non_dir_owner) { + if let Some(mod_dir) = self.child(dir_path, !root_dir_owner) { return Ok((file_id, is_mod_rs, mod_dir)); } } diff --git a/crates/hir-def/src/nameres/path_resolution.rs b/crates/hir-def/src/nameres/path_resolution.rs index 1e13f7f8fd01..9e53b0372830 100644 --- a/crates/hir-def/src/nameres/path_resolution.rs +++ b/crates/hir-def/src/nameres/path_resolution.rs @@ -22,7 +22,7 @@ use crate::{ path::{ModPath, PathKind}, per_ns::PerNs, visibility::{RawVisibility, Visibility}, - AdtId, CrateId, LocalModuleId, ModuleDefId, + AdtId, LocalModuleId, ModuleDefId, }; #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -42,21 +42,21 @@ pub(super) struct ResolvePathResult { pub(super) resolved_def: PerNs, pub(super) segment_index: Option, pub(super) reached_fixedpoint: ReachedFixedPoint, - pub(super) krate: Option, + pub(super) from_differing_crate: bool, } impl ResolvePathResult { fn empty(reached_fixedpoint: ReachedFixedPoint) -> ResolvePathResult { - ResolvePathResult::with(PerNs::none(), reached_fixedpoint, None, None) + ResolvePathResult::new(PerNs::none(), reached_fixedpoint, None, false) } - fn with( + fn new( resolved_def: PerNs, reached_fixedpoint: ReachedFixedPoint, segment_index: Option, - krate: Option, + from_differing_crate: bool, ) -> ResolvePathResult { - ResolvePathResult { resolved_def, segment_index, reached_fixedpoint, krate } + ResolvePathResult { resolved_def, segment_index, reached_fixedpoint, from_differing_crate } } } @@ -134,7 +134,19 @@ impl DefMap { // resolving them to. Pass `None` otherwise, e.g. when we're resolving import paths. expected_macro_subns: Option, ) -> ResolvePathResult { - let mut result = ResolvePathResult::empty(ReachedFixedPoint::No); + let mut result = self.resolve_path_fp_with_macro_single( + db, + mode, + original_module, + path, + shadow, + expected_macro_subns, + ); + + if self.block.is_none() { + // If we're in the root `DefMap`, we can resolve the path directly. + return result; + } let mut arc; let mut current_map = self; @@ -153,8 +165,7 @@ impl DefMap { if result.reached_fixedpoint == ReachedFixedPoint::No { result.reached_fixedpoint = new.reached_fixedpoint; } - // FIXME: this doesn't seem right; what if the different namespace resolutions come from different crates? - result.krate = result.krate.or(new.krate); + result.from_differing_crate |= new.from_differing_crate; result.segment_index = match (result.segment_index, new.segment_index) { (Some(idx), None) => Some(idx), (Some(old), Some(new)) => Some(old.max(new)), @@ -333,11 +344,11 @@ impl DefMap { // expectation is discarded. let (def, s) = defp_map.resolve_path(db, module.local_id, &path, shadow, None); - return ResolvePathResult::with( + return ResolvePathResult::new( def, ReachedFixedPoint::Yes, s.map(|s| s + i), - Some(module.krate), + true, ); } @@ -385,11 +396,11 @@ impl DefMap { match res { Some(res) => res, None => { - return ResolvePathResult::with( + return ResolvePathResult::new( PerNs::types(e.into(), vis, imp), ReachedFixedPoint::Yes, Some(i), - Some(self.krate), + false, ) } } @@ -403,11 +414,11 @@ impl DefMap { curr, ); - return ResolvePathResult::with( + return ResolvePathResult::new( PerNs::types(s, vis, imp), ReachedFixedPoint::Yes, Some(i), - Some(self.krate), + false, ); } }; @@ -416,7 +427,7 @@ impl DefMap { .filter_visibility(|vis| vis.is_visible_from_def_map(db, self, original_module)); } - ResolvePathResult::with(curr_per_ns, ReachedFixedPoint::Yes, None, Some(self.krate)) + ResolvePathResult::new(curr_per_ns, ReachedFixedPoint::Yes, None, false) } fn resolve_name_in_module( diff --git a/crates/hir-expand/Cargo.toml b/crates/hir-expand/Cargo.toml index 506a188a211d..4f3080801565 100644 --- a/crates/hir-expand/Cargo.toml +++ b/crates/hir-expand/Cargo.toml @@ -28,7 +28,6 @@ intern.workspace = true base-db.workspace = true cfg.workspace = true syntax.workspace = true -profile.workspace = true tt.workspace = true mbe.workspace = true limit.workspace = true @@ -38,4 +37,4 @@ span.workspace = true expect-test = "1.4.0" [lints] -workspace = true \ No newline at end of file +workspace = true diff --git a/crates/hir-expand/src/builtin_attr_macro.rs b/crates/hir-expand/src/builtin_attr_macro.rs index 903b0d480700..a0102f36aff5 100644 --- a/crates/hir-expand/src/builtin_attr_macro.rs +++ b/crates/hir-expand/src/builtin_attr_macro.rs @@ -4,23 +4,17 @@ use span::{MacroCallId, Span}; use crate::{db::ExpandDatabase, name, tt, ExpandResult, MacroCallKind}; macro_rules! register_builtin { - ($expand_fn:ident: $(($name:ident, $variant:ident) => $expand:ident),* ) => { + ($(($name:ident, $variant:ident) => $expand:ident),* ) => { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum BuiltinAttrExpander { $($variant),* } impl BuiltinAttrExpander { - pub fn $expand_fn( - &self, - db: &dyn ExpandDatabase, - id: MacroCallId, - tt: &tt::Subtree, - ) -> ExpandResult { - let expander = match *self { + pub fn expander(&self) -> fn (&dyn ExpandDatabase, MacroCallId, &tt::Subtree) -> ExpandResult { + match *self { $( BuiltinAttrExpander::$variant => $expand, )* - }; - expander(db, id, tt) + } } fn find_by_name(name: &name::Name) -> Option { @@ -35,6 +29,15 @@ macro_rules! register_builtin { } impl BuiltinAttrExpander { + pub fn expand( + &self, + db: &dyn ExpandDatabase, + id: MacroCallId, + tt: &tt::Subtree, + ) -> ExpandResult { + self.expander()(db, id, tt) + } + pub fn is_derive(self) -> bool { matches!(self, BuiltinAttrExpander::Derive | BuiltinAttrExpander::DeriveConst) } @@ -46,7 +49,7 @@ impl BuiltinAttrExpander { } } -register_builtin! { expand: +register_builtin! { (bench, Bench) => dummy_attr_expand, (cfg, Cfg) => dummy_attr_expand, (cfg_attr, CfgAttr) => dummy_attr_expand, diff --git a/crates/hir-expand/src/builtin_derive_macro.rs b/crates/hir-expand/src/builtin_derive_macro.rs index 279548751434..f36f48baaee1 100644 --- a/crates/hir-expand/src/builtin_derive_macro.rs +++ b/crates/hir-expand/src/builtin_derive_macro.rs @@ -25,20 +25,10 @@ macro_rules! register_builtin { } impl BuiltinDeriveExpander { - pub fn expand( - &self, - db: &dyn ExpandDatabase, - id: MacroCallId, - tt: &ast::Adt, - token_map: SpanMapRef<'_>, - ) -> ExpandResult { - let expander = match *self { + pub fn expander(&self) -> fn(Span, &ast::Adt, SpanMapRef<'_>) -> ExpandResult { + match *self { $( BuiltinDeriveExpander::$trait => $expand, )* - }; - - let span = db.lookup_intern_macro_call(id).call_site; - let span = span_with_def_site_ctxt(db, span, id); - expander(span, tt, token_map) + } } fn find_by_name(name: &name::Name) -> Option { @@ -52,6 +42,20 @@ macro_rules! register_builtin { }; } +impl BuiltinDeriveExpander { + pub fn expand( + &self, + db: &dyn ExpandDatabase, + id: MacroCallId, + tt: &ast::Adt, + token_map: SpanMapRef<'_>, + ) -> ExpandResult { + let span = db.lookup_intern_macro_call(id).call_site; + let span = span_with_def_site_ctxt(db, span, id); + self.expander()(span, tt, token_map) + } +} + register_builtin! { Copy => copy_expand, Clone => clone_expand, diff --git a/crates/hir-expand/src/builtin_fn_macro.rs b/crates/hir-expand/src/builtin_fn_macro.rs index 90cd3af75783..0fd0c25dcce2 100644 --- a/crates/hir-expand/src/builtin_fn_macro.rs +++ b/crates/hir-expand/src/builtin_fn_macro.rs @@ -31,36 +31,18 @@ macro_rules! register_builtin { } impl BuiltinFnLikeExpander { - pub fn expand( - &self, - db: &dyn ExpandDatabase, - id: MacroCallId, - tt: &tt::Subtree, - ) -> ExpandResult { - let expander = match *self { + pub fn expander(&self) -> fn (&dyn ExpandDatabase, MacroCallId, &tt::Subtree, Span) -> ExpandResult { + match *self { $( BuiltinFnLikeExpander::$kind => $expand, )* - }; - - let span = db.lookup_intern_macro_call(id).call_site; - let span = span_with_def_site_ctxt(db, span, id); - expander(db, id, tt, span) + } } } impl EagerExpander { - pub fn expand( - &self, - db: &dyn ExpandDatabase, - id: MacroCallId, - tt: &tt::Subtree, - ) -> ExpandResult { - let expander = match *self { + pub fn expander(&self) -> fn (&dyn ExpandDatabase, MacroCallId, &tt::Subtree, Span) -> ExpandResult { + match *self { $( EagerExpander::$e_kind => $e_expand, )* - }; - - let span = db.lookup_intern_macro_call(id).call_site; - let span = span_with_def_site_ctxt(db, span, id); - expander(db, id, tt, span) + } } } @@ -74,7 +56,31 @@ macro_rules! register_builtin { }; } +impl BuiltinFnLikeExpander { + pub fn expand( + &self, + db: &dyn ExpandDatabase, + id: MacroCallId, + tt: &tt::Subtree, + ) -> ExpandResult { + let span = db.lookup_intern_macro_call(id).call_site; + let span = span_with_def_site_ctxt(db, span, id); + self.expander()(db, id, tt, span) + } +} + impl EagerExpander { + pub fn expand( + &self, + db: &dyn ExpandDatabase, + id: MacroCallId, + tt: &tt::Subtree, + ) -> ExpandResult { + let span = db.lookup_intern_macro_call(id).call_site; + let span = span_with_def_site_ctxt(db, span, id); + self.expander()(db, id, tt, span) + } + pub fn is_include(&self) -> bool { matches!(self, EagerExpander::Include) } diff --git a/crates/hir-expand/src/change.rs b/crates/hir-expand/src/change.rs index c6611438e64d..8b9e5a59df8f 100644 --- a/crates/hir-expand/src/change.rs +++ b/crates/hir-expand/src/change.rs @@ -11,14 +11,14 @@ use triomphe::Arc; use crate::{db::ExpandDatabase, proc_macro::ProcMacros}; #[derive(Debug, Default)] -pub struct Change { +pub struct ChangeWithProcMacros { pub source_change: FileChange, pub proc_macros: Option, pub toolchains: Option>>, pub target_data_layouts: Option>, } -impl Change { +impl ChangeWithProcMacros { pub fn new() -> Self { Self::default() } diff --git a/crates/hir-expand/src/mod_path.rs b/crates/hir-expand/src/mod_path.rs index 0cf1fadec972..ae10ad2f8019 100644 --- a/crates/hir-expand/src/mod_path.rs +++ b/crates/hir-expand/src/mod_path.rs @@ -144,6 +144,12 @@ impl ModPath { } } +impl Extend for ModPath { + fn extend>(&mut self, iter: T) { + self.segments.extend(iter); + } +} + struct Display<'a> { db: &'a dyn ExpandDatabase, path: &'a ModPath, diff --git a/crates/hir-ty/Cargo.toml b/crates/hir-ty/Cargo.toml index 1f8f8744f9eb..41e2f7ad73c3 100644 --- a/crates/hir-ty/Cargo.toml +++ b/crates/hir-ty/Cargo.toml @@ -45,7 +45,6 @@ intern.workspace = true hir-def.workspace = true hir-expand.workspace = true base-db.workspace = true -profile.workspace = true syntax.workspace = true limit.workspace = true diff --git a/crates/hir/Cargo.toml b/crates/hir/Cargo.toml index 7fea8372876e..190722075a20 100644 --- a/crates/hir/Cargo.toml +++ b/crates/hir/Cargo.toml @@ -27,7 +27,6 @@ cfg.workspace = true hir-def.workspace = true hir-expand.workspace = true hir-ty.workspace = true -profile.workspace = true stdx.workspace = true syntax.workspace = true tt.workspace = true diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 5c607030167f..1e16f78ca2d3 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -126,7 +126,7 @@ pub use { }, hir_expand::{ attrs::{Attr, AttrId}, - change::Change, + change::ChangeWithProcMacros, hygiene::{marks_rev, SyntaxContextExt}, name::{known, Name}, proc_macro::ProcMacros, diff --git a/crates/ide-assists/Cargo.toml b/crates/ide-assists/Cargo.toml index 98961a18de25..e1375f9c3ee8 100644 --- a/crates/ide-assists/Cargo.toml +++ b/crates/ide-assists/Cargo.toml @@ -23,7 +23,6 @@ tracing.workspace = true stdx.workspace = true syntax.workspace = true text-edit.workspace = true -profile.workspace = true ide-db.workspace = true hir.workspace = true diff --git a/crates/ide-completion/Cargo.toml b/crates/ide-completion/Cargo.toml index f2a11276ba2b..6a4c70d460f2 100644 --- a/crates/ide-completion/Cargo.toml +++ b/crates/ide-completion/Cargo.toml @@ -23,7 +23,6 @@ smallvec.workspace = true # local deps base-db.workspace = true ide-db.workspace = true -profile.workspace = true stdx.workspace = true syntax.workspace = true text-edit.workspace = true diff --git a/crates/ide-db/src/apply_change.rs b/crates/ide-db/src/apply_change.rs index 2b2df144d6dd..f769f72d462d 100644 --- a/crates/ide-db/src/apply_change.rs +++ b/crates/ide-db/src/apply_change.rs @@ -11,7 +11,7 @@ use profile::{memory_usage, Bytes}; use rustc_hash::FxHashSet; use triomphe::Arc; -use crate::{symbol_index::SymbolsDatabase, Change, RootDatabase}; +use crate::{symbol_index::SymbolsDatabase, ChangeWithProcMacros, RootDatabase}; impl RootDatabase { pub fn request_cancellation(&mut self) { @@ -20,7 +20,7 @@ impl RootDatabase { self.synthetic_write(Durability::LOW); } - pub fn apply_change(&mut self, change: Change) { + pub fn apply_change(&mut self, change: ChangeWithProcMacros) { let _p = tracing::span!(tracing::Level::INFO, "RootDatabase::apply_change").entered(); self.request_cancellation(); tracing::trace!("apply_change {:?}", change); diff --git a/crates/ide-db/src/lib.rs b/crates/ide-db/src/lib.rs index 3e6cb7476bbb..a9f7e58de951 100644 --- a/crates/ide-db/src/lib.rs +++ b/crates/ide-db/src/lib.rs @@ -44,7 +44,7 @@ pub mod syntax_helpers { pub use parser::LexedStr; } -pub use hir::Change; +pub use hir::ChangeWithProcMacros; use std::{fmt, mem::ManuallyDrop}; diff --git a/crates/ide-diagnostics/Cargo.toml b/crates/ide-diagnostics/Cargo.toml index 69768041389a..509c5a152f72 100644 --- a/crates/ide-diagnostics/Cargo.toml +++ b/crates/ide-diagnostics/Cargo.toml @@ -20,7 +20,6 @@ tracing.workspace = true once_cell = "1.17.0" # local deps -profile.workspace = true stdx.workspace = true syntax.workspace = true text-edit.workspace = true diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index a076c7ca9fa4..4eb4acdf183c 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs @@ -61,7 +61,7 @@ use std::ffi::OsStr; use cfg::CfgOptions; use fetch_crates::CrateInfo; -use hir::Change; +use hir::ChangeWithProcMacros; use ide_db::{ base_db::{ salsa::{self, ParallelDatabase}, @@ -184,7 +184,7 @@ impl AnalysisHost { /// Applies changes to the current state of the world. If there are /// outstanding snapshots, they will be canceled. - pub fn apply_change(&mut self, change: Change) { + pub fn apply_change(&mut self, change: ChangeWithProcMacros) { self.db.apply_change(change); } @@ -239,7 +239,7 @@ impl Analysis { file_set.insert(file_id, VfsPath::new_virtual_path("/main.rs".to_owned())); let source_root = SourceRoot::new_local(file_set); - let mut change = Change::new(); + let mut change = ChangeWithProcMacros::new(); change.set_roots(vec![source_root]); let mut crate_graph = CrateGraph::default(); // FIXME: cfg options diff --git a/crates/load-cargo/src/lib.rs b/crates/load-cargo/src/lib.rs index 2b5f515c3ad5..29c1251cceee 100644 --- a/crates/load-cargo/src/lib.rs +++ b/crates/load-cargo/src/lib.rs @@ -11,7 +11,7 @@ use hir_expand::proc_macro::{ }; use ide_db::{ base_db::{CrateGraph, Env, SourceRoot}, - prime_caches, Change, FxHashMap, RootDatabase, + prime_caches, ChangeWithProcMacros, FxHashMap, RootDatabase, }; use itertools::Itertools; use proc_macro_api::{MacroDylib, ProcMacroServer}; @@ -314,7 +314,7 @@ fn load_crate_graph( let lru_cap = std::env::var("RA_LRU_CAP").ok().and_then(|it| it.parse::().ok()); let mut db = RootDatabase::new(lru_cap); - let mut analysis_change = Change::new(); + let mut analysis_change = ChangeWithProcMacros::new(); db.enable_proc_attr_macros(); diff --git a/crates/parser/Cargo.toml b/crates/parser/Cargo.toml index e74b340126c0..1f84e3f3af3f 100644 --- a/crates/parser/Cargo.toml +++ b/crates/parser/Cargo.toml @@ -15,6 +15,7 @@ doctest = false drop_bomb = "0.1.5" ra-ap-rustc_lexer.workspace = true limit.workspace = true +tracing = { workspace = true, optional = true } [dev-dependencies] expect-test = "1.4.0" @@ -23,6 +24,7 @@ stdx.workspace = true sourcegen.workspace = true [features] +default = ["tracing"] in-rust-tree = [] [lints] diff --git a/crates/parser/src/lexed_str.rs b/crates/parser/src/lexed_str.rs index 2da9184693d9..48e4c8a6225c 100644 --- a/crates/parser/src/lexed_str.rs +++ b/crates/parser/src/lexed_str.rs @@ -31,6 +31,7 @@ struct LexError { impl<'a> LexedStr<'a> { pub fn new(text: &'a str) -> LexedStr<'a> { + let _p = tracing::span!(tracing::Level::INFO, "LexedStr::new").entered(); let mut conv = Converter::new(text); if let Some(shebang_len) = rustc_lexer::strip_shebang(text) { conv.res.push(SHEBANG, conv.offset); diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index 3ca285e787e8..86c771c00085 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs @@ -87,6 +87,7 @@ pub enum TopEntryPoint { impl TopEntryPoint { pub fn parse(&self, input: &Input) -> Output { + let _p = tracing::span!(tracing::Level::INFO, "TopEntryPoint::parse", ?self).entered(); let entry_point: fn(&'_ mut parser::Parser<'_>) = match self { TopEntryPoint::SourceFile => grammar::entry::top::source_file, TopEntryPoint::MacroStmts => grammar::entry::top::macro_stmts, diff --git a/crates/parser/src/shortcuts.rs b/crates/parser/src/shortcuts.rs index 57005a6834c9..680a70997d4b 100644 --- a/crates/parser/src/shortcuts.rs +++ b/crates/parser/src/shortcuts.rs @@ -26,6 +26,7 @@ pub enum StrStep<'a> { impl LexedStr<'_> { pub fn to_input(&self) -> crate::Input { + let _p = tracing::span!(tracing::Level::INFO, "LexedStr::to_input").entered(); let mut res = crate::Input::default(); let mut was_joint = false; for i in 0..self.len() { diff --git a/crates/proc-macro-api/Cargo.toml b/crates/proc-macro-api/Cargo.toml index cf01b94c0a2c..e98d70776c95 100644 --- a/crates/proc-macro-api/Cargo.toml +++ b/crates/proc-macro-api/Cargo.toml @@ -32,7 +32,6 @@ indexmap = "2.1.0" paths.workspace = true tt.workspace = true stdx.workspace = true -profile.workspace = true text-size.workspace = true span.workspace = true # Ideally this crate would not depend on salsa things, but we need span information here which wraps diff --git a/crates/profile/src/lib.rs b/crates/profile/src/lib.rs index 363998156063..a3fdb72a6d1d 100644 --- a/crates/profile/src/lib.rs +++ b/crates/profile/src/lib.rs @@ -23,29 +23,6 @@ pub use countme::Count; thread_local!(static IN_SCOPE: RefCell = const { RefCell::new(false) }); -/// Allows to check if the current code is within some dynamic scope, can be -/// useful during debugging to figure out why a function is called. -pub struct Scope { - prev: bool, -} - -impl Scope { - #[must_use] - pub fn enter() -> Scope { - let prev = IN_SCOPE.with(|slot| std::mem::replace(&mut *slot.borrow_mut(), true)); - Scope { prev } - } - pub fn is_active() -> bool { - IN_SCOPE.with(|slot| *slot.borrow()) - } -} - -impl Drop for Scope { - fn drop(&mut self) { - IN_SCOPE.with(|slot| *slot.borrow_mut() = self.prev); - } -} - /// A wrapper around google_cpu_profiler. /// /// Usage: diff --git a/crates/project-model/Cargo.toml b/crates/project-model/Cargo.toml index 3552ed191628..924a4a89e216 100644 --- a/crates/project-model/Cargo.toml +++ b/crates/project-model/Cargo.toml @@ -27,7 +27,6 @@ itertools.workspace = true base-db.workspace = true cfg.workspace = true paths.workspace = true -profile.workspace = true stdx.workspace = true toolchain.workspace = true @@ -35,4 +34,4 @@ toolchain.workspace = true expect-test = "1.4.0" [lints] -workspace = true \ No newline at end of file +workspace = true diff --git a/crates/rust-analyzer/src/cli/rustc_tests.rs b/crates/rust-analyzer/src/cli/rustc_tests.rs index 9276d241affd..7ad87ab97fc6 100644 --- a/crates/rust-analyzer/src/cli/rustc_tests.rs +++ b/crates/rust-analyzer/src/cli/rustc_tests.rs @@ -5,7 +5,7 @@ use std::thread::Builder; use std::time::{Duration, Instant}; use std::{cell::RefCell, fs::read_to_string, panic::AssertUnwindSafe, path::PathBuf}; -use hir::{Change, Crate}; +use hir::{ChangeWithProcMacros, Crate}; use ide::{AnalysisHost, DiagnosticCode, DiagnosticsConfig}; use itertools::Either; use profile::StopWatch; @@ -122,7 +122,7 @@ impl Tester { FxHashMap::default() }; let text = read_to_string(&p).unwrap(); - let mut change = Change::new(); + let mut change = ChangeWithProcMacros::new(); // Ignore unstable tests, since they move too fast and we do not intend to support all of them. let mut ignore_test = text.contains("#![feature"); // Ignore test with extern crates, as this infra don't support them yet. diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index 9bcee6465ab7..8b8d0ebcb989 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs @@ -7,7 +7,7 @@ use std::{collections::hash_map::Entry, time::Instant}; use crossbeam_channel::{unbounded, Receiver, Sender}; use flycheck::FlycheckHandle; -use hir::Change; +use hir::ChangeWithProcMacros; use ide::{Analysis, AnalysisHost, Cancellable, FileId}; use ide_db::base_db::{CrateId, ProcMacroPaths}; use load_cargo::SourceRootConfig; @@ -238,7 +238,7 @@ impl GlobalState { let mut file_changes = FxHashMap::<_, (bool, ChangedFile)>::default(); let (change, modified_rust_files, workspace_structure_change) = { - let mut change = Change::new(); + let mut change = ChangeWithProcMacros::new(); let mut guard = self.vfs.write(); let changed_files = guard.0.take_changes(); if changed_files.is_empty() { diff --git a/crates/rust-analyzer/src/integrated_benchmarks.rs b/crates/rust-analyzer/src/integrated_benchmarks.rs index 9d692175203d..008c63c35a6d 100644 --- a/crates/rust-analyzer/src/integrated_benchmarks.rs +++ b/crates/rust-analyzer/src/integrated_benchmarks.rs @@ -10,7 +10,7 @@ //! in release mode in VS Code. There's however "rust-analyzer: Copy Run Command Line" //! which you can use to paste the command in terminal and add `--release` manually. -use hir::Change; +use hir::ChangeWithProcMacros; use ide::{AnalysisHost, CallableSnippets, CompletionConfig, FilePosition, TextSize}; use ide_db::{ imports::insert_use::{ImportGranularity, InsertUseConfig}, @@ -55,19 +55,19 @@ fn integrated_highlighting_benchmark() { vfs.file_id(&path).unwrap_or_else(|| panic!("can't find virtual file for {path}")) }; + crate::tracing::hprof::init("*>100"); + { let _it = stdx::timeit("initial"); let analysis = host.analysis(); analysis.highlight_as_html(file_id, false).unwrap(); } - crate::tracing::hprof::init("*>100"); - { let _it = stdx::timeit("change"); let mut text = host.analysis().file_text(file_id).unwrap().to_string(); text.push_str("\npub fn _dummy() {}\n"); - let mut change = Change::new(); + let mut change = ChangeWithProcMacros::new(); change.change_file(file_id, Some(Arc::from(text))); host.apply_change(change); } @@ -120,7 +120,7 @@ fn integrated_completion_benchmark() { let completion_offset = patch(&mut text, "db.struct_data(self.id)", "sel;\ndb.struct_data(self.id)") + "sel".len(); - let mut change = Change::new(); + let mut change = ChangeWithProcMacros::new(); change.change_file(file_id, Some(Arc::from(text))); host.apply_change(change); completion_offset @@ -163,7 +163,7 @@ fn integrated_completion_benchmark() { let completion_offset = patch(&mut text, "sel;\ndb.struct_data(self.id)", ";sel;\ndb.struct_data(self.id)") + ";sel".len(); - let mut change = Change::new(); + let mut change = ChangeWithProcMacros::new(); change.change_file(file_id, Some(Arc::from(text))); host.apply_change(change); completion_offset @@ -205,7 +205,7 @@ fn integrated_completion_benchmark() { let completion_offset = patch(&mut text, "sel;\ndb.struct_data(self.id)", "self.;\ndb.struct_data(self.id)") + "self.".len(); - let mut change = Change::new(); + let mut change = ChangeWithProcMacros::new(); change.change_file(file_id, Some(Arc::from(text))); host.apply_change(change); completion_offset diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index f6bc032c0198..95d51baab387 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs @@ -16,7 +16,7 @@ use std::{iter, mem}; use flycheck::{FlycheckConfig, FlycheckHandle}; -use hir::{db::DefDatabase, Change, ProcMacros}; +use hir::{db::DefDatabase, ChangeWithProcMacros, ProcMacros}; use ide::CrateId; use ide_db::{ base_db::{salsa::Durability, CrateGraph, ProcMacroPaths, Version}, @@ -357,7 +357,7 @@ impl GlobalState { } pub(crate) fn set_proc_macros(&mut self, proc_macros: ProcMacros) { - let mut change = Change::new(); + let mut change = ChangeWithProcMacros::new(); change.set_proc_macros(proc_macros); self.analysis_host.apply_change(change); } @@ -548,7 +548,7 @@ impl GlobalState { ws_to_crate_graph(&self.workspaces, self.config.extra_env(), load) }; - let mut change = Change::new(); + let mut change = ChangeWithProcMacros::new(); if self.config.expand_proc_macros() { change.set_proc_macros( crate_graph diff --git a/crates/syntax/Cargo.toml b/crates/syntax/Cargo.toml index a0fd73ee13f5..9a8d73cf7ff4 100644 --- a/crates/syntax/Cargo.toml +++ b/crates/syntax/Cargo.toml @@ -27,7 +27,6 @@ tracing.workspace = true ra-ap-rustc_lexer.workspace = true parser.workspace = true -profile.workspace = true stdx.workspace = true text-edit.workspace = true diff --git a/crates/syntax/src/lib.rs b/crates/syntax/src/lib.rs index b755de86d32c..e8bb9ee938f9 100644 --- a/crates/syntax/src/lib.rs +++ b/crates/syntax/src/lib.rs @@ -168,6 +168,7 @@ pub use crate::ast::SourceFile; impl SourceFile { pub fn parse(text: &str) -> Parse { + let _p = tracing::span!(tracing::Level::INFO, "SourceFile::parse").entered(); let (green, mut errors) = parsing::parse_text(text); let root = SyntaxNode::new_root(green.clone()); diff --git a/crates/syntax/src/parsing.rs b/crates/syntax/src/parsing.rs index 1250b5274c18..d750476f63cb 100644 --- a/crates/syntax/src/parsing.rs +++ b/crates/syntax/src/parsing.rs @@ -10,6 +10,7 @@ use crate::{syntax_node::GreenNode, SyntaxError, SyntaxTreeBuilder}; pub(crate) use crate::parsing::reparsing::incremental_reparse; pub(crate) fn parse_text(text: &str) -> (GreenNode, Vec) { + let _p = tracing::span!(tracing::Level::INFO, "parse_text").entered(); let lexed = parser::LexedStr::new(text); let parser_input = lexed.to_input(); let parser_output = parser::TopEntryPoint::SourceFile.parse(&parser_input); @@ -21,6 +22,7 @@ pub(crate) fn build_tree( lexed: parser::LexedStr<'_>, parser_output: parser::Output, ) -> (GreenNode, Vec, bool) { + let _p = tracing::span!(tracing::Level::INFO, "build_tree").entered(); let mut builder = SyntaxTreeBuilder::default(); let is_eof = lexed.intersperse_trivia(&parser_output, &mut |step| match step { diff --git a/crates/syntax/src/validation.rs b/crates/syntax/src/validation.rs index 5c5b26f525f6..5b3f449eeeb3 100644 --- a/crates/syntax/src/validation.rs +++ b/crates/syntax/src/validation.rs @@ -16,6 +16,7 @@ use crate::{ }; pub(crate) fn validate(root: &SyntaxNode) -> Vec { + let _p = tracing::span!(tracing::Level::INFO, "parser::validate").entered(); // FIXME: // * Add unescape validation of raw string literals and raw byte string literals // * Add validation of doc comments are being attached to nodes diff --git a/crates/test-fixture/src/lib.rs b/crates/test-fixture/src/lib.rs index 58a0e48bc49e..a654366c62a7 100644 --- a/crates/test-fixture/src/lib.rs +++ b/crates/test-fixture/src/lib.rs @@ -7,7 +7,7 @@ use base_db::{ }; use cfg::CfgOptions; use hir_expand::{ - change::Change, + change::ChangeWithProcMacros, db::ExpandDatabase, proc_macro::{ ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroKind, ProcMacros, @@ -103,7 +103,7 @@ impl WithFixture for pub struct ChangeFixture { pub file_position: Option<(FileId, RangeOrOffset)>, pub files: Vec, - pub change: Change, + pub change: ChangeWithProcMacros, } const SOURCE_ROOT_PREFIX: &str = "/"; @@ -320,7 +320,7 @@ impl ChangeFixture { }; roots.push(root); - let mut change = Change { + let mut change = ChangeWithProcMacros { source_change, proc_macros: proc_macros.is_empty().not().then_some(proc_macros), toolchains: Some(iter::repeat(toolchain).take(crate_graph.len()).collect()),