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.rs | 354 |
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) + } +} |