Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-expand/src/lib.rs')
-rw-r--r--crates/hir-expand/src/lib.rs85
1 files changed, 42 insertions, 43 deletions
diff --git a/crates/hir-expand/src/lib.rs b/crates/hir-expand/src/lib.rs
index 8d42a24e2f..0850d6156d 100644
--- a/crates/hir-expand/src/lib.rs
+++ b/crates/hir-expand/src/lib.rs
@@ -69,12 +69,12 @@ pub use tt;
#[macro_export]
macro_rules! impl_intern_lookup {
- ($db:ident, $id:ident, $loc:ident, $intern:ident, $lookup:ident) => {
+ ($db:ident, $id:ident, $loc:ident) => {
impl $crate::Intern for $loc {
type Database = dyn $db;
type ID = $id;
fn intern(self, db: &Self::Database) -> Self::ID {
- db.$intern(self)
+ $id::new(db, self)
}
}
@@ -82,7 +82,7 @@ macro_rules! impl_intern_lookup {
type Database = dyn $db;
type Data = $loc;
fn lookup(&self, db: &Self::Database) -> Self::Data {
- db.$lookup(*self)
+ self.loc(db)
}
}
};
@@ -101,13 +101,7 @@ pub trait Lookup {
fn lookup(&self, db: &Self::Database) -> Self::Data;
}
-impl_intern_lookup!(
- ExpandDatabase,
- MacroCallId,
- MacroCallLoc,
- intern_macro_call,
- lookup_intern_macro_call
-);
+impl_intern_lookup!(ExpandDatabase, MacroCallId, MacroCallLoc);
pub type ExpandResult<T> = ValueResult<T, ExpandError>;
@@ -279,7 +273,7 @@ impl MacroDefKind {
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct EagerCallInfo {
/// The expanded argument of the eager macro.
- arg: Arc<tt::TopSubtree>,
+ arg: tt::TopSubtree,
/// Call id of the eager macro's input file (this is the macro file for its fully expanded input).
arg_id: MacroCallId,
error: Option<ExpandError>,
@@ -296,7 +290,7 @@ pub enum MacroCallKind {
/// for the eager input macro file.
// FIXME: This is being interned, subtrees can vary quickly differing just slightly causing
// leakage problems here
- eager: Option<Arc<EagerCallInfo>>,
+ eager: Option<Box<EagerCallInfo>>,
},
Derive {
ast_id: AstId<ast::Adt>,
@@ -311,7 +305,7 @@ pub enum MacroCallKind {
Attr {
ast_id: AstId<ast::Item>,
// FIXME: This shouldn't be here, we can derive this from `invoc_attr_index`.
- attr_args: Option<Arc<tt::TopSubtree>>,
+ attr_args: Option<Box<tt::TopSubtree>>,
/// This contains the list of all *active* attributes (derives and attr macros) preceding this
/// attribute, including this attribute. You can retrieve the [`AttrId`] of the current attribute
/// by calling [`invoc_attr()`] on this.
@@ -386,7 +380,7 @@ impl HirFileId {
pub fn edition(self, db: &dyn ExpandDatabase) -> Edition {
match self {
HirFileId::FileId(file_id) => file_id.edition(db),
- HirFileId::MacroFile(m) => db.lookup_intern_macro_call(m).def.edition,
+ HirFileId::MacroFile(m) => m.loc(db).def.edition,
}
}
pub fn original_file(self, db: &dyn ExpandDatabase) -> EditionedFileId {
@@ -395,7 +389,7 @@ impl HirFileId {
match file_id {
HirFileId::FileId(id) => break id,
HirFileId::MacroFile(macro_call_id) => {
- file_id = db.lookup_intern_macro_call(macro_call_id).kind.file_id()
+ file_id = macro_call_id.loc(db).kind.file_id()
}
}
}
@@ -406,7 +400,7 @@ impl HirFileId {
match self {
HirFileId::FileId(id) => break id,
HirFileId::MacroFile(file) => {
- let loc = db.lookup_intern_macro_call(file);
+ let loc = file.loc(db);
if loc.def.is_include()
&& let MacroCallKind::FnLike { eager: Some(eager), .. } = &loc.kind
&& let Ok(it) = include_input_to_file_id(db, file, &eager.arg)
@@ -420,21 +414,21 @@ impl HirFileId {
}
pub fn original_call_node(self, db: &dyn ExpandDatabase) -> Option<InRealFile<SyntaxNode>> {
- let mut call = db.lookup_intern_macro_call(self.macro_file()?).to_node(db);
+ let mut call = self.macro_file()?.loc(db).to_node(db);
loop {
match call.file_id {
HirFileId::FileId(file_id) => {
break Some(InRealFile { file_id, value: call.value });
}
HirFileId::MacroFile(macro_call_id) => {
- call = db.lookup_intern_macro_call(macro_call_id).to_node(db);
+ call = macro_call_id.loc(db).to_node(db);
}
}
}
}
pub fn call_node(self, db: &dyn ExpandDatabase) -> Option<InFile<SyntaxNode>> {
- Some(db.lookup_intern_macro_call(self.macro_file()?).to_node(db))
+ Some(self.macro_file()?.loc(db).to_node(db))
}
pub fn as_builtin_derive_attr_node(
@@ -442,7 +436,7 @@ impl HirFileId {
db: &dyn ExpandDatabase,
) -> Option<InFile<ast::Attr>> {
let macro_file = self.macro_file()?;
- let loc = db.lookup_intern_macro_call(macro_file);
+ let loc = macro_file.loc(db);
let attr = match loc.def.kind {
MacroDefKind::BuiltInDerive(..) => loc.to_node(db),
_ => return None,
@@ -471,13 +465,13 @@ pub enum MacroKind {
impl MacroCallId {
pub fn call_node(self, db: &dyn ExpandDatabase) -> InFile<SyntaxNode> {
- db.lookup_intern_macro_call(self).to_node(db)
+ self.loc(db).to_node(db)
}
pub fn expansion_level(self, db: &dyn ExpandDatabase) -> u32 {
let mut level = 0;
let mut macro_file = self;
loop {
- let loc = db.lookup_intern_macro_call(macro_file);
+ let loc = macro_file.loc(db);
level += 1;
macro_file = match loc.kind.file_id() {
@@ -487,16 +481,16 @@ impl MacroCallId {
}
}
pub fn parent(self, db: &dyn ExpandDatabase) -> HirFileId {
- db.lookup_intern_macro_call(self).kind.file_id()
+ self.loc(db).kind.file_id()
}
/// Return expansion information if it is a macro-expansion file
- pub fn expansion_info(self, db: &dyn ExpandDatabase) -> ExpansionInfo {
+ pub fn expansion_info(self, db: &dyn ExpandDatabase) -> ExpansionInfo<'_> {
ExpansionInfo::new(db, self)
}
pub fn kind(self, db: &dyn ExpandDatabase) -> MacroKind {
- match db.lookup_intern_macro_call(self).def.kind {
+ match self.loc(db).def.kind {
MacroDefKind::Declarative(..) => MacroKind::Declarative,
MacroDefKind::BuiltIn(..) | MacroDefKind::BuiltInEager(..) => {
MacroKind::DeclarativeBuiltIn
@@ -510,24 +504,24 @@ impl MacroCallId {
}
pub fn is_include_macro(self, db: &dyn ExpandDatabase) -> bool {
- db.lookup_intern_macro_call(self).def.is_include()
+ self.loc(db).def.is_include()
}
pub fn is_include_like_macro(self, db: &dyn ExpandDatabase) -> bool {
- db.lookup_intern_macro_call(self).def.is_include_like()
+ self.loc(db).def.is_include_like()
}
pub fn is_env_or_option_env(self, db: &dyn ExpandDatabase) -> bool {
- db.lookup_intern_macro_call(self).def.is_env_or_option_env()
+ self.loc(db).def.is_env_or_option_env()
}
pub fn is_eager(self, db: &dyn ExpandDatabase) -> bool {
- let loc = db.lookup_intern_macro_call(self);
+ let loc = self.loc(db);
matches!(loc.def.kind, MacroDefKind::BuiltInEager(..))
}
pub fn eager_arg(self, db: &dyn ExpandDatabase) -> Option<MacroCallId> {
- let loc = db.lookup_intern_macro_call(self);
+ let loc = self.loc(db);
match &loc.kind {
MacroCallKind::FnLike { eager, .. } => eager.as_ref().map(|it| it.arg_id),
_ => None,
@@ -535,7 +529,7 @@ impl MacroCallId {
}
pub fn is_derive_attr_pseudo_expansion(self, db: &dyn ExpandDatabase) -> bool {
- let loc = db.lookup_intern_macro_call(self);
+ let loc = self.loc(db);
loc.def.is_attribute_derive()
}
}
@@ -548,7 +542,7 @@ impl MacroDefId {
kind: MacroCallKind,
ctxt: SyntaxContext,
) -> MacroCallId {
- db.intern_macro_call(MacroCallLoc { def: self, krate, kind, ctxt })
+ MacroCallId::new(db, MacroCallLoc { def: self, krate, kind, ctxt })
}
pub fn definition_range(&self, db: &dyn ExpandDatabase) -> InFile<TextRange> {
@@ -725,7 +719,7 @@ impl MacroCallKind {
let file_id = loop {
match kind.file_id() {
HirFileId::MacroFile(file) => {
- kind = db.lookup_intern_macro_call(file).kind;
+ kind = file.loc(db).kind;
}
HirFileId::FileId(file_id) => break file_id,
}
@@ -750,7 +744,7 @@ impl MacroCallKind {
let file_id = loop {
match kind.file_id() {
HirFileId::MacroFile(file) => {
- kind = db.lookup_intern_macro_call(file).kind;
+ kind = file.loc(db).kind;
}
HirFileId::FileId(file_id) => break file_id,
}
@@ -797,16 +791,16 @@ impl MacroCallKind {
// FIXME: can be expensive to create, we should check the use sites and maybe replace them with
// simpler function calls if the map is only used once
#[derive(Clone, Debug, PartialEq, Eq)]
-pub struct ExpansionInfo {
+pub struct ExpansionInfo<'db> {
expanded: InMacroFile<SyntaxNode>,
/// The argument TokenTree or item for attributes
arg: InFile<Option<SyntaxNode>>,
- exp_map: Arc<ExpansionSpanMap>,
- arg_map: SpanMap,
+ exp_map: &'db ExpansionSpanMap,
+ arg_map: SpanMap<'db>,
loc: MacroCallLoc,
}
-impl ExpansionInfo {
+impl<'db> ExpansionInfo<'db> {
pub fn expanded(&self) -> InMacroFile<SyntaxNode> {
self.expanded.clone()
}
@@ -872,7 +866,7 @@ impl ExpansionInfo {
offset: TextSize,
) -> (FileRange, SyntaxContext) {
debug_assert!(self.expanded.value.text_range().contains(offset));
- span_for_offset(db, &self.exp_map, offset)
+ span_for_offset(db, self.exp_map, offset)
}
/// Maps up the text range out of the expansion hierarchy back into the original file its from.
@@ -882,7 +876,7 @@ impl ExpansionInfo {
range: TextRange,
) -> Option<(FileRange, SyntaxContext)> {
debug_assert!(self.expanded.value.text_range().contains_range(range));
- map_node_range_up(db, &self.exp_map, range)
+ map_node_range_up(db, self.exp_map, range)
}
/// Maps up the text range out of the expansion into its macro call.
@@ -918,14 +912,14 @@ impl ExpansionInfo {
}
}
- pub fn new(db: &dyn ExpandDatabase, macro_file: MacroCallId) -> ExpansionInfo {
+ pub fn new(db: &'db dyn ExpandDatabase, macro_file: MacroCallId) -> ExpansionInfo<'db> {
let _p = tracing::info_span!("ExpansionInfo::new").entered();
- let loc = db.lookup_intern_macro_call(macro_file);
+ let loc = macro_file.loc(db);
let arg_tt = loc.kind.arg(db);
let arg_map = db.span_map(arg_tt.file_id);
- let (parse, exp_map) = db.parse_macro_expansion(macro_file).value;
+ let (parse, exp_map) = &db.parse_macro_expansion(macro_file).value;
let expanded = InMacroFile { file_id: macro_file, value: parse.syntax_node() };
ExpansionInfo { expanded, loc, arg: arg_tt, exp_map, arg_map }
@@ -1054,6 +1048,11 @@ impl ExpandTo {
intern::impl_internable!(ModPath);
+/// Macro ids. That's probably the tricksiest bit in rust-analyzer, and the
+/// reason why we use salsa at all.
+///
+/// We encode macro definitions into ids of macro calls, this what allows us
+/// to be incremental.
#[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)]
#[doc(alias = "MacroFileId")]
pub struct MacroCallId {