Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-expand/src/db.rs')
| -rw-r--r-- | crates/hir-expand/src/db.rs | 67 |
1 files changed, 59 insertions, 8 deletions
diff --git a/crates/hir-expand/src/db.rs b/crates/hir-expand/src/db.rs index dab9d5d560..4585a532ab 100644 --- a/crates/hir-expand/src/db.rs +++ b/crates/hir-expand/src/db.rs @@ -1,8 +1,10 @@ //! Defines database & queries for macro expansion. +use std::sync::OnceLock; + use base_db::{ salsa::{self, debug::DebugQueryTable}, - CrateId, Edition, FileId, SourceDatabase, + CrateId, Edition, FileId, SourceDatabase, VersionReq, }; use either::Either; use limit::Limit; @@ -45,6 +47,9 @@ pub struct DeclarativeMacroExpander { pub transparency: Transparency, } +// FIXME: Remove this once we drop support for 1.76 +static REQUIREMENT: OnceLock<VersionReq> = OnceLock::new(); + impl DeclarativeMacroExpander { pub fn expand( &self, @@ -52,6 +57,18 @@ impl DeclarativeMacroExpander { tt: tt::Subtree, call_id: MacroCallId, ) -> ExpandResult<tt::Subtree> { + let toolchain = &db.crate_graph()[db.lookup_intern_macro_call(call_id).def.krate].toolchain; + let new_meta_vars = toolchain.as_ref().map_or(false, |version| { + REQUIREMENT.get_or_init(|| VersionReq::parse(">=1.76").unwrap()).matches( + &base_db::Version { + pre: base_db::Prerelease::EMPTY, + build: base_db::BuildMetadata::EMPTY, + major: version.major, + minor: version.minor, + patch: version.patch, + }, + ) + }); match self.mac.err() { Some(e) => ExpandResult::new( tt::Subtree::empty(tt::DelimSpan::DUMMY), @@ -59,18 +76,39 @@ impl DeclarativeMacroExpander { ), None => self .mac - .expand(&tt, |s| s.ctx = apply_mark(db, s.ctx, call_id, self.transparency)) + .expand( + &tt, + |s| s.ctx = apply_mark(db, s.ctx, call_id, self.transparency), + new_meta_vars, + ) .map_err(Into::into), } } - pub fn expand_unhygienic(&self, tt: tt::Subtree) -> ExpandResult<tt::Subtree> { + pub fn expand_unhygienic( + &self, + db: &dyn ExpandDatabase, + tt: tt::Subtree, + krate: CrateId, + ) -> ExpandResult<tt::Subtree> { + let toolchain = &db.crate_graph()[krate].toolchain; + let new_meta_vars = toolchain.as_ref().map_or(false, |version| { + REQUIREMENT.get_or_init(|| VersionReq::parse(">=1.76").unwrap()).matches( + &base_db::Version { + pre: base_db::Prerelease::EMPTY, + build: base_db::BuildMetadata::EMPTY, + major: version.major, + minor: version.minor, + patch: version.patch, + }, + ) + }); match self.mac.err() { Some(e) => ExpandResult::new( tt::Subtree::empty(tt::DelimSpan::DUMMY), ExpandError::other(format!("invalid macro definition: {e}")), ), - None => self.mac.expand(&tt, |_| ()).map_err(Into::into), + None => self.mac.expand(&tt, |_| (), new_meta_vars).map_err(Into::into), } } } @@ -278,7 +316,7 @@ pub fn expand_speculative( expander.expand(db, actual_macro_call, &adt, span_map) } MacroDefKind::Declarative(it) => { - db.decl_macro_expander(loc.krate, it).expand_unhygienic(tt) + db.decl_macro_expander(loc.krate, it).expand_unhygienic(db, tt, loc.def.krate) } MacroDefKind::BuiltIn(it, _) => it.expand(db, actual_macro_call, &tt).map_err(Into::into), MacroDefKind::BuiltInEager(it, _) => { @@ -525,7 +563,8 @@ fn decl_macro_expander( def_crate: CrateId, id: AstId<ast::Macro>, ) -> Arc<DeclarativeMacroExpander> { - let is_2021 = db.crate_graph()[def_crate].edition >= Edition::Edition2021; + let crate_data = &db.crate_graph()[def_crate]; + let is_2021 = crate_data.edition >= Edition::Edition2021; let (root, map) = parse_with_map(db, id.file_id); let root = root.syntax_node(); @@ -549,13 +588,25 @@ fn decl_macro_expander( _ => None, } }; + let toolchain = crate_data.toolchain.as_ref(); + let new_meta_vars = toolchain.as_ref().map_or(false, |version| { + REQUIREMENT.get_or_init(|| VersionReq::parse(">=1.76").unwrap()).matches( + &base_db::Version { + pre: base_db::Prerelease::EMPTY, + build: base_db::BuildMetadata::EMPTY, + major: version.major, + minor: version.minor, + patch: version.patch, + }, + ) + }); let (mac, transparency) = match id.to_ptr(db).to_node(&root) { ast::Macro::MacroRules(macro_rules) => ( match macro_rules.token_tree() { Some(arg) => { let tt = mbe::syntax_node_to_token_tree(arg.syntax(), map.as_ref()); - let mac = mbe::DeclarativeMacro::parse_macro_rules(&tt, is_2021); + let mac = mbe::DeclarativeMacro::parse_macro_rules(&tt, is_2021, new_meta_vars); mac } None => mbe::DeclarativeMacro::from_err( @@ -569,7 +620,7 @@ fn decl_macro_expander( match macro_def.body() { Some(arg) => { let tt = mbe::syntax_node_to_token_tree(arg.syntax(), map.as_ref()); - let mac = mbe::DeclarativeMacro::parse_macro2(&tt, is_2021); + let mac = mbe::DeclarativeMacro::parse_macro2(&tt, is_2021, new_meta_vars); mac } None => mbe::DeclarativeMacro::from_err( |