mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-03 23:25:03 +00:00
Auto merge of #12827 - Veykril:be-lazy, r=Veykril
internal: Construct fewer `AstIdMap`s in lowering
This commit is contained in:
commit
2f6c39005c
4 changed files with 36 additions and 48 deletions
|
@ -5,21 +5,18 @@ mod lower;
|
||||||
mod tests;
|
mod tests;
|
||||||
pub mod scope;
|
pub mod scope;
|
||||||
|
|
||||||
use std::{mem, ops::Index, sync::Arc};
|
use std::{ops::Index, sync::Arc};
|
||||||
|
|
||||||
use base_db::CrateId;
|
use base_db::CrateId;
|
||||||
use cfg::{CfgExpr, CfgOptions};
|
use cfg::{CfgExpr, CfgOptions};
|
||||||
use drop_bomb::DropBomb;
|
use drop_bomb::DropBomb;
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use hir_expand::{
|
use hir_expand::{hygiene::Hygiene, ExpandError, ExpandResult, HirFileId, InFile, MacroCallId};
|
||||||
ast_id_map::AstIdMap, hygiene::Hygiene, AstId, ExpandError, ExpandResult, HirFileId, InFile,
|
|
||||||
MacroCallId,
|
|
||||||
};
|
|
||||||
use la_arena::{Arena, ArenaMap};
|
use la_arena::{Arena, ArenaMap};
|
||||||
use limit::Limit;
|
use limit::Limit;
|
||||||
use profile::Count;
|
use profile::Count;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use syntax::{ast, AstNode, AstPtr, SyntaxNodePtr};
|
use syntax::{ast, AstPtr, SyntaxNodePtr};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
attr::{Attrs, RawAttrs},
|
attr::{Attrs, RawAttrs},
|
||||||
|
@ -50,7 +47,6 @@ pub struct Expander {
|
||||||
cfg_expander: CfgExpander,
|
cfg_expander: CfgExpander,
|
||||||
def_map: Arc<DefMap>,
|
def_map: Arc<DefMap>,
|
||||||
current_file_id: HirFileId,
|
current_file_id: HirFileId,
|
||||||
ast_id_map: Arc<AstIdMap>,
|
|
||||||
module: LocalModuleId,
|
module: LocalModuleId,
|
||||||
recursion_limit: usize,
|
recursion_limit: usize,
|
||||||
}
|
}
|
||||||
|
@ -80,12 +76,10 @@ impl Expander {
|
||||||
pub fn new(db: &dyn DefDatabase, current_file_id: HirFileId, module: ModuleId) -> Expander {
|
pub fn new(db: &dyn DefDatabase, current_file_id: HirFileId, module: ModuleId) -> Expander {
|
||||||
let cfg_expander = CfgExpander::new(db, current_file_id, module.krate);
|
let cfg_expander = CfgExpander::new(db, current_file_id, module.krate);
|
||||||
let def_map = module.def_map(db);
|
let def_map = module.def_map(db);
|
||||||
let ast_id_map = db.ast_id_map(current_file_id);
|
|
||||||
Expander {
|
Expander {
|
||||||
cfg_expander,
|
cfg_expander,
|
||||||
def_map,
|
def_map,
|
||||||
current_file_id,
|
current_file_id,
|
||||||
ast_id_map,
|
|
||||||
module: module.local_id,
|
module: module.local_id,
|
||||||
recursion_limit: 0,
|
recursion_limit: 0,
|
||||||
}
|
}
|
||||||
|
@ -168,14 +162,10 @@ impl Expander {
|
||||||
tracing::debug!("macro expansion {:#?}", node.syntax());
|
tracing::debug!("macro expansion {:#?}", node.syntax());
|
||||||
|
|
||||||
self.recursion_limit += 1;
|
self.recursion_limit += 1;
|
||||||
let mark = Mark {
|
let mark =
|
||||||
file_id: self.current_file_id,
|
Mark { file_id: self.current_file_id, bomb: DropBomb::new("expansion mark dropped") };
|
||||||
ast_id_map: mem::take(&mut self.ast_id_map),
|
|
||||||
bomb: DropBomb::new("expansion mark dropped"),
|
|
||||||
};
|
|
||||||
self.cfg_expander.hygiene = Hygiene::new(db.upcast(), file_id);
|
self.cfg_expander.hygiene = Hygiene::new(db.upcast(), file_id);
|
||||||
self.current_file_id = file_id;
|
self.current_file_id = file_id;
|
||||||
self.ast_id_map = db.ast_id_map(file_id);
|
|
||||||
|
|
||||||
ExpandResult { value: Some((mark, node)), err }
|
ExpandResult { value: Some((mark, node)), err }
|
||||||
}
|
}
|
||||||
|
@ -183,7 +173,6 @@ impl Expander {
|
||||||
pub fn exit(&mut self, db: &dyn DefDatabase, mut mark: Mark) {
|
pub fn exit(&mut self, db: &dyn DefDatabase, mut mark: Mark) {
|
||||||
self.cfg_expander.hygiene = Hygiene::new(db.upcast(), mark.file_id);
|
self.cfg_expander.hygiene = Hygiene::new(db.upcast(), mark.file_id);
|
||||||
self.current_file_id = mark.file_id;
|
self.current_file_id = mark.file_id;
|
||||||
self.ast_id_map = mem::take(&mut mark.ast_id_map);
|
|
||||||
self.recursion_limit -= 1;
|
self.recursion_limit -= 1;
|
||||||
mark.bomb.defuse();
|
mark.bomb.defuse();
|
||||||
}
|
}
|
||||||
|
@ -213,11 +202,6 @@ impl Expander {
|
||||||
self.def_map.resolve_path(db, self.module, path, BuiltinShadowMode::Other).0.take_macros()
|
self.def_map.resolve_path(db, self.module, path, BuiltinShadowMode::Other).0.take_macros()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ast_id<N: AstNode>(&self, item: &N) -> AstId<N> {
|
|
||||||
let file_local_id = self.ast_id_map.ast_id(item);
|
|
||||||
AstId::new(self.current_file_id, file_local_id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn recursion_limit(&self, db: &dyn DefDatabase) -> Limit {
|
fn recursion_limit(&self, db: &dyn DefDatabase) -> Limit {
|
||||||
let limit = db.crate_limits(self.cfg_expander.krate).recursion_limit as _;
|
let limit = db.crate_limits(self.cfg_expander.krate).recursion_limit as _;
|
||||||
|
|
||||||
|
@ -233,7 +217,6 @@ impl Expander {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Mark {
|
pub struct Mark {
|
||||||
file_id: HirFileId,
|
file_id: HirFileId,
|
||||||
ast_id_map: Arc<AstIdMap>,
|
|
||||||
bomb: DropBomb,
|
bomb: DropBomb,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,12 +5,13 @@ use std::{mem, sync::Arc};
|
||||||
|
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
ast_id_map::{AstIdMap, FileAstId},
|
ast_id_map::AstIdMap,
|
||||||
hygiene::Hygiene,
|
hygiene::Hygiene,
|
||||||
name::{name, AsName, Name},
|
name::{name, AsName, Name},
|
||||||
ExpandError, HirFileId, InFile,
|
AstId, ExpandError, HirFileId, InFile,
|
||||||
};
|
};
|
||||||
use la_arena::Arena;
|
use la_arena::Arena;
|
||||||
|
use once_cell::unsync::OnceCell;
|
||||||
use profile::Count;
|
use profile::Count;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use syntax::{
|
use syntax::{
|
||||||
|
@ -41,8 +42,7 @@ use crate::{
|
||||||
pub struct LowerCtx<'a> {
|
pub struct LowerCtx<'a> {
|
||||||
pub db: &'a dyn DefDatabase,
|
pub db: &'a dyn DefDatabase,
|
||||||
hygiene: Hygiene,
|
hygiene: Hygiene,
|
||||||
file_id: Option<HirFileId>,
|
ast_id_map: Option<(HirFileId, OnceCell<Arc<AstIdMap>>)>,
|
||||||
source_ast_id_map: Option<Arc<AstIdMap>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> LowerCtx<'a> {
|
impl<'a> LowerCtx<'a> {
|
||||||
|
@ -50,29 +50,26 @@ impl<'a> LowerCtx<'a> {
|
||||||
LowerCtx {
|
LowerCtx {
|
||||||
db,
|
db,
|
||||||
hygiene: Hygiene::new(db.upcast(), file_id),
|
hygiene: Hygiene::new(db.upcast(), file_id),
|
||||||
file_id: Some(file_id),
|
ast_id_map: Some((file_id, OnceCell::new())),
|
||||||
source_ast_id_map: Some(db.ast_id_map(file_id)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_hygiene(db: &'a dyn DefDatabase, hygiene: &Hygiene) -> Self {
|
pub fn with_hygiene(db: &'a dyn DefDatabase, hygiene: &Hygiene) -> Self {
|
||||||
LowerCtx { db, hygiene: hygiene.clone(), file_id: None, source_ast_id_map: None }
|
LowerCtx { db, hygiene: hygiene.clone(), ast_id_map: None }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn hygiene(&self) -> &Hygiene {
|
pub(crate) fn hygiene(&self) -> &Hygiene {
|
||||||
&self.hygiene
|
&self.hygiene
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn file_id(&self) -> HirFileId {
|
|
||||||
self.file_id.unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn lower_path(&self, ast: ast::Path) -> Option<Path> {
|
pub(crate) fn lower_path(&self, ast: ast::Path) -> Option<Path> {
|
||||||
Path::from_src(ast, self)
|
Path::from_src(ast, self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn ast_id<N: AstNode>(&self, item: &N) -> Option<FileAstId<N>> {
|
pub(crate) fn ast_id<N: AstNode>(&self, db: &dyn DefDatabase, item: &N) -> Option<AstId<N>> {
|
||||||
self.source_ast_id_map.as_ref().map(|ast_id_map| ast_id_map.ast_id(item))
|
let &(file_id, ref ast_id_map) = self.ast_id_map.as_ref()?;
|
||||||
|
let ast_id_map = ast_id_map.get_or_init(|| db.ast_id_map(file_id));
|
||||||
|
Some(InFile::new(file_id, ast_id_map.ast_id(item)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,6 +82,7 @@ pub(super) fn lower(
|
||||||
ExprCollector {
|
ExprCollector {
|
||||||
db,
|
db,
|
||||||
source_map: BodySourceMap::default(),
|
source_map: BodySourceMap::default(),
|
||||||
|
ast_id_map: db.ast_id_map(expander.current_file_id),
|
||||||
body: Body {
|
body: Body {
|
||||||
exprs: Arena::default(),
|
exprs: Arena::default(),
|
||||||
pats: Arena::default(),
|
pats: Arena::default(),
|
||||||
|
@ -105,6 +103,7 @@ pub(super) fn lower(
|
||||||
struct ExprCollector<'a> {
|
struct ExprCollector<'a> {
|
||||||
db: &'a dyn DefDatabase,
|
db: &'a dyn DefDatabase,
|
||||||
expander: Expander,
|
expander: Expander,
|
||||||
|
ast_id_map: Arc<AstIdMap>,
|
||||||
body: Body,
|
body: Body,
|
||||||
source_map: BodySourceMap,
|
source_map: BodySourceMap,
|
||||||
// a poor-mans union-find?
|
// a poor-mans union-find?
|
||||||
|
@ -586,8 +585,13 @@ impl ExprCollector<'_> {
|
||||||
match res.value {
|
match res.value {
|
||||||
Some((mark, expansion)) => {
|
Some((mark, expansion)) => {
|
||||||
self.source_map.expansions.insert(macro_call_ptr, self.expander.current_file_id);
|
self.source_map.expansions.insert(macro_call_ptr, self.expander.current_file_id);
|
||||||
|
let prev_ast_id_map = mem::replace(
|
||||||
|
&mut self.ast_id_map,
|
||||||
|
self.db.ast_id_map(self.expander.current_file_id),
|
||||||
|
);
|
||||||
|
|
||||||
let id = collector(self, Some(expansion));
|
let id = collector(self, Some(expansion));
|
||||||
|
self.ast_id_map = prev_ast_id_map;
|
||||||
self.expander.exit(self.db, mark);
|
self.expander.exit(self.db, mark);
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
@ -675,7 +679,8 @@ impl ExprCollector<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_block(&mut self, block: ast::BlockExpr) -> ExprId {
|
fn collect_block(&mut self, block: ast::BlockExpr) -> ExprId {
|
||||||
let ast_id = self.expander.ast_id(&block);
|
let file_local_id = self.ast_id_map.ast_id(&block);
|
||||||
|
let ast_id = AstId::new(self.expander.current_file_id, file_local_id);
|
||||||
let block_loc =
|
let block_loc =
|
||||||
BlockLoc { ast_id, module: self.expander.def_map.module_id(self.expander.module) };
|
BlockLoc { ast_id, module: self.expander.def_map.module_id(self.expander.module) };
|
||||||
let block_id = self.db.intern_block(block_loc);
|
let block_id = self.db.intern_block(block_loc);
|
||||||
|
|
|
@ -550,10 +550,12 @@ impl<'a> AssocItemCollector<'a> {
|
||||||
AssocItem::MacroCall(call) => {
|
AssocItem::MacroCall(call) => {
|
||||||
let call = &item_tree[call];
|
let call = &item_tree[call];
|
||||||
let ast_id_map = self.db.ast_id_map(self.expander.current_file_id());
|
let ast_id_map = self.db.ast_id_map(self.expander.current_file_id());
|
||||||
let root = self.db.parse_or_expand(self.expander.current_file_id()).unwrap();
|
if let Some(root) = self.db.parse_or_expand(self.expander.current_file_id()) {
|
||||||
let call = ast_id_map.get(call.ast_id).to_node(&root);
|
let call = ast_id_map.get(call.ast_id).to_node(&root);
|
||||||
let _cx =
|
let _cx = stdx::panic_context::enter(format!(
|
||||||
stdx::panic_context::enter(format!("collect_items MacroCall: {}", call));
|
"collect_items MacroCall: {}",
|
||||||
|
call
|
||||||
|
));
|
||||||
let res = self.expander.enter_expand(self.db, call);
|
let res = self.expander.enter_expand(self.db, call);
|
||||||
|
|
||||||
if let Ok(ExpandResult { value: Some((mark, mac)), .. }) = res {
|
if let Ok(ExpandResult { value: Some((mark, mac)), .. }) = res {
|
||||||
|
@ -563,6 +565,7 @@ impl<'a> AssocItemCollector<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn collect_macro_items(&mut self, mark: Mark, mac: ast::MacroItems) {
|
fn collect_macro_items(&mut self, mark: Mark, mac: ast::MacroItems) {
|
||||||
let src: InFile<ast::MacroItems> = self.expander.to_source(mac);
|
let src: InFile<ast::MacroItems> = self.expander.to_source(mac);
|
||||||
|
|
|
@ -5,7 +5,7 @@ use std::fmt::Write;
|
||||||
|
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
name::{AsName, Name},
|
name::{AsName, Name},
|
||||||
AstId, InFile,
|
AstId,
|
||||||
};
|
};
|
||||||
use syntax::ast::{self, HasName};
|
use syntax::ast::{self, HasName};
|
||||||
|
|
||||||
|
@ -236,10 +236,7 @@ impl TypeRef {
|
||||||
TypeRef::DynTrait(type_bounds_from_ast(ctx, inner.type_bound_list()))
|
TypeRef::DynTrait(type_bounds_from_ast(ctx, inner.type_bound_list()))
|
||||||
}
|
}
|
||||||
ast::Type::MacroType(mt) => match mt.macro_call() {
|
ast::Type::MacroType(mt) => match mt.macro_call() {
|
||||||
Some(mc) => ctx
|
Some(mc) => ctx.ast_id(ctx.db, &mc).map(TypeRef::Macro).unwrap_or(TypeRef::Error),
|
||||||
.ast_id(&mc)
|
|
||||||
.map(|mc| TypeRef::Macro(InFile::new(ctx.file_id(), mc)))
|
|
||||||
.unwrap_or(TypeRef::Error),
|
|
||||||
None => TypeRef::Error,
|
None => TypeRef::Error,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue