mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-27 20:35:09 +00:00
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:
commit
99a1b8f7a8
42 changed files with 433 additions and 468 deletions
11
Cargo.lock
generated
11
Cargo.lock
generated
|
@ -71,7 +71,6 @@ version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg",
|
"cfg",
|
||||||
"la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"profile",
|
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"salsa",
|
"salsa",
|
||||||
"semver",
|
"semver",
|
||||||
|
@ -501,7 +500,6 @@ dependencies = [
|
||||||
"hir-ty",
|
"hir-ty",
|
||||||
"itertools",
|
"itertools",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"profile",
|
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"span",
|
"span",
|
||||||
|
@ -565,7 +563,6 @@ dependencies = [
|
||||||
"la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"limit",
|
"limit",
|
||||||
"mbe",
|
"mbe",
|
||||||
"profile",
|
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"span",
|
"span",
|
||||||
|
@ -601,7 +598,6 @@ dependencies = [
|
||||||
"nohash-hasher",
|
"nohash-hasher",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"oorandom",
|
"oorandom",
|
||||||
"profile",
|
|
||||||
"project-model",
|
"project-model",
|
||||||
"ra-ap-rustc_abi",
|
"ra-ap-rustc_abi",
|
||||||
"ra-ap-rustc_index 0.35.0",
|
"ra-ap-rustc_index 0.35.0",
|
||||||
|
@ -673,7 +669,6 @@ dependencies = [
|
||||||
"hir",
|
"hir",
|
||||||
"ide-db",
|
"ide-db",
|
||||||
"itertools",
|
"itertools",
|
||||||
"profile",
|
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"sourcegen",
|
"sourcegen",
|
||||||
"stdx",
|
"stdx",
|
||||||
|
@ -695,7 +690,6 @@ dependencies = [
|
||||||
"ide-db",
|
"ide-db",
|
||||||
"itertools",
|
"itertools",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"profile",
|
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"stdx",
|
"stdx",
|
||||||
"syntax",
|
"syntax",
|
||||||
|
@ -753,7 +747,6 @@ dependencies = [
|
||||||
"ide-db",
|
"ide-db",
|
||||||
"itertools",
|
"itertools",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"profile",
|
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sourcegen",
|
"sourcegen",
|
||||||
"stdx",
|
"stdx",
|
||||||
|
@ -1233,6 +1226,7 @@ dependencies = [
|
||||||
"ra-ap-rustc_lexer",
|
"ra-ap-rustc_lexer",
|
||||||
"sourcegen",
|
"sourcegen",
|
||||||
"stdx",
|
"stdx",
|
||||||
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1302,7 +1296,6 @@ dependencies = [
|
||||||
"memmap2",
|
"memmap2",
|
||||||
"object 0.32.0",
|
"object 0.32.0",
|
||||||
"paths",
|
"paths",
|
||||||
"profile",
|
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
@ -1386,7 +1379,6 @@ dependencies = [
|
||||||
"itertools",
|
"itertools",
|
||||||
"la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"paths",
|
"paths",
|
||||||
"profile",
|
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"semver",
|
"semver",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -1925,7 +1917,6 @@ dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"parser",
|
"parser",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"profile",
|
|
||||||
"quote",
|
"quote",
|
||||||
"ra-ap-rustc_lexer",
|
"ra-ap-rustc_lexer",
|
||||||
"rayon",
|
"rayon",
|
||||||
|
|
|
@ -21,7 +21,6 @@ tracing.workspace = true
|
||||||
|
|
||||||
# local deps
|
# local deps
|
||||||
cfg.workspace = true
|
cfg.workspace = true
|
||||||
profile.workspace = true
|
|
||||||
stdx.workspace = true
|
stdx.workspace = true
|
||||||
syntax.workspace = true
|
syntax.workspace = true
|
||||||
vfs.workspace = true
|
vfs.workspace = true
|
||||||
|
|
|
@ -13,7 +13,6 @@ use cfg::{CfgExpr, CfgOptions};
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use hir_expand::{name::Name, HirFileId, InFile};
|
use hir_expand::{name::Name, HirFileId, InFile};
|
||||||
use la_arena::{Arena, ArenaMap};
|
use la_arena::{Arena, ArenaMap};
|
||||||
use profile::Count;
|
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use syntax::{ast, AstPtr, SyntaxNodePtr};
|
use syntax::{ast, AstPtr, SyntaxNodePtr};
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
|
@ -51,7 +50,6 @@ pub struct Body {
|
||||||
pub body_expr: ExprId,
|
pub body_expr: ExprId,
|
||||||
/// Block expressions in this body that may contain inner items.
|
/// Block expressions in this body that may contain inner items.
|
||||||
block_scopes: Vec<BlockId>,
|
block_scopes: Vec<BlockId>,
|
||||||
_c: Count<Self>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type ExprPtr = AstPtr<ast::Expr>;
|
pub type ExprPtr = AstPtr<ast::Expr>;
|
||||||
|
@ -216,7 +214,6 @@ impl Body {
|
||||||
|
|
||||||
fn shrink_to_fit(&mut self) {
|
fn shrink_to_fit(&mut self) {
|
||||||
let Self {
|
let Self {
|
||||||
_c: _,
|
|
||||||
body_expr: _,
|
body_expr: _,
|
||||||
block_scopes,
|
block_scopes,
|
||||||
exprs,
|
exprs,
|
||||||
|
@ -300,7 +297,6 @@ impl Default for Body {
|
||||||
params: Default::default(),
|
params: Default::default(),
|
||||||
block_scopes: Default::default(),
|
block_scopes: Default::default(),
|
||||||
binding_owners: Default::default(),
|
binding_owners: Default::default(),
|
||||||
_c: Default::default(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@ use hir_expand::{
|
||||||
ExpandError, InFile,
|
ExpandError, InFile,
|
||||||
};
|
};
|
||||||
use intern::Interned;
|
use intern::Interned;
|
||||||
use profile::Count;
|
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use span::AstIdMap;
|
use span::AstIdMap;
|
||||||
|
@ -76,7 +75,6 @@ pub(super) fn lower(
|
||||||
params: Vec::new(),
|
params: Vec::new(),
|
||||||
body_expr: dummy_expr_id(),
|
body_expr: dummy_expr_id(),
|
||||||
block_scopes: Vec::new(),
|
block_scopes: Vec::new(),
|
||||||
_c: Count::new(),
|
|
||||||
},
|
},
|
||||||
expander,
|
expander,
|
||||||
current_try_block_label: None,
|
current_try_block_label: None,
|
||||||
|
|
|
@ -50,7 +50,6 @@ use either::Either;
|
||||||
use hir_expand::{attrs::RawAttrs, name::Name, ExpandTo, HirFileId, InFile};
|
use hir_expand::{attrs::RawAttrs, name::Name, ExpandTo, HirFileId, InFile};
|
||||||
use intern::Interned;
|
use intern::Interned;
|
||||||
use la_arena::{Arena, Idx, IdxRange, RawIdx};
|
use la_arena::{Arena, Idx, IdxRange, RawIdx};
|
||||||
use profile::Count;
|
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use span::{AstIdNode, FileAstId, Span};
|
use span::{AstIdNode, FileAstId, Span};
|
||||||
|
@ -94,8 +93,6 @@ impl fmt::Debug for RawVisibilityId {
|
||||||
/// The item tree of a source file.
|
/// The item tree of a source file.
|
||||||
#[derive(Debug, Default, Eq, PartialEq)]
|
#[derive(Debug, Default, Eq, PartialEq)]
|
||||||
pub struct ItemTree {
|
pub struct ItemTree {
|
||||||
_c: Count<Self>,
|
|
||||||
|
|
||||||
top_level: SmallVec<[ModItem; 1]>,
|
top_level: SmallVec<[ModItem; 1]>,
|
||||||
attrs: FxHashMap<AttrOwner, RawAttrs>,
|
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)]
|
#[derive(Default, Debug, Eq, PartialEq)]
|
||||||
struct ItemTreeData {
|
struct ItemTreeData {
|
||||||
uses: Arena<Use>,
|
uses: Arena<Use>,
|
||||||
|
@ -562,6 +551,20 @@ impl_index!(fields: Field, variants: Variant, params: Param);
|
||||||
impl Index<RawVisibilityId> for ItemTree {
|
impl Index<RawVisibilityId> for ItemTree {
|
||||||
type Output = RawVisibility;
|
type Output = RawVisibility;
|
||||||
fn index(&self, index: RawVisibilityId) -> &Self::Output {
|
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 {
|
match index {
|
||||||
RawVisibilityId::PRIV_IMPLICIT => &VIS_PRIV_IMPLICIT,
|
RawVisibilityId::PRIV_IMPLICIT => &VIS_PRIV_IMPLICIT,
|
||||||
RawVisibilityId::PRIV_EXPLICIT => &VIS_PRIV_EXPLICIT,
|
RawVisibilityId::PRIV_EXPLICIT => &VIS_PRIV_EXPLICIT,
|
||||||
|
@ -871,25 +874,19 @@ impl UseTree {
|
||||||
prefix: Option<ModPath>,
|
prefix: Option<ModPath>,
|
||||||
path: &ModPath,
|
path: &ModPath,
|
||||||
) -> Option<(ModPath, ImportKind)> {
|
) -> Option<(ModPath, ImportKind)> {
|
||||||
match (prefix, &path.kind) {
|
match (prefix, path.kind) {
|
||||||
(None, _) => Some((path.clone(), ImportKind::Plain)),
|
(None, _) => Some((path.clone(), ImportKind::Plain)),
|
||||||
(Some(mut prefix), PathKind::Plain) => {
|
(Some(mut prefix), PathKind::Plain) => {
|
||||||
for segment in path.segments() {
|
prefix.extend(path.segments().iter().cloned());
|
||||||
prefix.push_segment(segment.clone());
|
|
||||||
}
|
|
||||||
Some((prefix, ImportKind::Plain))
|
Some((prefix, ImportKind::Plain))
|
||||||
}
|
}
|
||||||
(Some(mut prefix), PathKind::Super(n))
|
(Some(mut prefix), PathKind::Super(n)) if n > 0 && prefix.segments().is_empty() => {
|
||||||
if *n > 0 && prefix.segments().is_empty() =>
|
|
||||||
{
|
|
||||||
// `super::super` + `super::rest`
|
// `super::super` + `super::rest`
|
||||||
match &mut prefix.kind {
|
match &mut prefix.kind {
|
||||||
PathKind::Super(m) => {
|
PathKind::Super(m) => {
|
||||||
cov_mark::hit!(concat_super_mod_paths);
|
cov_mark::hit!(concat_super_mod_paths);
|
||||||
*m += *n;
|
*m += n;
|
||||||
for segment in path.segments() {
|
prefix.extend(path.segments().iter().cloned());
|
||||||
prefix.push_segment(segment.clone());
|
|
||||||
}
|
|
||||||
Some((prefix, ImportKind::Plain))
|
Some((prefix, ImportKind::Plain))
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -963,10 +960,10 @@ impl ModItem {
|
||||||
| ModItem::Mod(_)
|
| ModItem::Mod(_)
|
||||||
| ModItem::MacroRules(_)
|
| ModItem::MacroRules(_)
|
||||||
| ModItem::Macro2(_) => None,
|
| ModItem::Macro2(_) => None,
|
||||||
ModItem::MacroCall(call) => Some(AssocItem::MacroCall(*call)),
|
&ModItem::MacroCall(call) => Some(AssocItem::MacroCall(call)),
|
||||||
ModItem::Const(konst) => Some(AssocItem::Const(*konst)),
|
&ModItem::Const(konst) => Some(AssocItem::Const(konst)),
|
||||||
ModItem::TypeAlias(alias) => Some(AssocItem::TypeAlias(*alias)),
|
&ModItem::TypeAlias(alias) => Some(AssocItem::TypeAlias(alias)),
|
||||||
ModItem::Function(func) => Some(AssocItem::Function(*func)),
|
&ModItem::Function(func) => Some(AssocItem::Function(func)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,6 @@ use hir_expand::{
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use la_arena::Arena;
|
use la_arena::Arena;
|
||||||
use profile::Count;
|
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
use span::FileAstId;
|
use span::FileAstId;
|
||||||
use stdx::format_to;
|
use stdx::format_to;
|
||||||
|
@ -95,7 +94,6 @@ use crate::{
|
||||||
/// is computed by the `block_def_map` query.
|
/// is computed by the `block_def_map` query.
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct DefMap {
|
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
|
/// When this is a block def map, this will hold the block id of the block and module that
|
||||||
/// contains this block.
|
/// contains this block.
|
||||||
block: Option<BlockInfo>,
|
block: Option<BlockInfo>,
|
||||||
|
@ -154,6 +152,23 @@ struct DefMapCrateData {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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) {
|
fn shrink_to_fit(&mut self) {
|
||||||
let Self {
|
let Self {
|
||||||
extern_prelude,
|
extern_prelude,
|
||||||
|
@ -305,67 +320,67 @@ impl DefMap {
|
||||||
/// The module id of a crate or block root.
|
/// The module id of a crate or block root.
|
||||||
pub const ROOT: LocalModuleId = LocalModuleId::from_raw(la_arena::RawIdx::from_u32(0));
|
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 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 module_data = ModuleData::new(
|
||||||
|
ModuleOrigin::CrateRoot { definition: krate.root_file_id },
|
||||||
let crate_graph = db.crate_graph();
|
Visibility::Public,
|
||||||
|
|
||||||
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 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)
|
Arc::new(def_map)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn block_def_map_query(db: &dyn DefDatabase, block_id: BlockId) -> Arc<DefMap> {
|
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(
|
let visibility = Visibility::Module(
|
||||||
ModuleId { krate, local_id, block: None },
|
ModuleId { krate: module.krate, local_id: Self::ROOT, block: module.block },
|
||||||
VisibilityExplicitness::Implicit,
|
VisibilityExplicitness::Implicit,
|
||||||
);
|
);
|
||||||
let module_data = ModuleData::new(
|
let module_data =
|
||||||
ModuleOrigin::BlockExpr { block: block.ast_id, id: block_id },
|
ModuleData::new(ModuleOrigin::BlockExpr { block: ast_id, id: block_id }, visibility);
|
||||||
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 =
|
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)
|
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 mut modules: Arena<ModuleData> = Arena::default();
|
||||||
let root = modules.alloc(module_data);
|
let root = modules.alloc(module_data);
|
||||||
assert_eq!(root, Self::ROOT);
|
assert_eq!(root, Self::ROOT);
|
||||||
|
|
||||||
DefMap {
|
DefMap {
|
||||||
_c: Count::new(),
|
block,
|
||||||
block: None,
|
|
||||||
modules,
|
modules,
|
||||||
krate,
|
krate,
|
||||||
prelude: None,
|
prelude: None,
|
||||||
|
@ -373,23 +388,36 @@ impl DefMap {
|
||||||
derive_helpers_in_scope: FxHashMap::default(),
|
derive_helpers_in_scope: FxHashMap::default(),
|
||||||
diagnostics: Vec::new(),
|
diagnostics: Vec::new(),
|
||||||
enum_definitions: FxHashMap::default(),
|
enum_definitions: FxHashMap::default(),
|
||||||
data: Arc::new(DefMapCrateData {
|
data: crate_data,
|
||||||
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) {
|
||||||
|
// 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> + '_ {
|
pub fn modules_for_file(&self, file_id: FileId) -> impl Iterator<Item = LocalModuleId> + '_ {
|
||||||
self.modules
|
self.modules
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -440,6 +468,105 @@ impl DefMap {
|
||||||
self.krate
|
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> {
|
pub(crate) fn block_id(&self) -> Option<BlockId> {
|
||||||
self.block.map(|block| block.block)
|
self.block.map(|block| block.block)
|
||||||
}
|
}
|
||||||
|
@ -460,21 +587,6 @@ impl DefMap {
|
||||||
self.macro_use_prelude.iter().map(|(name, &def)| (name, def))
|
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(
|
pub(crate) fn resolve_path(
|
||||||
&self,
|
&self,
|
||||||
db: &dyn DefDatabase,
|
db: &dyn DefDatabase,
|
||||||
|
@ -536,114 +648,6 @@ impl DefMap {
|
||||||
|
|
||||||
None
|
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 {
|
impl ModuleData {
|
||||||
|
|
|
@ -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 {
|
pub(super) fn collect_defs(db: &dyn DefDatabase, def_map: DefMap, tree_id: TreeId) -> DefMap {
|
||||||
let crate_graph = db.crate_graph();
|
let crate_graph = db.crate_graph();
|
||||||
|
|
||||||
let mut deps = FxHashMap::default();
|
|
||||||
// populate external prelude and dependency list
|
|
||||||
let krate = &crate_graph[def_map.krate];
|
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 {
|
for dep in &krate.dependencies {
|
||||||
tracing::debug!("crate dep {:?} -> {:?}", dep.name, dep.crate_id);
|
tracing::debug!("crate dep {:?} -> {:?}", dep.name, dep.crate_id);
|
||||||
|
|
||||||
deps.insert(dep.as_name(), dep.clone());
|
deps.insert(dep.as_name(), dep.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
let cfg_options = &krate.cfg_options;
|
let proc_macros = if krate.is_proc_macro {
|
||||||
|
|
||||||
let is_proc_macro = krate.is_proc_macro;
|
|
||||||
let proc_macros = if is_proc_macro {
|
|
||||||
match db.proc_macros().get(&def_map.krate) {
|
match db.proc_macros().get(&def_map.krate) {
|
||||||
Some(Ok(proc_macros)) => {
|
Some(Ok(proc_macros)) => {
|
||||||
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(),
|
indeterminate_imports: Vec::new(),
|
||||||
unresolved_macros: Vec::new(),
|
unresolved_macros: Vec::new(),
|
||||||
mod_dirs: FxHashMap::default(),
|
mod_dirs: FxHashMap::default(),
|
||||||
cfg_options,
|
cfg_options: &krate.cfg_options,
|
||||||
proc_macros,
|
proc_macros,
|
||||||
from_glob_import: Default::default(),
|
from_glob_import: Default::default(),
|
||||||
skip_attrs: Default::default(),
|
skip_attrs: Default::default(),
|
||||||
is_proc_macro,
|
is_proc_macro: krate.is_proc_macro,
|
||||||
};
|
};
|
||||||
if tree_id.is_block() {
|
if tree_id.is_block() {
|
||||||
collector.seed_with_inner(tree_id);
|
collector.seed_with_inner(tree_id);
|
||||||
|
@ -302,71 +301,50 @@ impl DefCollector<'_> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let attr_name = match attr.path.as_ident() {
|
let Some(attr_name) = attr.path.as_ident() else { continue };
|
||||||
Some(name) => name,
|
|
||||||
None => continue,
|
|
||||||
};
|
|
||||||
|
|
||||||
if *attr_name == hir_expand::name![recursion_limit] {
|
match () {
|
||||||
if let Some(limit) = attr.string_value() {
|
() if *attr_name == hir_expand::name![recursion_limit] => {
|
||||||
if let Ok(limit) = limit.parse() {
|
if let Some(limit) = attr.string_value() {
|
||||||
crate_data.recursion_limit = Some(limit);
|
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,
|
||||||
}
|
() 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") => {
|
||||||
if *attr_name == hir_expand::name![no_core] {
|
crate_data.rustc_coherence_is_core = true;
|
||||||
crate_data.no_core = true;
|
}
|
||||||
continue;
|
() if *attr_name == hir_expand::name![feature] => {
|
||||||
}
|
let features = attr
|
||||||
|
.parse_path_comma_token_tree(self.db.upcast())
|
||||||
if *attr_name == hir_expand::name![no_std] {
|
.into_iter()
|
||||||
crate_data.no_std = true;
|
.flatten()
|
||||||
continue;
|
.filter_map(|(feat, _)| match feat.segments() {
|
||||||
}
|
[name] => Some(name.to_smol_str()),
|
||||||
|
_ => None,
|
||||||
if attr_name.as_text().as_deref() == Some("rustc_coherence_is_core") {
|
});
|
||||||
crate_data.rustc_coherence_is_core = true;
|
crate_data.unstable_features.extend(features);
|
||||||
continue;
|
}
|
||||||
}
|
() if *attr_name == hir_expand::name![register_attr] => {
|
||||||
|
if let Some(ident) = attr.single_ident_value() {
|
||||||
if *attr_name == hir_expand::name![feature] {
|
crate_data.registered_attrs.push(ident.text.clone());
|
||||||
let features = attr
|
cov_mark::hit!(register_attr);
|
||||||
.parse_path_comma_token_tree(self.db.upcast())
|
}
|
||||||
.into_iter()
|
}
|
||||||
.flatten()
|
() if *attr_name == hir_expand::name![register_tool] => {
|
||||||
.filter_map(|(feat, _)| match feat.segments() {
|
if let Some(ident) = attr.single_ident_value() {
|
||||||
[name] => Some(name.to_smol_str()),
|
crate_data.registered_tools.push(ident.text.clone());
|
||||||
_ => None,
|
cov_mark::hit!(register_tool);
|
||||||
});
|
}
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -409,6 +387,7 @@ impl DefCollector<'_> {
|
||||||
// main name resolution fixed-point loop.
|
// main name resolution fixed-point loop.
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
'resolve_attr: loop {
|
'resolve_attr: loop {
|
||||||
|
let _p = tracing::span!(tracing::Level::INFO, "resolve_macros loop").entered();
|
||||||
'resolve_macros: loop {
|
'resolve_macros: loop {
|
||||||
self.db.unwind_if_cancelled();
|
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
|
// 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
|
// exported in type/value namespace. This function reduces the visibility of all items
|
||||||
// in the crate root that aren't proc macros.
|
// in the crate root that aren't proc macros.
|
||||||
let root = DefMap::ROOT;
|
let module_id = self.def_map.module_id(DefMap::ROOT);
|
||||||
let module_id = self.def_map.module_id(root);
|
let root = &mut self.def_map.modules[DefMap::ROOT];
|
||||||
let root = &mut self.def_map.modules[root];
|
|
||||||
root.scope.censor_non_proc_macros(module_id);
|
root.scope.censor_non_proc_macros(module_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -828,12 +806,10 @@ impl DefCollector<'_> {
|
||||||
return PartialResolvedImport::Unresolved;
|
return PartialResolvedImport::Unresolved;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(krate) = res.krate {
|
if res.from_differing_crate {
|
||||||
if krate != self.def_map.krate {
|
return PartialResolvedImport::Resolved(
|
||||||
return PartialResolvedImport::Resolved(
|
def.filter_visibility(|v| matches!(v, Visibility::Public)),
|
||||||
def.filter_visibility(|v| matches!(v, Visibility::Public)),
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check whether all namespaces are resolved.
|
// Check whether all namespaces are resolved.
|
||||||
|
@ -1920,7 +1896,7 @@ impl ModCollector<'_, '_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_module(&mut self, module_id: FileItemTreeId<Mod>, attrs: &Attrs) {
|
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 is_macro_use = attrs.by_key("macro_use").exists();
|
||||||
let module = &self.item_tree[module_id];
|
let module = &self.item_tree[module_id];
|
||||||
match &module.kind {
|
match &module.kind {
|
||||||
|
@ -1934,25 +1910,26 @@ impl ModCollector<'_, '_> {
|
||||||
module_id,
|
module_id,
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(mod_dir) = self.mod_dir.descend_into_definition(&module.name, path_attr)
|
let Some(mod_dir) = self.mod_dir.descend_into_definition(&module.name, path_attr)
|
||||||
{
|
else {
|
||||||
ModCollector {
|
return;
|
||||||
def_collector: &mut *self.def_collector,
|
};
|
||||||
macro_depth: self.macro_depth,
|
ModCollector {
|
||||||
module_id,
|
def_collector: &mut *self.def_collector,
|
||||||
tree_id: self.tree_id,
|
macro_depth: self.macro_depth,
|
||||||
item_tree: self.item_tree,
|
module_id,
|
||||||
mod_dir,
|
tree_id: self.tree_id,
|
||||||
}
|
item_tree: self.item_tree,
|
||||||
.collect_in_top_module(items);
|
mod_dir,
|
||||||
if is_macro_use {
|
}
|
||||||
self.import_all_legacy_macros(module_id);
|
.collect_in_top_module(items);
|
||||||
}
|
if is_macro_use {
|
||||||
|
self.import_all_legacy_macros(module_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// out of line module, resolve, parse and recurse
|
// out of line module, resolve, parse and recurse
|
||||||
ModKind::Outline => {
|
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;
|
let db = self.def_collector.db;
|
||||||
match self.mod_dir.resolve_declaration(db, self.file_id(), &module.name, path_attr)
|
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 base_db::SourceDatabase;
|
||||||
use test_fixture::WithFixture;
|
use test_fixture::WithFixture;
|
||||||
|
|
||||||
use crate::test_db::TestDB;
|
use crate::{nameres::DefMapCrateData, test_db::TestDB};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
@ -2476,8 +2453,12 @@ mod tests {
|
||||||
|
|
||||||
let edition = db.crate_graph()[krate].edition;
|
let edition = db.crate_graph()[krate].edition;
|
||||||
let module_origin = ModuleOrigin::CrateRoot { definition: file_id };
|
let module_origin = ModuleOrigin::CrateRoot { definition: file_id };
|
||||||
let def_map =
|
let def_map = DefMap::empty(
|
||||||
DefMap::empty(krate, edition, ModuleData::new(module_origin, Visibility::Public));
|
krate,
|
||||||
|
Arc::new(DefMapCrateData::new(edition)),
|
||||||
|
ModuleData::new(module_origin, Visibility::Public),
|
||||||
|
None,
|
||||||
|
);
|
||||||
do_collect_defs(&db, def_map)
|
do_collect_defs(&db, def_map)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
//! Diagnostics emitted during DefMap construction.
|
//! Diagnostics emitted during DefMap construction.
|
||||||
|
|
||||||
|
use std::ops::Not;
|
||||||
|
|
||||||
use base_db::CrateId;
|
use base_db::CrateId;
|
||||||
use cfg::{CfgExpr, CfgOptions};
|
use cfg::{CfgExpr, CfgOptions};
|
||||||
use hir_expand::{attrs::AttrId, ErasedAstId, MacroCallKind};
|
use hir_expand::{attrs::AttrId, ErasedAstId, MacroCallKind};
|
||||||
|
@ -16,27 +18,16 @@ use crate::{
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum DefDiagnosticKind {
|
pub enum DefDiagnosticKind {
|
||||||
UnresolvedModule { ast: AstId<ast::Module>, candidates: Box<[String]> },
|
UnresolvedModule { ast: AstId<ast::Module>, candidates: Box<[String]> },
|
||||||
|
|
||||||
UnresolvedExternCrate { ast: AstId<ast::ExternCrate> },
|
UnresolvedExternCrate { ast: AstId<ast::ExternCrate> },
|
||||||
|
|
||||||
UnresolvedImport { id: ItemTreeId<item_tree::Use>, index: Idx<ast::UseTree> },
|
UnresolvedImport { id: ItemTreeId<item_tree::Use>, index: Idx<ast::UseTree> },
|
||||||
|
|
||||||
UnconfiguredCode { ast: ErasedAstId, cfg: CfgExpr, opts: CfgOptions },
|
UnconfiguredCode { ast: ErasedAstId, cfg: CfgExpr, opts: CfgOptions },
|
||||||
|
|
||||||
UnresolvedProcMacro { ast: MacroCallKind, krate: CrateId },
|
UnresolvedProcMacro { ast: MacroCallKind, krate: CrateId },
|
||||||
|
|
||||||
UnresolvedMacroCall { ast: MacroCallKind, path: ModPath },
|
UnresolvedMacroCall { ast: MacroCallKind, path: ModPath },
|
||||||
|
|
||||||
MacroError { ast: MacroCallKind, message: String },
|
MacroError { ast: MacroCallKind, message: String },
|
||||||
|
|
||||||
MacroExpansionParseError { ast: MacroCallKind, errors: Box<[SyntaxError]> },
|
MacroExpansionParseError { ast: MacroCallKind, errors: Box<[SyntaxError]> },
|
||||||
|
|
||||||
UnimplementedBuiltinMacro { ast: AstId<ast::Macro> },
|
UnimplementedBuiltinMacro { ast: AstId<ast::Macro> },
|
||||||
|
|
||||||
InvalidDeriveTarget { ast: AstId<ast::Item>, id: usize },
|
InvalidDeriveTarget { ast: AstId<ast::Item>, id: usize },
|
||||||
|
|
||||||
MalformedDerive { ast: AstId<ast::Adt>, id: usize },
|
MalformedDerive { ast: AstId<ast::Adt>, id: usize },
|
||||||
|
|
||||||
MacroDefError { ast: AstId<ast::Macro>, message: String },
|
MacroDefError { ast: AstId<ast::Macro>, message: String },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,11 +36,12 @@ pub struct DefDiagnostics(Option<triomphe::Arc<Box<[DefDiagnostic]>>>);
|
||||||
|
|
||||||
impl DefDiagnostics {
|
impl DefDiagnostics {
|
||||||
pub fn new(diagnostics: Vec<DefDiagnostic>) -> Self {
|
pub fn new(diagnostics: Vec<DefDiagnostic>) -> Self {
|
||||||
Self(if diagnostics.is_empty() {
|
Self(
|
||||||
None
|
diagnostics
|
||||||
} else {
|
.is_empty()
|
||||||
Some(triomphe::Arc::new(diagnostics.into_boxed_slice()))
|
.not()
|
||||||
})
|
.then(|| triomphe::Arc::new(diagnostics.into_boxed_slice())),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter(&self) -> impl Iterator<Item = &DefDiagnostic> {
|
pub fn iter(&self) -> impl Iterator<Item = &DefDiagnostic> {
|
||||||
|
|
|
@ -3,7 +3,6 @@ use arrayvec::ArrayVec;
|
||||||
use base_db::{AnchoredPath, FileId};
|
use base_db::{AnchoredPath, FileId};
|
||||||
use hir_expand::{name::Name, HirFileIdExt, MacroFileIdExt};
|
use hir_expand::{name::Name, HirFileIdExt, MacroFileIdExt};
|
||||||
use limit::Limit;
|
use limit::Limit;
|
||||||
use syntax::SmolStr;
|
|
||||||
|
|
||||||
use crate::{db::DefDatabase, HirFileId};
|
use crate::{db::DefDatabase, HirFileId};
|
||||||
|
|
||||||
|
@ -29,9 +28,9 @@ impl ModDir {
|
||||||
pub(super) fn descend_into_definition(
|
pub(super) fn descend_into_definition(
|
||||||
&self,
|
&self,
|
||||||
name: &Name,
|
name: &Name,
|
||||||
attr_path: Option<&SmolStr>,
|
attr_path: Option<&str>,
|
||||||
) -> Option<ModDir> {
|
) -> Option<ModDir> {
|
||||||
let path = match attr_path.map(SmolStr::as_str) {
|
let path = match attr_path {
|
||||||
None => {
|
None => {
|
||||||
let mut path = self.dir_path.clone();
|
let mut path = self.dir_path.clone();
|
||||||
path.push(&name.unescaped().to_smol_str());
|
path.push(&name.unescaped().to_smol_str());
|
||||||
|
@ -63,10 +62,9 @@ impl ModDir {
|
||||||
db: &dyn DefDatabase,
|
db: &dyn DefDatabase,
|
||||||
file_id: HirFileId,
|
file_id: HirFileId,
|
||||||
name: &Name,
|
name: &Name,
|
||||||
attr_path: Option<&SmolStr>,
|
attr_path: Option<&str>,
|
||||||
) -> Result<(FileId, bool, ModDir), Box<[String]>> {
|
) -> Result<(FileId, bool, ModDir), Box<[String]>> {
|
||||||
let name = name.unescaped();
|
let name = name.unescaped();
|
||||||
let orig_file_id = file_id.original_file_respecting_includes(db.upcast());
|
|
||||||
|
|
||||||
let mut candidate_files = ArrayVec::<_, 2>::new();
|
let mut candidate_files = ArrayVec::<_, 2>::new();
|
||||||
match attr_path {
|
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() {
|
for candidate in candidate_files.iter() {
|
||||||
let path = AnchoredPath { anchor: orig_file_id, path: candidate.as_str() };
|
let path = AnchoredPath { anchor: orig_file_id, path: candidate.as_str() };
|
||||||
if let Some(file_id) = db.resolve_path(path) {
|
if let Some(file_id) = db.resolve_path(path) {
|
||||||
let is_mod_rs = candidate.ends_with("/mod.rs");
|
let is_mod_rs = candidate.ends_with("/mod.rs");
|
||||||
|
|
||||||
let (dir_path, root_non_dir_owner) = if is_mod_rs || attr_path.is_some() {
|
let root_dir_owner = is_mod_rs || attr_path.is_some();
|
||||||
(DirPath::empty(), false)
|
let dir_path = if root_dir_owner {
|
||||||
|
DirPath::empty()
|
||||||
} else {
|
} 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));
|
return Ok((file_id, is_mod_rs, mod_dir));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ use crate::{
|
||||||
path::{ModPath, PathKind},
|
path::{ModPath, PathKind},
|
||||||
per_ns::PerNs,
|
per_ns::PerNs,
|
||||||
visibility::{RawVisibility, Visibility},
|
visibility::{RawVisibility, Visibility},
|
||||||
AdtId, CrateId, LocalModuleId, ModuleDefId,
|
AdtId, LocalModuleId, ModuleDefId,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
@ -42,21 +42,21 @@ pub(super) struct ResolvePathResult {
|
||||||
pub(super) resolved_def: PerNs,
|
pub(super) resolved_def: PerNs,
|
||||||
pub(super) segment_index: Option<usize>,
|
pub(super) segment_index: Option<usize>,
|
||||||
pub(super) reached_fixedpoint: ReachedFixedPoint,
|
pub(super) reached_fixedpoint: ReachedFixedPoint,
|
||||||
pub(super) krate: Option<CrateId>,
|
pub(super) from_differing_crate: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ResolvePathResult {
|
impl ResolvePathResult {
|
||||||
fn empty(reached_fixedpoint: ReachedFixedPoint) -> 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,
|
resolved_def: PerNs,
|
||||||
reached_fixedpoint: ReachedFixedPoint,
|
reached_fixedpoint: ReachedFixedPoint,
|
||||||
segment_index: Option<usize>,
|
segment_index: Option<usize>,
|
||||||
krate: Option<CrateId>,
|
from_differing_crate: bool,
|
||||||
) -> ResolvePathResult {
|
) -> 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.
|
// resolving them to. Pass `None` otherwise, e.g. when we're resolving import paths.
|
||||||
expected_macro_subns: Option<MacroSubNs>,
|
expected_macro_subns: Option<MacroSubNs>,
|
||||||
) -> ResolvePathResult {
|
) -> 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 arc;
|
||||||
let mut current_map = self;
|
let mut current_map = self;
|
||||||
|
@ -153,8 +165,7 @@ impl DefMap {
|
||||||
if result.reached_fixedpoint == ReachedFixedPoint::No {
|
if result.reached_fixedpoint == ReachedFixedPoint::No {
|
||||||
result.reached_fixedpoint = new.reached_fixedpoint;
|
result.reached_fixedpoint = new.reached_fixedpoint;
|
||||||
}
|
}
|
||||||
// FIXME: this doesn't seem right; what if the different namespace resolutions come from different crates?
|
result.from_differing_crate |= new.from_differing_crate;
|
||||||
result.krate = result.krate.or(new.krate);
|
|
||||||
result.segment_index = match (result.segment_index, new.segment_index) {
|
result.segment_index = match (result.segment_index, new.segment_index) {
|
||||||
(Some(idx), None) => Some(idx),
|
(Some(idx), None) => Some(idx),
|
||||||
(Some(old), Some(new)) => Some(old.max(new)),
|
(Some(old), Some(new)) => Some(old.max(new)),
|
||||||
|
@ -333,11 +344,11 @@ impl DefMap {
|
||||||
// expectation is discarded.
|
// expectation is discarded.
|
||||||
let (def, s) =
|
let (def, s) =
|
||||||
defp_map.resolve_path(db, module.local_id, &path, shadow, None);
|
defp_map.resolve_path(db, module.local_id, &path, shadow, None);
|
||||||
return ResolvePathResult::with(
|
return ResolvePathResult::new(
|
||||||
def,
|
def,
|
||||||
ReachedFixedPoint::Yes,
|
ReachedFixedPoint::Yes,
|
||||||
s.map(|s| s + i),
|
s.map(|s| s + i),
|
||||||
Some(module.krate),
|
true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,11 +396,11 @@ impl DefMap {
|
||||||
match res {
|
match res {
|
||||||
Some(res) => res,
|
Some(res) => res,
|
||||||
None => {
|
None => {
|
||||||
return ResolvePathResult::with(
|
return ResolvePathResult::new(
|
||||||
PerNs::types(e.into(), vis, imp),
|
PerNs::types(e.into(), vis, imp),
|
||||||
ReachedFixedPoint::Yes,
|
ReachedFixedPoint::Yes,
|
||||||
Some(i),
|
Some(i),
|
||||||
Some(self.krate),
|
false,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -403,11 +414,11 @@ impl DefMap {
|
||||||
curr,
|
curr,
|
||||||
);
|
);
|
||||||
|
|
||||||
return ResolvePathResult::with(
|
return ResolvePathResult::new(
|
||||||
PerNs::types(s, vis, imp),
|
PerNs::types(s, vis, imp),
|
||||||
ReachedFixedPoint::Yes,
|
ReachedFixedPoint::Yes,
|
||||||
Some(i),
|
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));
|
.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(
|
fn resolve_name_in_module(
|
||||||
|
|
|
@ -28,7 +28,6 @@ intern.workspace = true
|
||||||
base-db.workspace = true
|
base-db.workspace = true
|
||||||
cfg.workspace = true
|
cfg.workspace = true
|
||||||
syntax.workspace = true
|
syntax.workspace = true
|
||||||
profile.workspace = true
|
|
||||||
tt.workspace = true
|
tt.workspace = true
|
||||||
mbe.workspace = true
|
mbe.workspace = true
|
||||||
limit.workspace = true
|
limit.workspace = true
|
||||||
|
|
|
@ -4,23 +4,17 @@ use span::{MacroCallId, Span};
|
||||||
use crate::{db::ExpandDatabase, name, tt, ExpandResult, MacroCallKind};
|
use crate::{db::ExpandDatabase, name, tt, ExpandResult, MacroCallKind};
|
||||||
|
|
||||||
macro_rules! register_builtin {
|
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)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub enum BuiltinAttrExpander {
|
pub enum BuiltinAttrExpander {
|
||||||
$($variant),*
|
$($variant),*
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BuiltinAttrExpander {
|
impl BuiltinAttrExpander {
|
||||||
pub fn $expand_fn(
|
pub fn expander(&self) -> fn (&dyn ExpandDatabase, MacroCallId, &tt::Subtree) -> ExpandResult<tt::Subtree> {
|
||||||
&self,
|
match *self {
|
||||||
db: &dyn ExpandDatabase,
|
|
||||||
id: MacroCallId,
|
|
||||||
tt: &tt::Subtree,
|
|
||||||
) -> ExpandResult<tt::Subtree> {
|
|
||||||
let expander = match *self {
|
|
||||||
$( BuiltinAttrExpander::$variant => $expand, )*
|
$( BuiltinAttrExpander::$variant => $expand, )*
|
||||||
};
|
}
|
||||||
expander(db, id, tt)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_by_name(name: &name::Name) -> Option<Self> {
|
fn find_by_name(name: &name::Name) -> Option<Self> {
|
||||||
|
@ -35,6 +29,15 @@ macro_rules! register_builtin {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BuiltinAttrExpander {
|
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 {
|
pub fn is_derive(self) -> bool {
|
||||||
matches!(self, BuiltinAttrExpander::Derive | BuiltinAttrExpander::DeriveConst)
|
matches!(self, BuiltinAttrExpander::Derive | BuiltinAttrExpander::DeriveConst)
|
||||||
}
|
}
|
||||||
|
@ -46,7 +49,7 @@ impl BuiltinAttrExpander {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
register_builtin! { expand:
|
register_builtin! {
|
||||||
(bench, Bench) => dummy_attr_expand,
|
(bench, Bench) => dummy_attr_expand,
|
||||||
(cfg, Cfg) => dummy_attr_expand,
|
(cfg, Cfg) => dummy_attr_expand,
|
||||||
(cfg_attr, CfgAttr) => dummy_attr_expand,
|
(cfg_attr, CfgAttr) => dummy_attr_expand,
|
||||||
|
|
|
@ -25,20 +25,10 @@ macro_rules! register_builtin {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BuiltinDeriveExpander {
|
impl BuiltinDeriveExpander {
|
||||||
pub fn expand(
|
pub fn expander(&self) -> fn(Span, &ast::Adt, SpanMapRef<'_>) -> ExpandResult<tt::Subtree> {
|
||||||
&self,
|
match *self {
|
||||||
db: &dyn ExpandDatabase,
|
|
||||||
id: MacroCallId,
|
|
||||||
tt: &ast::Adt,
|
|
||||||
token_map: SpanMapRef<'_>,
|
|
||||||
) -> ExpandResult<tt::Subtree> {
|
|
||||||
let expander = match *self {
|
|
||||||
$( BuiltinDeriveExpander::$trait => $expand, )*
|
$( 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> {
|
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! {
|
register_builtin! {
|
||||||
Copy => copy_expand,
|
Copy => copy_expand,
|
||||||
Clone => clone_expand,
|
Clone => clone_expand,
|
||||||
|
|
|
@ -31,36 +31,18 @@ macro_rules! register_builtin {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BuiltinFnLikeExpander {
|
impl BuiltinFnLikeExpander {
|
||||||
pub fn expand(
|
pub fn expander(&self) -> fn (&dyn ExpandDatabase, MacroCallId, &tt::Subtree, Span) -> ExpandResult<tt::Subtree> {
|
||||||
&self,
|
match *self {
|
||||||
db: &dyn ExpandDatabase,
|
|
||||||
id: MacroCallId,
|
|
||||||
tt: &tt::Subtree,
|
|
||||||
) -> ExpandResult<tt::Subtree> {
|
|
||||||
let expander = match *self {
|
|
||||||
$( BuiltinFnLikeExpander::$kind => $expand, )*
|
$( 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 {
|
impl EagerExpander {
|
||||||
pub fn expand(
|
pub fn expander(&self) -> fn (&dyn ExpandDatabase, MacroCallId, &tt::Subtree, Span) -> ExpandResult<tt::Subtree> {
|
||||||
&self,
|
match *self {
|
||||||
db: &dyn ExpandDatabase,
|
|
||||||
id: MacroCallId,
|
|
||||||
tt: &tt::Subtree,
|
|
||||||
) -> ExpandResult<tt::Subtree> {
|
|
||||||
let expander = match *self {
|
|
||||||
$( EagerExpander::$e_kind => $e_expand, )*
|
$( 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 {
|
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 {
|
pub fn is_include(&self) -> bool {
|
||||||
matches!(self, EagerExpander::Include)
|
matches!(self, EagerExpander::Include)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,14 +11,14 @@ use triomphe::Arc;
|
||||||
use crate::{db::ExpandDatabase, proc_macro::ProcMacros};
|
use crate::{db::ExpandDatabase, proc_macro::ProcMacros};
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Change {
|
pub struct ChangeWithProcMacros {
|
||||||
pub source_change: FileChange,
|
pub source_change: FileChange,
|
||||||
pub proc_macros: Option<ProcMacros>,
|
pub proc_macros: Option<ProcMacros>,
|
||||||
pub toolchains: Option<Vec<Option<Version>>>,
|
pub toolchains: Option<Vec<Option<Version>>>,
|
||||||
pub target_data_layouts: Option<Vec<TargetLayoutLoadResult>>,
|
pub target_data_layouts: Option<Vec<TargetLayoutLoadResult>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Change {
|
impl ChangeWithProcMacros {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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> {
|
struct Display<'a> {
|
||||||
db: &'a dyn ExpandDatabase,
|
db: &'a dyn ExpandDatabase,
|
||||||
path: &'a ModPath,
|
path: &'a ModPath,
|
||||||
|
|
|
@ -45,7 +45,6 @@ intern.workspace = true
|
||||||
hir-def.workspace = true
|
hir-def.workspace = true
|
||||||
hir-expand.workspace = true
|
hir-expand.workspace = true
|
||||||
base-db.workspace = true
|
base-db.workspace = true
|
||||||
profile.workspace = true
|
|
||||||
syntax.workspace = true
|
syntax.workspace = true
|
||||||
limit.workspace = true
|
limit.workspace = true
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,6 @@ cfg.workspace = true
|
||||||
hir-def.workspace = true
|
hir-def.workspace = true
|
||||||
hir-expand.workspace = true
|
hir-expand.workspace = true
|
||||||
hir-ty.workspace = true
|
hir-ty.workspace = true
|
||||||
profile.workspace = true
|
|
||||||
stdx.workspace = true
|
stdx.workspace = true
|
||||||
syntax.workspace = true
|
syntax.workspace = true
|
||||||
tt.workspace = true
|
tt.workspace = true
|
||||||
|
|
|
@ -126,7 +126,7 @@ pub use {
|
||||||
},
|
},
|
||||||
hir_expand::{
|
hir_expand::{
|
||||||
attrs::{Attr, AttrId},
|
attrs::{Attr, AttrId},
|
||||||
change::Change,
|
change::ChangeWithProcMacros,
|
||||||
hygiene::{marks_rev, SyntaxContextExt},
|
hygiene::{marks_rev, SyntaxContextExt},
|
||||||
name::{known, Name},
|
name::{known, Name},
|
||||||
proc_macro::ProcMacros,
|
proc_macro::ProcMacros,
|
||||||
|
|
|
@ -23,7 +23,6 @@ tracing.workspace = true
|
||||||
stdx.workspace = true
|
stdx.workspace = true
|
||||||
syntax.workspace = true
|
syntax.workspace = true
|
||||||
text-edit.workspace = true
|
text-edit.workspace = true
|
||||||
profile.workspace = true
|
|
||||||
ide-db.workspace = true
|
ide-db.workspace = true
|
||||||
hir.workspace = true
|
hir.workspace = true
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,6 @@ smallvec.workspace = true
|
||||||
# local deps
|
# local deps
|
||||||
base-db.workspace = true
|
base-db.workspace = true
|
||||||
ide-db.workspace = true
|
ide-db.workspace = true
|
||||||
profile.workspace = true
|
|
||||||
stdx.workspace = true
|
stdx.workspace = true
|
||||||
syntax.workspace = true
|
syntax.workspace = true
|
||||||
text-edit.workspace = true
|
text-edit.workspace = true
|
||||||
|
|
|
@ -11,7 +11,7 @@ use profile::{memory_usage, Bytes};
|
||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::FxHashSet;
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
|
|
||||||
use crate::{symbol_index::SymbolsDatabase, Change, RootDatabase};
|
use crate::{symbol_index::SymbolsDatabase, ChangeWithProcMacros, RootDatabase};
|
||||||
|
|
||||||
impl RootDatabase {
|
impl RootDatabase {
|
||||||
pub fn request_cancellation(&mut self) {
|
pub fn request_cancellation(&mut self) {
|
||||||
|
@ -20,7 +20,7 @@ impl RootDatabase {
|
||||||
self.synthetic_write(Durability::LOW);
|
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();
|
let _p = tracing::span!(tracing::Level::INFO, "RootDatabase::apply_change").entered();
|
||||||
self.request_cancellation();
|
self.request_cancellation();
|
||||||
tracing::trace!("apply_change {:?}", change);
|
tracing::trace!("apply_change {:?}", change);
|
||||||
|
|
|
@ -44,7 +44,7 @@ pub mod syntax_helpers {
|
||||||
pub use parser::LexedStr;
|
pub use parser::LexedStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub use hir::Change;
|
pub use hir::ChangeWithProcMacros;
|
||||||
|
|
||||||
use std::{fmt, mem::ManuallyDrop};
|
use std::{fmt, mem::ManuallyDrop};
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@ tracing.workspace = true
|
||||||
once_cell = "1.17.0"
|
once_cell = "1.17.0"
|
||||||
|
|
||||||
# local deps
|
# local deps
|
||||||
profile.workspace = true
|
|
||||||
stdx.workspace = true
|
stdx.workspace = true
|
||||||
syntax.workspace = true
|
syntax.workspace = true
|
||||||
text-edit.workspace = true
|
text-edit.workspace = true
|
||||||
|
|
|
@ -61,7 +61,7 @@ use std::ffi::OsStr;
|
||||||
|
|
||||||
use cfg::CfgOptions;
|
use cfg::CfgOptions;
|
||||||
use fetch_crates::CrateInfo;
|
use fetch_crates::CrateInfo;
|
||||||
use hir::Change;
|
use hir::ChangeWithProcMacros;
|
||||||
use ide_db::{
|
use ide_db::{
|
||||||
base_db::{
|
base_db::{
|
||||||
salsa::{self, ParallelDatabase},
|
salsa::{self, ParallelDatabase},
|
||||||
|
@ -184,7 +184,7 @@ impl AnalysisHost {
|
||||||
|
|
||||||
/// Applies changes to the current state of the world. If there are
|
/// Applies changes to the current state of the world. If there are
|
||||||
/// outstanding snapshots, they will be canceled.
|
/// 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);
|
self.db.apply_change(change);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,7 +239,7 @@ impl Analysis {
|
||||||
file_set.insert(file_id, VfsPath::new_virtual_path("/main.rs".to_owned()));
|
file_set.insert(file_id, VfsPath::new_virtual_path("/main.rs".to_owned()));
|
||||||
let source_root = SourceRoot::new_local(file_set);
|
let source_root = SourceRoot::new_local(file_set);
|
||||||
|
|
||||||
let mut change = Change::new();
|
let mut change = ChangeWithProcMacros::new();
|
||||||
change.set_roots(vec![source_root]);
|
change.set_roots(vec![source_root]);
|
||||||
let mut crate_graph = CrateGraph::default();
|
let mut crate_graph = CrateGraph::default();
|
||||||
// FIXME: cfg options
|
// FIXME: cfg options
|
||||||
|
|
|
@ -11,7 +11,7 @@ use hir_expand::proc_macro::{
|
||||||
};
|
};
|
||||||
use ide_db::{
|
use ide_db::{
|
||||||
base_db::{CrateGraph, Env, SourceRoot},
|
base_db::{CrateGraph, Env, SourceRoot},
|
||||||
prime_caches, Change, FxHashMap, RootDatabase,
|
prime_caches, ChangeWithProcMacros, FxHashMap, RootDatabase,
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use proc_macro_api::{MacroDylib, ProcMacroServer};
|
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 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 db = RootDatabase::new(lru_cap);
|
||||||
let mut analysis_change = Change::new();
|
let mut analysis_change = ChangeWithProcMacros::new();
|
||||||
|
|
||||||
db.enable_proc_attr_macros();
|
db.enable_proc_attr_macros();
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ doctest = false
|
||||||
drop_bomb = "0.1.5"
|
drop_bomb = "0.1.5"
|
||||||
ra-ap-rustc_lexer.workspace = true
|
ra-ap-rustc_lexer.workspace = true
|
||||||
limit.workspace = true
|
limit.workspace = true
|
||||||
|
tracing = { workspace = true, optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
expect-test = "1.4.0"
|
expect-test = "1.4.0"
|
||||||
|
@ -23,6 +24,7 @@ stdx.workspace = true
|
||||||
sourcegen.workspace = true
|
sourcegen.workspace = true
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
default = ["tracing"]
|
||||||
in-rust-tree = []
|
in-rust-tree = []
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
|
|
|
@ -31,6 +31,7 @@ struct LexError {
|
||||||
|
|
||||||
impl<'a> LexedStr<'a> {
|
impl<'a> LexedStr<'a> {
|
||||||
pub fn new(text: &'a str) -> 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);
|
let mut conv = Converter::new(text);
|
||||||
if let Some(shebang_len) = rustc_lexer::strip_shebang(text) {
|
if let Some(shebang_len) = rustc_lexer::strip_shebang(text) {
|
||||||
conv.res.push(SHEBANG, conv.offset);
|
conv.res.push(SHEBANG, conv.offset);
|
||||||
|
|
|
@ -87,6 +87,7 @@ pub enum TopEntryPoint {
|
||||||
|
|
||||||
impl TopEntryPoint {
|
impl TopEntryPoint {
|
||||||
pub fn parse(&self, input: &Input) -> Output {
|
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 {
|
let entry_point: fn(&'_ mut parser::Parser<'_>) = match self {
|
||||||
TopEntryPoint::SourceFile => grammar::entry::top::source_file,
|
TopEntryPoint::SourceFile => grammar::entry::top::source_file,
|
||||||
TopEntryPoint::MacroStmts => grammar::entry::top::macro_stmts,
|
TopEntryPoint::MacroStmts => grammar::entry::top::macro_stmts,
|
||||||
|
|
|
@ -26,6 +26,7 @@ pub enum StrStep<'a> {
|
||||||
|
|
||||||
impl LexedStr<'_> {
|
impl LexedStr<'_> {
|
||||||
pub fn to_input(&self) -> crate::Input {
|
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 res = crate::Input::default();
|
||||||
let mut was_joint = false;
|
let mut was_joint = false;
|
||||||
for i in 0..self.len() {
|
for i in 0..self.len() {
|
||||||
|
|
|
@ -32,7 +32,6 @@ indexmap = "2.1.0"
|
||||||
paths.workspace = true
|
paths.workspace = true
|
||||||
tt.workspace = true
|
tt.workspace = true
|
||||||
stdx.workspace = true
|
stdx.workspace = true
|
||||||
profile.workspace = true
|
|
||||||
text-size.workspace = true
|
text-size.workspace = true
|
||||||
span.workspace = true
|
span.workspace = true
|
||||||
# Ideally this crate would not depend on salsa things, but we need span information here which wraps
|
# Ideally this crate would not depend on salsa things, but we need span information here which wraps
|
||||||
|
|
|
@ -23,29 +23,6 @@ pub use countme::Count;
|
||||||
|
|
||||||
thread_local!(static IN_SCOPE: RefCell<bool> = const { RefCell::new(false) });
|
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.
|
/// A wrapper around google_cpu_profiler.
|
||||||
///
|
///
|
||||||
/// Usage:
|
/// Usage:
|
||||||
|
|
|
@ -27,7 +27,6 @@ itertools.workspace = true
|
||||||
base-db.workspace = true
|
base-db.workspace = true
|
||||||
cfg.workspace = true
|
cfg.workspace = true
|
||||||
paths.workspace = true
|
paths.workspace = true
|
||||||
profile.workspace = true
|
|
||||||
stdx.workspace = true
|
stdx.workspace = true
|
||||||
toolchain.workspace = true
|
toolchain.workspace = true
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ use std::thread::Builder;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use std::{cell::RefCell, fs::read_to_string, panic::AssertUnwindSafe, path::PathBuf};
|
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 ide::{AnalysisHost, DiagnosticCode, DiagnosticsConfig};
|
||||||
use itertools::Either;
|
use itertools::Either;
|
||||||
use profile::StopWatch;
|
use profile::StopWatch;
|
||||||
|
@ -122,7 +122,7 @@ impl Tester {
|
||||||
FxHashMap::default()
|
FxHashMap::default()
|
||||||
};
|
};
|
||||||
let text = read_to_string(&p).unwrap();
|
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.
|
// 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");
|
let mut ignore_test = text.contains("#![feature");
|
||||||
// Ignore test with extern crates, as this infra don't support them yet.
|
// Ignore test with extern crates, as this infra don't support them yet.
|
||||||
|
|
|
@ -7,7 +7,7 @@ use std::{collections::hash_map::Entry, time::Instant};
|
||||||
|
|
||||||
use crossbeam_channel::{unbounded, Receiver, Sender};
|
use crossbeam_channel::{unbounded, Receiver, Sender};
|
||||||
use flycheck::FlycheckHandle;
|
use flycheck::FlycheckHandle;
|
||||||
use hir::Change;
|
use hir::ChangeWithProcMacros;
|
||||||
use ide::{Analysis, AnalysisHost, Cancellable, FileId};
|
use ide::{Analysis, AnalysisHost, Cancellable, FileId};
|
||||||
use ide_db::base_db::{CrateId, ProcMacroPaths};
|
use ide_db::base_db::{CrateId, ProcMacroPaths};
|
||||||
use load_cargo::SourceRootConfig;
|
use load_cargo::SourceRootConfig;
|
||||||
|
@ -238,7 +238,7 @@ impl GlobalState {
|
||||||
|
|
||||||
let mut file_changes = FxHashMap::<_, (bool, ChangedFile)>::default();
|
let mut file_changes = FxHashMap::<_, (bool, ChangedFile)>::default();
|
||||||
let (change, modified_rust_files, workspace_structure_change) = {
|
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 mut guard = self.vfs.write();
|
||||||
let changed_files = guard.0.take_changes();
|
let changed_files = guard.0.take_changes();
|
||||||
if changed_files.is_empty() {
|
if changed_files.is_empty() {
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
//! in release mode in VS Code. There's however "rust-analyzer: Copy Run Command Line"
|
//! 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.
|
//! 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::{AnalysisHost, CallableSnippets, CompletionConfig, FilePosition, TextSize};
|
||||||
use ide_db::{
|
use ide_db::{
|
||||||
imports::insert_use::{ImportGranularity, InsertUseConfig},
|
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}"))
|
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 _it = stdx::timeit("initial");
|
||||||
let analysis = host.analysis();
|
let analysis = host.analysis();
|
||||||
analysis.highlight_as_html(file_id, false).unwrap();
|
analysis.highlight_as_html(file_id, false).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
crate::tracing::hprof::init("*>100");
|
|
||||||
|
|
||||||
{
|
{
|
||||||
let _it = stdx::timeit("change");
|
let _it = stdx::timeit("change");
|
||||||
let mut text = host.analysis().file_text(file_id).unwrap().to_string();
|
let mut text = host.analysis().file_text(file_id).unwrap().to_string();
|
||||||
text.push_str("\npub fn _dummy() {}\n");
|
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)));
|
change.change_file(file_id, Some(Arc::from(text)));
|
||||||
host.apply_change(change);
|
host.apply_change(change);
|
||||||
}
|
}
|
||||||
|
@ -120,7 +120,7 @@ fn integrated_completion_benchmark() {
|
||||||
let completion_offset =
|
let completion_offset =
|
||||||
patch(&mut text, "db.struct_data(self.id)", "sel;\ndb.struct_data(self.id)")
|
patch(&mut text, "db.struct_data(self.id)", "sel;\ndb.struct_data(self.id)")
|
||||||
+ "sel".len();
|
+ "sel".len();
|
||||||
let mut change = Change::new();
|
let mut change = ChangeWithProcMacros::new();
|
||||||
change.change_file(file_id, Some(Arc::from(text)));
|
change.change_file(file_id, Some(Arc::from(text)));
|
||||||
host.apply_change(change);
|
host.apply_change(change);
|
||||||
completion_offset
|
completion_offset
|
||||||
|
@ -163,7 +163,7 @@ fn integrated_completion_benchmark() {
|
||||||
let completion_offset =
|
let completion_offset =
|
||||||
patch(&mut text, "sel;\ndb.struct_data(self.id)", ";sel;\ndb.struct_data(self.id)")
|
patch(&mut text, "sel;\ndb.struct_data(self.id)", ";sel;\ndb.struct_data(self.id)")
|
||||||
+ ";sel".len();
|
+ ";sel".len();
|
||||||
let mut change = Change::new();
|
let mut change = ChangeWithProcMacros::new();
|
||||||
change.change_file(file_id, Some(Arc::from(text)));
|
change.change_file(file_id, Some(Arc::from(text)));
|
||||||
host.apply_change(change);
|
host.apply_change(change);
|
||||||
completion_offset
|
completion_offset
|
||||||
|
@ -205,7 +205,7 @@ fn integrated_completion_benchmark() {
|
||||||
let completion_offset =
|
let completion_offset =
|
||||||
patch(&mut text, "sel;\ndb.struct_data(self.id)", "self.;\ndb.struct_data(self.id)")
|
patch(&mut text, "sel;\ndb.struct_data(self.id)", "self.;\ndb.struct_data(self.id)")
|
||||||
+ "self.".len();
|
+ "self.".len();
|
||||||
let mut change = Change::new();
|
let mut change = ChangeWithProcMacros::new();
|
||||||
change.change_file(file_id, Some(Arc::from(text)));
|
change.change_file(file_id, Some(Arc::from(text)));
|
||||||
host.apply_change(change);
|
host.apply_change(change);
|
||||||
completion_offset
|
completion_offset
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
use std::{iter, mem};
|
use std::{iter, mem};
|
||||||
|
|
||||||
use flycheck::{FlycheckConfig, FlycheckHandle};
|
use flycheck::{FlycheckConfig, FlycheckHandle};
|
||||||
use hir::{db::DefDatabase, Change, ProcMacros};
|
use hir::{db::DefDatabase, ChangeWithProcMacros, ProcMacros};
|
||||||
use ide::CrateId;
|
use ide::CrateId;
|
||||||
use ide_db::{
|
use ide_db::{
|
||||||
base_db::{salsa::Durability, CrateGraph, ProcMacroPaths, Version},
|
base_db::{salsa::Durability, CrateGraph, ProcMacroPaths, Version},
|
||||||
|
@ -357,7 +357,7 @@ impl GlobalState {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_proc_macros(&mut self, proc_macros: ProcMacros) {
|
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);
|
change.set_proc_macros(proc_macros);
|
||||||
self.analysis_host.apply_change(change);
|
self.analysis_host.apply_change(change);
|
||||||
}
|
}
|
||||||
|
@ -548,7 +548,7 @@ impl GlobalState {
|
||||||
|
|
||||||
ws_to_crate_graph(&self.workspaces, self.config.extra_env(), load)
|
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() {
|
if self.config.expand_proc_macros() {
|
||||||
change.set_proc_macros(
|
change.set_proc_macros(
|
||||||
crate_graph
|
crate_graph
|
||||||
|
|
|
@ -27,7 +27,6 @@ tracing.workspace = true
|
||||||
ra-ap-rustc_lexer.workspace = true
|
ra-ap-rustc_lexer.workspace = true
|
||||||
|
|
||||||
parser.workspace = true
|
parser.workspace = true
|
||||||
profile.workspace = true
|
|
||||||
stdx.workspace = true
|
stdx.workspace = true
|
||||||
text-edit.workspace = true
|
text-edit.workspace = true
|
||||||
|
|
||||||
|
|
|
@ -168,6 +168,7 @@ pub use crate::ast::SourceFile;
|
||||||
|
|
||||||
impl SourceFile {
|
impl SourceFile {
|
||||||
pub fn parse(text: &str) -> Parse<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 (green, mut errors) = parsing::parse_text(text);
|
||||||
let root = SyntaxNode::new_root(green.clone());
|
let root = SyntaxNode::new_root(green.clone());
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ use crate::{syntax_node::GreenNode, SyntaxError, SyntaxTreeBuilder};
|
||||||
pub(crate) use crate::parsing::reparsing::incremental_reparse;
|
pub(crate) use crate::parsing::reparsing::incremental_reparse;
|
||||||
|
|
||||||
pub(crate) fn parse_text(text: &str) -> (GreenNode, Vec<SyntaxError>) {
|
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 lexed = parser::LexedStr::new(text);
|
||||||
let parser_input = lexed.to_input();
|
let parser_input = lexed.to_input();
|
||||||
let parser_output = parser::TopEntryPoint::SourceFile.parse(&parser_input);
|
let parser_output = parser::TopEntryPoint::SourceFile.parse(&parser_input);
|
||||||
|
@ -21,6 +22,7 @@ pub(crate) fn build_tree(
|
||||||
lexed: parser::LexedStr<'_>,
|
lexed: parser::LexedStr<'_>,
|
||||||
parser_output: parser::Output,
|
parser_output: parser::Output,
|
||||||
) -> (GreenNode, Vec<SyntaxError>, bool) {
|
) -> (GreenNode, Vec<SyntaxError>, bool) {
|
||||||
|
let _p = tracing::span!(tracing::Level::INFO, "build_tree").entered();
|
||||||
let mut builder = SyntaxTreeBuilder::default();
|
let mut builder = SyntaxTreeBuilder::default();
|
||||||
|
|
||||||
let is_eof = lexed.intersperse_trivia(&parser_output, &mut |step| match step {
|
let is_eof = lexed.intersperse_trivia(&parser_output, &mut |step| match step {
|
||||||
|
|
|
@ -16,6 +16,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) fn validate(root: &SyntaxNode) -> Vec<SyntaxError> {
|
pub(crate) fn validate(root: &SyntaxNode) -> Vec<SyntaxError> {
|
||||||
|
let _p = tracing::span!(tracing::Level::INFO, "parser::validate").entered();
|
||||||
// FIXME:
|
// FIXME:
|
||||||
// * Add unescape validation of raw string literals and raw byte string literals
|
// * Add unescape validation of raw string literals and raw byte string literals
|
||||||
// * Add validation of doc comments are being attached to nodes
|
// * Add validation of doc comments are being attached to nodes
|
||||||
|
|
|
@ -7,7 +7,7 @@ use base_db::{
|
||||||
};
|
};
|
||||||
use cfg::CfgOptions;
|
use cfg::CfgOptions;
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
change::Change,
|
change::ChangeWithProcMacros,
|
||||||
db::ExpandDatabase,
|
db::ExpandDatabase,
|
||||||
proc_macro::{
|
proc_macro::{
|
||||||
ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroKind, ProcMacros,
|
ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroKind, ProcMacros,
|
||||||
|
@ -103,7 +103,7 @@ impl<DB: ExpandDatabase + SourceDatabaseExt + Default + 'static> WithFixture for
|
||||||
pub struct ChangeFixture {
|
pub struct ChangeFixture {
|
||||||
pub file_position: Option<(FileId, RangeOrOffset)>,
|
pub file_position: Option<(FileId, RangeOrOffset)>,
|
||||||
pub files: Vec<FileId>,
|
pub files: Vec<FileId>,
|
||||||
pub change: Change,
|
pub change: ChangeWithProcMacros,
|
||||||
}
|
}
|
||||||
|
|
||||||
const SOURCE_ROOT_PREFIX: &str = "/";
|
const SOURCE_ROOT_PREFIX: &str = "/";
|
||||||
|
@ -320,7 +320,7 @@ impl ChangeFixture {
|
||||||
};
|
};
|
||||||
roots.push(root);
|
roots.push(root);
|
||||||
|
|
||||||
let mut change = Change {
|
let mut change = ChangeWithProcMacros {
|
||||||
source_change,
|
source_change,
|
||||||
proc_macros: proc_macros.is_empty().not().then_some(proc_macros),
|
proc_macros: proc_macros.is_empty().not().then_some(proc_macros),
|
||||||
toolchains: Some(iter::repeat(toolchain).take(crate_graph.len()).collect()),
|
toolchains: Some(iter::repeat(toolchain).take(crate_graph.len()).collect()),
|
||||||
|
|
Loading…
Reference in a new issue