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.rs354
1 files changed, 196 insertions, 158 deletions
diff --git a/crates/hir-expand/src/lib.rs b/crates/hir-expand/src/lib.rs
index c1d808cbf2..f0a9a2ad52 100644
--- a/crates/hir-expand/src/lib.rs
+++ b/crates/hir-expand/src/lib.rs
@@ -27,28 +27,26 @@ mod prettify_macro_expansion_;
use attrs::collect_attrs;
use rustc_hash::FxHashMap;
+use salsa::plumbing::{AsId, FromId};
use stdx::TupleExt;
use triomphe::Arc;
use core::fmt;
use std::hash::Hash;
-use base_db::{ra_salsa::InternValueTrivial, CrateId};
+use base_db::Crate;
use either::Either;
-use span::{
- Edition, EditionedFileId, ErasedFileAstId, FileAstId, HirFileIdRepr, Span, SpanAnchor,
- SyntaxContextData, SyntaxContextId,
-};
+use span::{Edition, ErasedFileAstId, FileAstId, Span, SpanAnchor, SyntaxContext};
use syntax::{
- ast::{self, AstNode},
SyntaxNode, SyntaxToken, TextRange, TextSize,
+ ast::{self, AstNode},
};
use crate::{
attrs::AttrId,
builtin::{
- include_input_to_file_id, BuiltinAttrExpander, BuiltinDeriveExpander,
- BuiltinFnLikeExpander, EagerExpander,
+ BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerExpander,
+ include_input_to_file_id,
},
db::ExpandDatabase,
mod_path::ModPath,
@@ -62,12 +60,12 @@ pub use crate::{
prettify_macro_expansion_::prettify_macro_expansion,
};
+pub use base_db::EditionedFileId;
pub use mbe::{DeclarativeMacro, ValueResult};
-pub use span::{HirFileId, MacroCallId, MacroFileId};
pub mod tt {
pub use span::Span;
- pub use tt::{token_to_literal, DelimiterKind, IdentIsRaw, LitKind, Spacing};
+ pub use tt::{DelimiterKind, IdentIsRaw, LitKind, Spacing, token_to_literal};
pub type Delimiter = ::tt::Delimiter<Span>;
pub type DelimSpan = ::tt::DelimSpan<Span>;
@@ -89,17 +87,17 @@ pub mod tt {
macro_rules! impl_intern_lookup {
($db:ident, $id:ident, $loc:ident, $intern:ident, $lookup:ident) => {
impl $crate::Intern for $loc {
- type Database<'db> = dyn $db + 'db;
+ type Database = dyn $db;
type ID = $id;
- fn intern(self, db: &Self::Database<'_>) -> $id {
+ fn intern(self, db: &Self::Database) -> Self::ID {
db.$intern(self)
}
}
impl $crate::Lookup for $id {
- type Database<'db> = dyn $db + 'db;
+ type Database = dyn $db;
type Data = $loc;
- fn lookup(&self, db: &Self::Database<'_>) -> $loc {
+ fn lookup(&self, db: &Self::Database) -> Self::Data {
db.$lookup(*self)
}
}
@@ -108,15 +106,15 @@ macro_rules! impl_intern_lookup {
// ideally these would be defined in base-db, but the orphan rule doesn't let us
pub trait Intern {
- type Database<'db>: ?Sized;
+ type Database: ?Sized;
type ID;
- fn intern(self, db: &Self::Database<'_>) -> Self::ID;
+ fn intern(self, db: &Self::Database) -> Self::ID;
}
pub trait Lookup {
- type Database<'db>: ?Sized;
+ type Database: ?Sized;
type Data;
- fn lookup(&self, db: &Self::Database<'_>) -> Self::Data;
+ fn lookup(&self, db: &Self::Database) -> Self::Data;
}
impl_intern_lookup!(
@@ -127,14 +125,6 @@ impl_intern_lookup!(
lookup_intern_macro_call
);
-impl_intern_lookup!(
- ExpandDatabase,
- SyntaxContextId,
- SyntaxContextData,
- intern_syntax_context,
- lookup_intern_syntax_context
-);
-
pub type ExpandResult<T> = ValueResult<T, ExpandError>;
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
@@ -165,7 +155,7 @@ impl ExpandError {
pub enum ExpandErrorKind {
/// Attribute macro expansion is disabled.
ProcMacroAttrExpansionDisabled,
- MissingProcMacroExpander(CrateId),
+ MissingProcMacroExpander(Crate),
/// The macro for this call is disabled.
MacroDisabled,
/// The macro definition has errors.
@@ -208,14 +198,17 @@ impl ExpandErrorKind {
kind: RenderedExpandError::DISABLED,
},
&ExpandErrorKind::MissingProcMacroExpander(def_crate) => {
- match db.proc_macros().get_error_for_crate(def_crate) {
+ match db.proc_macros_for_crate(def_crate).as_ref().and_then(|it| it.get_error()) {
Some((e, hard_err)) => RenderedExpandError {
message: e.to_owned(),
error: hard_err,
kind: RenderedExpandError::GENERAL_KIND,
},
None => RenderedExpandError {
- message: format!("internal error: proc-macro map is missing error entry for crate {def_crate:?}"),
+ message: format!(
+ "internal error: proc-macro map is missing error entry for crate {:?}",
+ def_crate
+ ),
error: true,
kind: RenderedExpandError::GENERAL_KIND,
},
@@ -258,15 +251,14 @@ impl From<mbe::ExpandError> for ExpandError {
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct MacroCallLoc {
pub def: MacroDefId,
- pub krate: CrateId,
+ pub krate: Crate,
pub kind: MacroCallKind,
- pub ctxt: SyntaxContextId,
+ pub ctxt: SyntaxContext,
}
-impl InternValueTrivial for MacroCallLoc {}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct MacroDefId {
- pub krate: CrateId,
+ pub krate: Crate,
pub edition: Edition,
pub kind: MacroDefKind,
pub local_inner: bool,
@@ -288,6 +280,17 @@ impl MacroDefKind {
pub fn is_declarative(&self) -> bool {
matches!(self, MacroDefKind::Declarative(..))
}
+
+ pub fn erased_ast_id(&self) -> ErasedAstId {
+ match *self {
+ MacroDefKind::ProcMacro(id, ..) => id.erase(),
+ MacroDefKind::BuiltIn(id, _)
+ | MacroDefKind::BuiltInAttr(id, _)
+ | MacroDefKind::BuiltInDerive(id, _)
+ | MacroDefKind::BuiltInEager(id, _)
+ | MacroDefKind::Declarative(id, ..) => id.erase(),
+ }
+ }
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -338,51 +341,34 @@ pub enum MacroCallKind {
},
}
-pub trait HirFileIdExt {
- fn edition(self, db: &dyn ExpandDatabase) -> Edition;
- /// Returns the original file of this macro call hierarchy.
- fn original_file(self, db: &dyn ExpandDatabase) -> EditionedFileId;
-
- /// Returns the original file of this macro call hierarchy while going into the included file if
- /// one of the calls comes from an `include!``.
- fn original_file_respecting_includes(self, db: &dyn ExpandDatabase) -> EditionedFileId;
-
- /// If this is a macro call, returns the syntax node of the very first macro call this file resides in.
- fn original_call_node(self, db: &dyn ExpandDatabase) -> Option<InRealFile<SyntaxNode>>;
-
- fn as_builtin_derive_attr_node(&self, db: &dyn ExpandDatabase) -> Option<InFile<ast::Attr>>;
-}
-
-impl HirFileIdExt for HirFileId {
- fn edition(self, db: &dyn ExpandDatabase) -> Edition {
- match self.repr() {
- HirFileIdRepr::FileId(file_id) => file_id.edition(),
- HirFileIdRepr::MacroFile(m) => m.macro_call_id.lookup(db).def.edition,
+impl HirFileId {
+ pub fn edition(self, db: &dyn ExpandDatabase) -> Edition {
+ match self {
+ HirFileId::FileId(file_id) => file_id.editioned_file_id(db).edition(),
+ HirFileId::MacroFile(m) => db.lookup_intern_macro_call(m).def.edition,
}
}
- fn original_file(self, db: &dyn ExpandDatabase) -> EditionedFileId {
+ pub fn original_file(self, db: &dyn ExpandDatabase) -> EditionedFileId {
let mut file_id = self;
loop {
- match file_id.repr() {
- HirFileIdRepr::FileId(id) => break id,
- HirFileIdRepr::MacroFile(MacroFileId { macro_call_id }) => {
- file_id = macro_call_id.lookup(db).kind.file_id();
+ 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()
}
}
}
}
- fn original_file_respecting_includes(mut self, db: &dyn ExpandDatabase) -> EditionedFileId {
+ pub fn original_file_respecting_includes(mut self, db: &dyn ExpandDatabase) -> EditionedFileId {
loop {
- match self.repr() {
- HirFileIdRepr::FileId(id) => break id,
- HirFileIdRepr::MacroFile(file) => {
- let loc = db.lookup_intern_macro_call(file.macro_call_id);
+ match self {
+ HirFileId::FileId(id) => break id,
+ HirFileId::MacroFile(file) => {
+ let loc = db.lookup_intern_macro_call(file);
if loc.def.is_include() {
if let MacroCallKind::FnLike { eager: Some(eager), .. } = &loc.kind {
- if let Ok(it) =
- include_input_to_file_id(db, file.macro_call_id, &eager.arg)
- {
+ if let Ok(it) = include_input_to_file_id(db, file, &eager.arg) {
break it;
}
}
@@ -393,23 +379,26 @@ impl HirFileIdExt for HirFileId {
}
}
- fn original_call_node(self, db: &dyn ExpandDatabase) -> Option<InRealFile<SyntaxNode>> {
- let mut call = db.lookup_intern_macro_call(self.macro_file()?.macro_call_id).to_node(db);
+ 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);
loop {
- match call.file_id.repr() {
- HirFileIdRepr::FileId(file_id) => {
- break Some(InRealFile { file_id, value: call.value })
+ match call.file_id {
+ HirFileId::FileId(file_id) => {
+ break Some(InRealFile { file_id, value: call.value });
}
- HirFileIdRepr::MacroFile(MacroFileId { macro_call_id }) => {
+ HirFileId::MacroFile(macro_call_id) => {
call = db.lookup_intern_macro_call(macro_call_id).to_node(db);
}
}
}
}
- fn as_builtin_derive_attr_node(&self, db: &dyn ExpandDatabase) -> Option<InFile<ast::Attr>> {
+ pub fn as_builtin_derive_attr_node(
+ &self,
+ db: &dyn ExpandDatabase,
+ ) -> Option<InFile<ast::Attr>> {
let macro_file = self.macro_file()?;
- let loc: MacroCallLoc = db.lookup_intern_macro_call(macro_file.macro_call_id);
+ let loc = db.lookup_intern_macro_call(macro_file);
let attr = match loc.def.kind {
MacroDefKind::BuiltInDerive(..) => loc.to_node(db),
_ => return None,
@@ -436,57 +425,34 @@ pub enum MacroKind {
ProcMacro,
}
-pub trait MacroFileIdExt {
- fn is_env_or_option_env(&self, db: &dyn ExpandDatabase) -> bool;
- fn is_include_like_macro(&self, db: &dyn ExpandDatabase) -> bool;
- fn eager_arg(&self, db: &dyn ExpandDatabase) -> Option<MacroCallId>;
- fn expansion_level(self, db: &dyn ExpandDatabase) -> u32;
- /// If this is a macro call, returns the syntax node of the call.
- fn call_node(self, db: &dyn ExpandDatabase) -> InFile<SyntaxNode>;
- fn parent(self, db: &dyn ExpandDatabase) -> HirFileId;
-
- fn expansion_info(self, db: &dyn ExpandDatabase) -> ExpansionInfo;
-
- fn kind(&self, db: &dyn ExpandDatabase) -> MacroKind;
-
- /// Return whether this file is an include macro
- fn is_include_macro(&self, db: &dyn ExpandDatabase) -> bool;
-
- fn is_eager(&self, db: &dyn ExpandDatabase) -> bool;
-
- /// Return whether this file is the pseudo expansion of the derive attribute.
- /// See [`crate::builtin_attr_macro::derive_attr_expand`].
- fn is_derive_attr_pseudo_expansion(&self, db: &dyn ExpandDatabase) -> bool;
-}
-
-impl MacroFileIdExt for MacroFileId {
- fn call_node(self, db: &dyn ExpandDatabase) -> InFile<SyntaxNode> {
- db.lookup_intern_macro_call(self.macro_call_id).to_node(db)
+impl MacroCallId {
+ pub fn call_node(self, db: &dyn ExpandDatabase) -> InFile<SyntaxNode> {
+ db.lookup_intern_macro_call(self).to_node(db)
}
- fn expansion_level(self, db: &dyn ExpandDatabase) -> u32 {
+ pub fn expansion_level(self, db: &dyn ExpandDatabase) -> u32 {
let mut level = 0;
let mut macro_file = self;
loop {
- let loc: MacroCallLoc = db.lookup_intern_macro_call(macro_file.macro_call_id);
+ let loc = db.lookup_intern_macro_call(macro_file);
level += 1;
- macro_file = match loc.kind.file_id().repr() {
- HirFileIdRepr::FileId(_) => break level,
- HirFileIdRepr::MacroFile(it) => it,
+ macro_file = match loc.kind.file_id() {
+ HirFileId::FileId(_) => break level,
+ HirFileId::MacroFile(it) => it,
};
}
}
- fn parent(self, db: &dyn ExpandDatabase) -> HirFileId {
- self.macro_call_id.lookup(db).kind.file_id()
+ pub fn parent(self, db: &dyn ExpandDatabase) -> HirFileId {
+ db.lookup_intern_macro_call(self).kind.file_id()
}
/// Return expansion information if it is a macro-expansion file
- fn expansion_info(self, db: &dyn ExpandDatabase) -> ExpansionInfo {
+ pub fn expansion_info(self, db: &dyn ExpandDatabase) -> ExpansionInfo {
ExpansionInfo::new(db, self)
}
- fn kind(&self, db: &dyn ExpandDatabase) -> MacroKind {
- match db.lookup_intern_macro_call(self.macro_call_id).def.kind {
+ pub fn kind(self, db: &dyn ExpandDatabase) -> MacroKind {
+ match db.lookup_intern_macro_call(self).def.kind {
MacroDefKind::Declarative(..) => MacroKind::Declarative,
MacroDefKind::BuiltIn(..) | MacroDefKind::BuiltInEager(..) => {
MacroKind::DeclarativeBuiltIn
@@ -499,33 +465,33 @@ impl MacroFileIdExt for MacroFileId {
}
}
- fn is_include_macro(&self, db: &dyn ExpandDatabase) -> bool {
- db.lookup_intern_macro_call(self.macro_call_id).def.is_include()
+ pub fn is_include_macro(self, db: &dyn ExpandDatabase) -> bool {
+ db.lookup_intern_macro_call(self).def.is_include()
}
- fn is_include_like_macro(&self, db: &dyn ExpandDatabase) -> bool {
- db.lookup_intern_macro_call(self.macro_call_id).def.is_include_like()
+ pub fn is_include_like_macro(self, db: &dyn ExpandDatabase) -> bool {
+ db.lookup_intern_macro_call(self).def.is_include_like()
}
- fn is_env_or_option_env(&self, db: &dyn ExpandDatabase) -> bool {
- db.lookup_intern_macro_call(self.macro_call_id).def.is_env_or_option_env()
+ pub fn is_env_or_option_env(self, db: &dyn ExpandDatabase) -> bool {
+ db.lookup_intern_macro_call(self).def.is_env_or_option_env()
}
- fn is_eager(&self, db: &dyn ExpandDatabase) -> bool {
- let loc = db.lookup_intern_macro_call(self.macro_call_id);
+ pub fn is_eager(self, db: &dyn ExpandDatabase) -> bool {
+ let loc = db.lookup_intern_macro_call(self);
matches!(loc.def.kind, MacroDefKind::BuiltInEager(..))
}
- fn eager_arg(&self, db: &dyn ExpandDatabase) -> Option<MacroCallId> {
- let loc = db.lookup_intern_macro_call(self.macro_call_id);
+ pub fn eager_arg(self, db: &dyn ExpandDatabase) -> Option<MacroCallId> {
+ let loc = db.lookup_intern_macro_call(self);
match &loc.kind {
MacroCallKind::FnLike { eager, .. } => eager.as_ref().map(|it| it.arg_id),
_ => None,
}
}
- fn is_derive_attr_pseudo_expansion(&self, db: &dyn ExpandDatabase) -> bool {
- let loc = db.lookup_intern_macro_call(self.macro_call_id);
+ pub fn is_derive_attr_pseudo_expansion(self, db: &dyn ExpandDatabase) -> bool {
+ let loc = db.lookup_intern_macro_call(self);
loc.def.is_attribute_derive()
}
}
@@ -534,11 +500,11 @@ impl MacroDefId {
pub fn make_call(
self,
db: &dyn ExpandDatabase,
- krate: CrateId,
+ krate: Crate,
kind: MacroCallKind,
- ctxt: SyntaxContextId,
+ ctxt: SyntaxContext,
) -> MacroCallId {
- MacroCallLoc { def: self, krate, kind, ctxt }.intern(db)
+ db.intern_macro_call(MacroCallLoc { def: self, krate, kind, ctxt })
}
pub fn definition_range(&self, db: &dyn ExpandDatabase) -> InFile<TextRange> {
@@ -692,7 +658,7 @@ impl MacroCallLoc {
}
impl MacroCallKind {
- fn descr(&self) -> &'static str {
+ pub fn descr(&self) -> &'static str {
match self {
MacroCallKind::FnLike { .. } => "macro call",
MacroCallKind::Derive { .. } => "derive macro",
@@ -723,11 +689,11 @@ impl MacroCallKind {
pub fn original_call_range_with_body(self, db: &dyn ExpandDatabase) -> FileRange {
let mut kind = self;
let file_id = loop {
- match kind.file_id().repr() {
- HirFileIdRepr::MacroFile(file) => {
- kind = db.lookup_intern_macro_call(file.macro_call_id).kind;
+ match kind.file_id() {
+ HirFileId::MacroFile(file) => {
+ kind = db.lookup_intern_macro_call(file).kind;
}
- HirFileIdRepr::FileId(file_id) => break file_id,
+ HirFileId::FileId(file_id) => break file_id,
}
};
@@ -748,11 +714,11 @@ impl MacroCallKind {
pub fn original_call_range(self, db: &dyn ExpandDatabase) -> FileRange {
let mut kind = self;
let file_id = loop {
- match kind.file_id().repr() {
- HirFileIdRepr::MacroFile(file) => {
- kind = db.lookup_intern_macro_call(file.macro_call_id).kind;
+ match kind.file_id() {
+ HirFileId::MacroFile(file) => {
+ kind = db.lookup_intern_macro_call(file).kind;
}
- HirFileIdRepr::FileId(file_id) => break file_id,
+ HirFileId::FileId(file_id) => break file_id,
}
};
@@ -840,7 +806,7 @@ impl ExpansionInfo {
pub fn map_range_down_exact(
&self,
span: Span,
- ) -> Option<InMacroFile<impl Iterator<Item = (SyntaxToken, SyntaxContextId)> + '_>> {
+ ) -> Option<InMacroFile<impl Iterator<Item = (SyntaxToken, SyntaxContext)> + '_>> {
let tokens = self.exp_map.ranges_with_span_exact(span).flat_map(move |(range, ctx)| {
self.expanded.value.covering_element(range).into_token().zip(Some(ctx))
});
@@ -855,7 +821,7 @@ impl ExpansionInfo {
pub fn map_range_down(
&self,
span: Span,
- ) -> Option<InMacroFile<impl Iterator<Item = (SyntaxToken, SyntaxContextId)> + '_>> {
+ ) -> Option<InMacroFile<impl Iterator<Item = (SyntaxToken, SyntaxContext)> + '_>> {
let tokens = self.exp_map.ranges_with_span(span).flat_map(move |(range, ctx)| {
self.expanded.value.covering_element(range).into_token().zip(Some(ctx))
});
@@ -868,7 +834,7 @@ impl ExpansionInfo {
&self,
db: &dyn ExpandDatabase,
offset: TextSize,
- ) -> (FileRange, SyntaxContextId) {
+ ) -> (FileRange, SyntaxContext) {
debug_assert!(self.expanded.value.text_range().contains(offset));
span_for_offset(db, &self.exp_map, offset)
}
@@ -878,7 +844,7 @@ impl ExpansionInfo {
&self,
db: &dyn ExpandDatabase,
range: TextRange,
- ) -> Option<(FileRange, SyntaxContextId)> {
+ ) -> Option<(FileRange, SyntaxContext)> {
debug_assert!(self.expanded.value.text_range().contains_range(range));
map_node_range_up(db, &self.exp_map, range)
}
@@ -893,7 +859,7 @@ impl ExpansionInfo {
let span = self.exp_map.span_at(token.start());
match &self.arg_map {
SpanMap::RealSpanMap(_) => {
- let file_id = span.anchor.file_id.into();
+ let file_id = EditionedFileId::from_span(db, span.anchor.file_id).into();
let anchor_offset =
db.ast_id_map(file_id).get_erased(span.anchor.ast_id).text_range().start();
InFile { file_id, value: smallvec::smallvec![span.range + anchor_offset] }
@@ -916,9 +882,9 @@ impl ExpansionInfo {
}
}
- pub fn new(db: &dyn ExpandDatabase, macro_file: MacroFileId) -> ExpansionInfo {
+ pub fn new(db: &dyn ExpandDatabase, macro_file: MacroCallId) -> ExpansionInfo {
let _p = tracing::info_span!("ExpansionInfo::new").entered();
- let loc = db.lookup_intern_macro_call(macro_file.macro_call_id);
+ let loc = db.lookup_intern_macro_call(macro_file);
let arg_tt = loc.kind.arg(db);
let arg_map = db.span_map(arg_tt.file_id);
@@ -950,9 +916,10 @@ pub fn map_node_range_up_rooted(
start = start.min(span.range.start());
end = end.max(span.range.end());
}
+ let file_id = EditionedFileId::from_span(db, anchor.file_id);
let anchor_offset =
- db.ast_id_map(anchor.file_id.into()).get_erased(anchor.ast_id).text_range().start();
- Some(FileRange { file_id: anchor.file_id, range: TextRange::new(start, end) + anchor_offset })
+ db.ast_id_map(file_id.into()).get_erased(anchor.ast_id).text_range().start();
+ Some(FileRange { file_id, range: TextRange::new(start, end) + anchor_offset })
}
/// Maps up the text range out of the expansion hierarchy back into the original file its from.
@@ -962,7 +929,7 @@ pub fn map_node_range_up(
db: &dyn ExpandDatabase,
exp_map: &ExpansionSpanMap,
range: TextRange,
-) -> Option<(FileRange, SyntaxContextId)> {
+) -> Option<(FileRange, SyntaxContext)> {
let mut spans = exp_map.spans_for_range(range);
let Span { range, anchor, ctx } = spans.next()?;
let mut start = range.start();
@@ -975,12 +942,10 @@ pub fn map_node_range_up(
start = start.min(span.range.start());
end = end.max(span.range.end());
}
+ let file_id = EditionedFileId::from_span(db, anchor.file_id);
let anchor_offset =
- db.ast_id_map(anchor.file_id.into()).get_erased(anchor.ast_id).text_range().start();
- Some((
- FileRange { file_id: anchor.file_id, range: TextRange::new(start, end) + anchor_offset },
- ctx,
- ))
+ db.ast_id_map(file_id.into()).get_erased(anchor.ast_id).text_range().start();
+ Some((FileRange { file_id, range: TextRange::new(start, end) + anchor_offset }, ctx))
}
/// Maps up the text range out of the expansion hierarchy back into the original file its from.
@@ -989,7 +954,7 @@ pub fn map_node_range_up_aggregated(
db: &dyn ExpandDatabase,
exp_map: &ExpansionSpanMap,
range: TextRange,
-) -> FxHashMap<(SpanAnchor, SyntaxContextId), TextRange> {
+) -> FxHashMap<(SpanAnchor, SyntaxContext), TextRange> {
let mut map = FxHashMap::default();
for span in exp_map.spans_for_range(range) {
let range = map.entry((span.anchor, span.ctx)).or_insert_with(|| span.range);
@@ -999,8 +964,9 @@ pub fn map_node_range_up_aggregated(
);
}
for ((anchor, _), range) in &mut map {
+ let file_id = EditionedFileId::from_span(db, anchor.file_id);
let anchor_offset =
- db.ast_id_map(anchor.file_id.into()).get_erased(anchor.ast_id).text_range().start();
+ db.ast_id_map(file_id.into()).get_erased(anchor.ast_id).text_range().start();
*range += anchor_offset;
}
map
@@ -1011,14 +977,12 @@ pub fn span_for_offset(
db: &dyn ExpandDatabase,
exp_map: &ExpansionSpanMap,
offset: TextSize,
-) -> (FileRange, SyntaxContextId) {
+) -> (FileRange, SyntaxContext) {
let span = exp_map.span_at(offset);
- let anchor_offset = db
- .ast_id_map(span.anchor.file_id.into())
- .get_erased(span.anchor.ast_id)
- .text_range()
- .start();
- (FileRange { file_id: span.anchor.file_id, range: span.range + anchor_offset }, span.ctx)
+ let file_id = EditionedFileId::from_span(db, span.anchor.file_id);
+ let anchor_offset =
+ db.ast_id_map(file_id.into()).get_erased(span.anchor.ast_id).text_range().start();
+ (FileRange { file_id, range: span.range + anchor_offset }, span.ctx)
}
/// In Rust, macros expand token trees to token trees. When we want to turn a
@@ -1086,3 +1050,77 @@ impl ExpandTo {
}
intern::impl_internable!(ModPath, attrs::AttrInput);
+
+#[salsa::interned(no_lifetime, debug)]
+#[doc(alias = "MacroFileId")]
+pub struct MacroCallId {
+ pub loc: MacroCallLoc,
+}
+
+impl From<span::MacroCallId> for MacroCallId {
+ #[inline]
+ fn from(value: span::MacroCallId) -> Self {
+ MacroCallId::from_id(value.0)
+ }
+}
+
+impl From<MacroCallId> for span::MacroCallId {
+ #[inline]
+ fn from(value: MacroCallId) -> span::MacroCallId {
+ span::MacroCallId(value.as_id())
+ }
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)]
+pub enum HirFileId {
+ FileId(EditionedFileId),
+ MacroFile(MacroCallId),
+}
+
+impl From<EditionedFileId> for HirFileId {
+ #[inline]
+ fn from(file_id: EditionedFileId) -> Self {
+ HirFileId::FileId(file_id)
+ }
+}
+
+impl From<MacroCallId> for HirFileId {
+ #[inline]
+ fn from(file_id: MacroCallId) -> Self {
+ HirFileId::MacroFile(file_id)
+ }
+}
+
+impl HirFileId {
+ #[inline]
+ pub fn macro_file(self) -> Option<MacroCallId> {
+ match self {
+ HirFileId::FileId(_) => None,
+ HirFileId::MacroFile(it) => Some(it),
+ }
+ }
+
+ #[inline]
+ pub fn is_macro(self) -> bool {
+ matches!(self, HirFileId::MacroFile(_))
+ }
+
+ #[inline]
+ pub fn file_id(self) -> Option<EditionedFileId> {
+ match self {
+ HirFileId::FileId(it) => Some(it),
+ HirFileId::MacroFile(_) => None,
+ }
+ }
+}
+
+impl PartialEq<EditionedFileId> for HirFileId {
+ fn eq(&self, &other: &EditionedFileId) -> bool {
+ *self == HirFileId::from(other)
+ }
+}
+impl PartialEq<HirFileId> for EditionedFileId {
+ fn eq(&self, &other: &HirFileId) -> bool {
+ other == HirFileId::from(*self)
+ }
+}