mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-10 07:04:22 +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 = [
|
||||
"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",
|
||||
|
|
|
@ -21,7 +21,6 @@ tracing.workspace = true
|
|||
|
||||
# local deps
|
||||
cfg.workspace = true
|
||||
profile.workspace = true
|
||||
stdx.workspace = true
|
||||
syntax.workspace = true
|
||||
vfs.workspace = true
|
||||
|
|
|
@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()),
|
||||
|
|
Loading…
Reference in a new issue