11//! Defines database & queries for macro expansion.
22
3+ use std:: sync:: OnceLock ;
4+
35use base_db:: {
46 salsa:: { self , debug:: DebugQueryTable } ,
5- CrateId , Edition , FileId , SourceDatabase ,
7+ CrateId , Edition , FileId , SourceDatabase , VersionReq ,
68} ;
79use either:: Either ;
810use limit:: Limit ;
@@ -45,32 +47,68 @@ pub struct DeclarativeMacroExpander {
4547 pub transparency : Transparency ,
4648}
4749
50+ // FIXME: Remove this once we drop support for 1.76
51+ static REQUIREMENT : OnceLock < VersionReq > = OnceLock :: new ( ) ;
52+
4853impl DeclarativeMacroExpander {
4954 pub fn expand (
5055 & self ,
5156 db : & dyn ExpandDatabase ,
5257 tt : tt:: Subtree ,
5358 call_id : MacroCallId ,
5459 ) -> ExpandResult < tt:: Subtree > {
60+ let toolchain = & db. crate_graph ( ) [ db. lookup_intern_macro_call ( call_id) . def . krate ] . toolchain ;
61+ let new_meta_vars = toolchain. as_ref ( ) . map_or ( false , |version| {
62+ REQUIREMENT . get_or_init ( || VersionReq :: parse ( ">=1.76" ) . unwrap ( ) ) . matches (
63+ & base_db:: Version {
64+ pre : base_db:: Prerelease :: EMPTY ,
65+ build : base_db:: BuildMetadata :: EMPTY ,
66+ major : version. major ,
67+ minor : version. minor ,
68+ patch : version. patch ,
69+ } ,
70+ )
71+ } ) ;
5572 match self . mac . err ( ) {
5673 Some ( e) => ExpandResult :: new (
5774 tt:: Subtree :: empty ( tt:: DelimSpan :: DUMMY ) ,
5875 ExpandError :: other ( format ! ( "invalid macro definition: {e}" ) ) ,
5976 ) ,
6077 None => self
6178 . mac
62- . expand ( & tt, |s| s. ctx = apply_mark ( db, s. ctx , call_id, self . transparency ) )
79+ . expand (
80+ & tt,
81+ |s| s. ctx = apply_mark ( db, s. ctx , call_id, self . transparency ) ,
82+ new_meta_vars,
83+ )
6384 . map_err ( Into :: into) ,
6485 }
6586 }
6687
67- pub fn expand_unhygienic ( & self , tt : tt:: Subtree ) -> ExpandResult < tt:: Subtree > {
88+ pub fn expand_unhygienic (
89+ & self ,
90+ db : & dyn ExpandDatabase ,
91+ tt : tt:: Subtree ,
92+ krate : CrateId ,
93+ ) -> ExpandResult < tt:: Subtree > {
94+ let toolchain = & db. crate_graph ( ) [ krate] . toolchain ;
95+ let new_meta_vars = toolchain. as_ref ( ) . map_or ( false , |version| {
96+ REQUIREMENT . get_or_init ( || VersionReq :: parse ( ">=1.76" ) . unwrap ( ) ) . matches (
97+ & base_db:: Version {
98+ pre : base_db:: Prerelease :: EMPTY ,
99+ build : base_db:: BuildMetadata :: EMPTY ,
100+ major : version. major ,
101+ minor : version. minor ,
102+ patch : version. patch ,
103+ } ,
104+ )
105+ } ) ;
68106 match self . mac . err ( ) {
69107 Some ( e) => ExpandResult :: new (
70108 tt:: Subtree :: empty ( tt:: DelimSpan :: DUMMY ) ,
71109 ExpandError :: other ( format ! ( "invalid macro definition: {e}" ) ) ,
72110 ) ,
73- None => self . mac . expand ( & tt, |_| ( ) ) . map_err ( Into :: into) ,
111+ None => self . mac . expand ( & tt, |_| ( ) , new_meta_vars ) . map_err ( Into :: into) ,
74112 }
75113 }
76114}
@@ -278,7 +316,7 @@ pub fn expand_speculative(
278316 expander. expand ( db, actual_macro_call, & adt, span_map)
279317 }
280318 MacroDefKind :: Declarative ( it) => {
281- db. decl_macro_expander ( loc. krate , it) . expand_unhygienic ( tt )
319+ db. decl_macro_expander ( loc. krate , it) . expand_unhygienic ( db , tt , loc . def . krate )
282320 }
283321 MacroDefKind :: BuiltIn ( it, _) => it. expand ( db, actual_macro_call, & tt) . map_err ( Into :: into) ,
284322 MacroDefKind :: BuiltInEager ( it, _) => {
@@ -525,7 +563,8 @@ fn decl_macro_expander(
525563 def_crate : CrateId ,
526564 id : AstId < ast:: Macro > ,
527565) -> Arc < DeclarativeMacroExpander > {
528- let is_2021 = db. crate_graph ( ) [ def_crate] . edition >= Edition :: Edition2021 ;
566+ let crate_data = & db. crate_graph ( ) [ def_crate] ;
567+ let is_2021 = crate_data. edition >= Edition :: Edition2021 ;
529568 let ( root, map) = parse_with_map ( db, id. file_id ) ;
530569 let root = root. syntax_node ( ) ;
531570
@@ -549,13 +588,25 @@ fn decl_macro_expander(
549588 _ => None ,
550589 }
551590 } ;
591+ let toolchain = crate_data. toolchain . as_ref ( ) ;
592+ let new_meta_vars = toolchain. as_ref ( ) . map_or ( false , |version| {
593+ REQUIREMENT . get_or_init ( || VersionReq :: parse ( ">=1.76" ) . unwrap ( ) ) . matches (
594+ & base_db:: Version {
595+ pre : base_db:: Prerelease :: EMPTY ,
596+ build : base_db:: BuildMetadata :: EMPTY ,
597+ major : version. major ,
598+ minor : version. minor ,
599+ patch : version. patch ,
600+ } ,
601+ )
602+ } ) ;
552603
553604 let ( mac, transparency) = match id. to_ptr ( db) . to_node ( & root) {
554605 ast:: Macro :: MacroRules ( macro_rules) => (
555606 match macro_rules. token_tree ( ) {
556607 Some ( arg) => {
557608 let tt = mbe:: syntax_node_to_token_tree ( arg. syntax ( ) , map. as_ref ( ) ) ;
558- let mac = mbe:: DeclarativeMacro :: parse_macro_rules ( & tt, is_2021) ;
609+ let mac = mbe:: DeclarativeMacro :: parse_macro_rules ( & tt, is_2021, new_meta_vars ) ;
559610 mac
560611 }
561612 None => mbe:: DeclarativeMacro :: from_err (
@@ -569,7 +620,7 @@ fn decl_macro_expander(
569620 match macro_def. body ( ) {
570621 Some ( arg) => {
571622 let tt = mbe:: syntax_node_to_token_tree ( arg. syntax ( ) , map. as_ref ( ) ) ;
572- let mac = mbe:: DeclarativeMacro :: parse_macro2 ( & tt, is_2021) ;
623+ let mac = mbe:: DeclarativeMacro :: parse_macro2 ( & tt, is_2021, new_meta_vars ) ;
573624 mac
574625 }
575626 None => mbe:: DeclarativeMacro :: from_err (
0 commit comments