1
1
//! Defines database & queries for macro expansion.
2
2
3
+ use std:: sync:: OnceLock ;
4
+
3
5
use base_db:: {
4
6
salsa:: { self , debug:: DebugQueryTable } ,
5
- CrateId , Edition , FileId , SourceDatabase ,
7
+ CrateId , Edition , FileId , SourceDatabase , VersionReq ,
6
8
} ;
7
9
use either:: Either ;
8
10
use limit:: Limit ;
@@ -45,32 +47,68 @@ pub struct DeclarativeMacroExpander {
45
47
pub transparency : Transparency ,
46
48
}
47
49
50
+ // FIXME: Remove this once we drop support for 1.76
51
+ static REQUIREMENT : OnceLock < VersionReq > = OnceLock :: new ( ) ;
52
+
48
53
impl DeclarativeMacroExpander {
49
54
pub fn expand (
50
55
& self ,
51
56
db : & dyn ExpandDatabase ,
52
57
tt : tt:: Subtree ,
53
58
call_id : MacroCallId ,
54
59
) -> 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
+ } ) ;
55
72
match self . mac . err ( ) {
56
73
Some ( e) => ExpandResult :: new (
57
74
tt:: Subtree :: empty ( tt:: DelimSpan :: DUMMY ) ,
58
75
ExpandError :: other ( format ! ( "invalid macro definition: {e}" ) ) ,
59
76
) ,
60
77
None => self
61
78
. 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
+ )
63
84
. map_err ( Into :: into) ,
64
85
}
65
86
}
66
87
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
+ } ) ;
68
106
match self . mac . err ( ) {
69
107
Some ( e) => ExpandResult :: new (
70
108
tt:: Subtree :: empty ( tt:: DelimSpan :: DUMMY ) ,
71
109
ExpandError :: other ( format ! ( "invalid macro definition: {e}" ) ) ,
72
110
) ,
73
- None => self . mac . expand ( & tt, |_| ( ) ) . map_err ( Into :: into) ,
111
+ None => self . mac . expand ( & tt, |_| ( ) , new_meta_vars ) . map_err ( Into :: into) ,
74
112
}
75
113
}
76
114
}
@@ -278,7 +316,7 @@ pub fn expand_speculative(
278
316
expander. expand ( db, actual_macro_call, & adt, span_map)
279
317
}
280
318
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 )
282
320
}
283
321
MacroDefKind :: BuiltIn ( it, _) => it. expand ( db, actual_macro_call, & tt) . map_err ( Into :: into) ,
284
322
MacroDefKind :: BuiltInEager ( it, _) => {
@@ -525,7 +563,8 @@ fn decl_macro_expander(
525
563
def_crate : CrateId ,
526
564
id : AstId < ast:: Macro > ,
527
565
) -> 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 ;
529
568
let ( root, map) = parse_with_map ( db, id. file_id ) ;
530
569
let root = root. syntax_node ( ) ;
531
570
@@ -549,13 +588,25 @@ fn decl_macro_expander(
549
588
_ => None ,
550
589
}
551
590
} ;
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
+ } ) ;
552
603
553
604
let ( mac, transparency) = match id. to_ptr ( db) . to_node ( & root) {
554
605
ast:: Macro :: MacroRules ( macro_rules) => (
555
606
match macro_rules. token_tree ( ) {
556
607
Some ( arg) => {
557
608
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 ) ;
559
610
mac
560
611
}
561
612
None => mbe:: DeclarativeMacro :: from_err (
@@ -569,7 +620,7 @@ fn decl_macro_expander(
569
620
match macro_def. body ( ) {
570
621
Some ( arg) => {
571
622
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 ) ;
573
624
mac
574
625
}
575
626
None => mbe:: DeclarativeMacro :: from_err (
0 commit comments