Auto merge of #16747 - Veykril:cleanup, r=Veykril

internal: Clean some stuff up

Just a bunch of small refactorings, mainly from browsing through `hir-def`
This commit is contained in:
bors 2024-03-04 10:30:17 +00:00
commit 99a1b8f7a8
42 changed files with 433 additions and 468 deletions

11
Cargo.lock generated
View file

@ -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",

View file

@ -21,7 +21,6 @@ tracing.workspace = true
# local deps
cfg.workspace = true
profile.workspace = true
stdx.workspace = true
syntax.workspace = true
vfs.workspace = true

View file

@ -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<BlockId>,
_c: Count<Self>,
}
pub type ExprPtr = AstPtr<ast::Expr>;
@ -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(),
}
}
}

View file

@ -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,

View file

@ -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<Self>,
top_level: SmallVec<[ModItem; 1]>,
attrs: FxHashMap<AttrOwner, RawAttrs>,
@ -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<Use>,
@ -562,6 +551,20 @@ impl_index!(fields: Field, variants: Variant, params: Param);
impl Index<RawVisibilityId> 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<ModPath>,
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)),
}
}

View file

@ -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<Self>,
/// When this is a block def map, this will hold the block id of the block and module that
/// contains this block.
block: Option<BlockInfo>,
@ -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<DefMap> {
pub(crate) fn crate_def_map_query(db: &dyn DefDatabase, crate_id: CrateId) -> Arc<DefMap> {
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<DefMap> {
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<DefMapCrateData>,
module_data: ModuleData,
block: Option<BlockInfo>,
) -> DefMap {
let mut modules: Arena<ModuleData> = 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<Item = LocalModuleId> + '_ {
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<ModuleId> {
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<ModuleId> {
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<BlockId> {
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<ModuleId> {
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<ModuleId> {
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 {

View file

@ -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<Mod>, 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)
}

View file

@ -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<ast::Module>, candidates: Box<[String]> },
UnresolvedExternCrate { ast: AstId<ast::ExternCrate> },
UnresolvedImport { id: ItemTreeId<item_tree::Use>, index: Idx<ast::UseTree> },
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<ast::Macro> },
InvalidDeriveTarget { ast: AstId<ast::Item>, id: usize },
MalformedDerive { ast: AstId<ast::Adt>, id: usize },
MacroDefError { ast: AstId<ast::Macro>, message: String },
}
@ -45,11 +36,12 @@ pub struct DefDiagnostics(Option<triomphe::Arc<Box<[DefDiagnostic]>>>);
impl DefDiagnostics {
pub fn new(diagnostics: Vec<DefDiagnostic>) -> 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<Item = &DefDiagnostic> {

View file

@ -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<ModDir> {
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));
}
}

View file

@ -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<usize>,
pub(super) reached_fixedpoint: ReachedFixedPoint,
pub(super) krate: Option<CrateId>,
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<usize>,
krate: Option<CrateId>,
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<MacroSubNs>,
) -> 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(

View file

@ -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
workspace = true

View file

@ -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<tt::Subtree> {
let expander = match *self {
pub fn expander(&self) -> fn (&dyn ExpandDatabase, MacroCallId, &tt::Subtree) -> ExpandResult<tt::Subtree> {
match *self {
$( BuiltinAttrExpander::$variant => $expand, )*
};
expander(db, id, tt)
}
}
fn find_by_name(name: &name::Name) -> Option<Self> {
@ -35,6 +29,15 @@ macro_rules! register_builtin {
}
impl BuiltinAttrExpander {
pub fn expand(
&self,
db: &dyn ExpandDatabase,
id: MacroCallId,
tt: &tt::Subtree,
) -> ExpandResult<tt::Subtree> {
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,

View file

@ -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<tt::Subtree> {
let expander = match *self {
pub fn expander(&self) -> fn(Span, &ast::Adt, SpanMapRef<'_>) -> ExpandResult<tt::Subtree> {
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<Self> {
@ -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<tt::Subtree> {
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,

View file

@ -31,36 +31,18 @@ macro_rules! register_builtin {
}
impl BuiltinFnLikeExpander {
pub fn expand(
&self,
db: &dyn ExpandDatabase,
id: MacroCallId,
tt: &tt::Subtree,
) -> ExpandResult<tt::Subtree> {
let expander = match *self {
pub fn expander(&self) -> fn (&dyn ExpandDatabase, MacroCallId, &tt::Subtree, Span) -> ExpandResult<tt::Subtree> {
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<tt::Subtree> {
let expander = match *self {
pub fn expander(&self) -> fn (&dyn ExpandDatabase, MacroCallId, &tt::Subtree, Span) -> ExpandResult<tt::Subtree> {
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<tt::Subtree> {
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<tt::Subtree> {
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)
}

View file

@ -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<ProcMacros>,
pub toolchains: Option<Vec<Option<Version>>>,
pub target_data_layouts: Option<Vec<TargetLayoutLoadResult>>,
}
impl Change {
impl ChangeWithProcMacros {
pub fn new() -> Self {
Self::default()
}

View file

@ -144,6 +144,12 @@ impl ModPath {
}
}
impl Extend<Name> for ModPath {
fn extend<T: IntoIterator<Item = Name>>(&mut self, iter: T) {
self.segments.extend(iter);
}
}
struct Display<'a> {
db: &'a dyn ExpandDatabase,
path: &'a ModPath,

View file

@ -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

View file

@ -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

View file

@ -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,

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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};

View file

@ -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

View file

@ -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

View file

@ -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::<usize>().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();

View file

@ -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]

View file

@ -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);

View file

@ -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,

View file

@ -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() {

View file

@ -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

View file

@ -23,29 +23,6 @@ pub use countme::Count;
thread_local!(static IN_SCOPE: RefCell<bool> = 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:

View file

@ -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
workspace = true

View file

@ -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.

View file

@ -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() {

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -168,6 +168,7 @@ pub use crate::ast::SourceFile;
impl SourceFile {
pub fn parse(text: &str) -> Parse<SourceFile> {
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());

View file

@ -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<SyntaxError>) {
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<SyntaxError>, 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 {

View file

@ -16,6 +16,7 @@ use crate::{
};
pub(crate) fn validate(root: &SyntaxNode) -> Vec<SyntaxError> {
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

View file

@ -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<DB: ExpandDatabase + SourceDatabaseExt + Default + 'static> WithFixture for
pub struct ChangeFixture {
pub file_position: Option<(FileId, RangeOrOffset)>,
pub files: Vec<FileId>,
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()),