mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-27 12:29:21 +00:00
Always cache macro expansions' root node in Semantics
Previously some expansions were not cached, but were cached in the expansion cache, which caused panics when later queries tried to lookup the node from the expansion cache.
This commit is contained in:
parent
94b526fc86
commit
35e171aa01
7 changed files with 166 additions and 48 deletions
|
@ -449,7 +449,7 @@ impl<'db> SemanticsImpl<'db> {
|
|||
Some(
|
||||
calls
|
||||
.into_iter()
|
||||
.map(|call| macro_call_to_macro_id(ctx, call?).map(|id| Macro { id }))
|
||||
.map(|call| macro_call_to_macro_id(self, ctx, call?).map(|id| Macro { id }))
|
||||
.collect(),
|
||||
)
|
||||
})
|
||||
|
@ -892,16 +892,7 @@ impl<'db> SemanticsImpl<'db> {
|
|||
let InMacroFile { file_id, value: mapped_tokens } = self.with_ctx(|ctx| {
|
||||
Some(
|
||||
ctx.cache
|
||||
.expansion_info_cache
|
||||
.entry(macro_file)
|
||||
.or_insert_with(|| {
|
||||
let exp_info = macro_file.expansion_info(self.db.upcast());
|
||||
|
||||
let InMacroFile { file_id, value } = exp_info.expanded();
|
||||
self.cache(value, file_id.into());
|
||||
|
||||
exp_info
|
||||
})
|
||||
.get_or_insert_expansion(self, macro_file)
|
||||
.map_range_down(span)?
|
||||
.map(SmallVec::<[_; 2]>::from_iter),
|
||||
)
|
||||
|
@ -1187,11 +1178,7 @@ impl<'db> SemanticsImpl<'db> {
|
|||
let macro_file = file_id.macro_file()?;
|
||||
|
||||
self.with_ctx(|ctx| {
|
||||
let expansion_info = ctx
|
||||
.cache
|
||||
.expansion_info_cache
|
||||
.entry(macro_file)
|
||||
.or_insert_with(|| macro_file.expansion_info(self.db.upcast()));
|
||||
let expansion_info = ctx.cache.get_or_insert_expansion(self, macro_file);
|
||||
expansion_info.arg().map(|node| node?.parent()).transpose()
|
||||
})
|
||||
}
|
||||
|
@ -1407,7 +1394,7 @@ impl<'db> SemanticsImpl<'db> {
|
|||
let macro_call = self.find_file(macro_call.syntax()).with_value(macro_call);
|
||||
self.with_ctx(|ctx| {
|
||||
ctx.macro_call_to_macro_call(macro_call)
|
||||
.and_then(|call| macro_call_to_macro_id(ctx, call))
|
||||
.and_then(|call| macro_call_to_macro_id(self, ctx, call))
|
||||
.map(Into::into)
|
||||
})
|
||||
.or_else(|| {
|
||||
|
@ -1449,7 +1436,7 @@ impl<'db> SemanticsImpl<'db> {
|
|||
let item_in_file = self.wrap_node_infile(item.clone());
|
||||
let id = self.with_ctx(|ctx| {
|
||||
let macro_call_id = ctx.item_to_macro_call(item_in_file.as_ref())?;
|
||||
macro_call_to_macro_id(ctx, macro_call_id)
|
||||
macro_call_to_macro_id(self, ctx, macro_call_id)
|
||||
})?;
|
||||
Some(Macro { id })
|
||||
}
|
||||
|
@ -1769,6 +1756,7 @@ impl<'db> SemanticsImpl<'db> {
|
|||
}
|
||||
|
||||
fn macro_call_to_macro_id(
|
||||
sema: &SemanticsImpl<'_>,
|
||||
ctx: &mut SourceToDefCtx<'_, '_>,
|
||||
macro_call_id: MacroCallId,
|
||||
) -> Option<MacroId> {
|
||||
|
@ -1784,11 +1772,7 @@ fn macro_call_to_macro_id(
|
|||
it.to_ptr(db).to_node(&db.parse(file_id).syntax_node())
|
||||
}
|
||||
HirFileIdRepr::MacroFile(macro_file) => {
|
||||
let expansion_info = ctx
|
||||
.cache
|
||||
.expansion_info_cache
|
||||
.entry(macro_file)
|
||||
.or_insert_with(|| macro_file.expansion_info(ctx.db.upcast()));
|
||||
let expansion_info = ctx.cache.get_or_insert_expansion(sema, macro_file);
|
||||
it.to_ptr(db).to_node(&expansion_info.expanded().value)
|
||||
}
|
||||
};
|
||||
|
@ -1800,11 +1784,7 @@ fn macro_call_to_macro_id(
|
|||
it.to_ptr(db).to_node(&db.parse(file_id).syntax_node())
|
||||
}
|
||||
HirFileIdRepr::MacroFile(macro_file) => {
|
||||
let expansion_info = ctx
|
||||
.cache
|
||||
.expansion_info_cache
|
||||
.entry(macro_file)
|
||||
.or_insert_with(|| macro_file.expansion_info(ctx.db.upcast()));
|
||||
let expansion_info = ctx.cache.get_or_insert_expansion(sema, macro_file);
|
||||
it.to_ptr(db).to_node(&expansion_info.expanded().value)
|
||||
}
|
||||
};
|
||||
|
|
|
@ -99,7 +99,8 @@ use hir_def::{
|
|||
VariantId,
|
||||
};
|
||||
use hir_expand::{
|
||||
attrs::AttrId, name::AsName, ExpansionInfo, HirFileId, HirFileIdExt, MacroCallId,
|
||||
attrs::AttrId, name::AsName, ExpansionInfo, HirFileId, HirFileIdExt, InMacroFile, MacroCallId,
|
||||
MacroFileIdExt,
|
||||
};
|
||||
use rustc_hash::FxHashMap;
|
||||
use smallvec::SmallVec;
|
||||
|
@ -110,15 +111,32 @@ use syntax::{
|
|||
AstNode, AstPtr, SyntaxNode,
|
||||
};
|
||||
|
||||
use crate::{db::HirDatabase, InFile, InlineAsmOperand};
|
||||
use crate::{db::HirDatabase, InFile, InlineAsmOperand, SemanticsImpl};
|
||||
|
||||
#[derive(Default)]
|
||||
pub(super) struct SourceToDefCache {
|
||||
pub(super) dynmap_cache: FxHashMap<(ChildContainer, HirFileId), DynMap>,
|
||||
pub(super) expansion_info_cache: FxHashMap<MacroFileId, ExpansionInfo>,
|
||||
expansion_info_cache: FxHashMap<MacroFileId, ExpansionInfo>,
|
||||
pub(super) file_to_def_cache: FxHashMap<FileId, SmallVec<[ModuleId; 1]>>,
|
||||
}
|
||||
|
||||
impl SourceToDefCache {
|
||||
pub(super) fn get_or_insert_expansion(
|
||||
&mut self,
|
||||
sema: &SemanticsImpl<'_>,
|
||||
macro_file: MacroFileId,
|
||||
) -> &ExpansionInfo {
|
||||
self.expansion_info_cache.entry(macro_file).or_insert_with(|| {
|
||||
let exp_info = macro_file.expansion_info(sema.db.upcast());
|
||||
|
||||
let InMacroFile { file_id, value } = exp_info.expanded();
|
||||
sema.cache(value, file_id.into());
|
||||
|
||||
exp_info
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct SourceToDefCtx<'db, 'cache> {
|
||||
pub(super) db: &'db dyn HirDatabase,
|
||||
pub(super) cache: &'cache mut SourceToDefCache,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue