11//! Defines database & queries for macro expansion.
22
3- use base_db:: { salsa, Edition , SourceDatabase } ;
3+ use base_db:: { salsa, CrateId , Edition , SourceDatabase } ;
44use either:: Either ;
55use limit:: Limit ;
66use mbe:: syntax_node_to_token_tree;
@@ -13,7 +13,7 @@ use triomphe::Arc;
1313
1414use crate :: {
1515 ast_id_map:: AstIdMap , builtin_attr_macro:: pseudo_derive_attr_expansion,
16- builtin_fn_macro:: EagerExpander , fixup, hygiene:: HygieneFrame , tt, BuiltinAttrExpander ,
16+ builtin_fn_macro:: EagerExpander , fixup, hygiene:: HygieneFrame , tt, AstId , BuiltinAttrExpander ,
1717 BuiltinDeriveExpander , BuiltinFnLikeExpander , EagerCallInfo , ExpandError , ExpandResult ,
1818 ExpandTo , HirFileId , HirFileIdRepr , MacroCallId , MacroCallKind , MacroCallLoc , MacroDefId ,
1919 MacroDefKind , MacroFile , ProcMacroExpander ,
@@ -27,61 +27,59 @@ use crate::{
2727/// Actual max for `analysis-stats .` at some point: 30672.
2828static TOKEN_LIMIT : Limit = Limit :: new ( 1_048_576 ) ;
2929
30+ #[ derive( Debug , Clone , Eq , PartialEq ) ]
31+ /// Old-style `macro_rules` or the new macros 2.0
32+ pub struct DeclarativeMacroExpander {
33+ pub mac : mbe:: DeclarativeMacro ,
34+ pub def_site_token_map : mbe:: TokenMap ,
35+ }
36+
37+ impl DeclarativeMacroExpander {
38+ pub fn expand ( & self , tt : & tt:: Subtree ) -> ExpandResult < tt:: Subtree > {
39+ match self . mac . err ( ) {
40+ Some ( e) => ExpandResult :: new (
41+ tt:: Subtree :: empty ( ) ,
42+ ExpandError :: other ( format ! ( "invalid macro definition: {e}" ) ) ,
43+ ) ,
44+ None => self . mac . expand ( tt) . map_err ( Into :: into) ,
45+ }
46+ }
47+ }
48+
3049#[ derive( Debug , Clone , Eq , PartialEq ) ]
3150pub enum TokenExpander {
32- /// Old-style `macro_rules` or the new macros 2.0
33- DeclarativeMacro { mac : mbe:: DeclarativeMacro , def_site_token_map : mbe:: TokenMap } ,
51+ DeclarativeMacro ( Arc < DeclarativeMacroExpander > ) ,
3452 /// Stuff like `line!` and `file!`.
35- Builtin ( BuiltinFnLikeExpander ) ,
53+ BuiltIn ( BuiltinFnLikeExpander ) ,
3654 /// Built-in eagerly expanded fn-like macros (`include!`, `concat!`, etc.)
37- BuiltinEager ( EagerExpander ) ,
55+ BuiltInEager ( EagerExpander ) ,
3856 /// `global_allocator` and such.
39- BuiltinAttr ( BuiltinAttrExpander ) ,
57+ BuiltInAttr ( BuiltinAttrExpander ) ,
4058 /// `derive(Copy)` and such.
41- BuiltinDerive ( BuiltinDeriveExpander ) ,
59+ BuiltInDerive ( BuiltinDeriveExpander ) ,
4260 /// The thing we love the most here in rust-analyzer -- procedural macros.
4361 ProcMacro ( ProcMacroExpander ) ,
4462}
4563
4664impl TokenExpander {
47- fn expand (
48- & self ,
49- db : & dyn ExpandDatabase ,
50- id : MacroCallId ,
51- tt : & tt:: Subtree ,
52- ) -> ExpandResult < tt:: Subtree > {
53- match self {
54- TokenExpander :: DeclarativeMacro { mac, .. } => mac. expand ( tt) . map_err ( Into :: into) ,
55- TokenExpander :: Builtin ( it) => it. expand ( db, id, tt) . map_err ( Into :: into) ,
56- TokenExpander :: BuiltinEager ( it) => it. expand ( db, id, tt) . map_err ( Into :: into) ,
57- TokenExpander :: BuiltinAttr ( it) => it. expand ( db, id, tt) ,
58- TokenExpander :: BuiltinDerive ( _) => {
59- unreachable ! ( "builtin derives should be expanded manually" )
60- }
61- TokenExpander :: ProcMacro ( _) => {
62- unreachable ! ( "ExpandDatabase::expand_proc_macro should be used for proc macros" )
63- }
64- }
65- }
66-
6765 pub ( crate ) fn map_id_down ( & self , id : tt:: TokenId ) -> tt:: TokenId {
6866 match self {
69- TokenExpander :: DeclarativeMacro { mac , .. } => mac. map_id_down ( id) ,
70- TokenExpander :: Builtin ( ..)
71- | TokenExpander :: BuiltinEager ( ..)
72- | TokenExpander :: BuiltinAttr ( ..)
73- | TokenExpander :: BuiltinDerive ( ..)
67+ TokenExpander :: DeclarativeMacro ( expander ) => expander . mac . map_id_down ( id) ,
68+ TokenExpander :: BuiltIn ( ..)
69+ | TokenExpander :: BuiltInEager ( ..)
70+ | TokenExpander :: BuiltInAttr ( ..)
71+ | TokenExpander :: BuiltInDerive ( ..)
7472 | TokenExpander :: ProcMacro ( ..) => id,
7573 }
7674 }
7775
7876 pub ( crate ) fn map_id_up ( & self , id : tt:: TokenId ) -> ( tt:: TokenId , mbe:: Origin ) {
7977 match self {
80- TokenExpander :: DeclarativeMacro { mac , .. } => mac. map_id_up ( id) ,
81- TokenExpander :: Builtin ( ..)
82- | TokenExpander :: BuiltinEager ( ..)
83- | TokenExpander :: BuiltinAttr ( ..)
84- | TokenExpander :: BuiltinDerive ( ..)
78+ TokenExpander :: DeclarativeMacro ( expander ) => expander . mac . map_id_up ( id) ,
79+ TokenExpander :: BuiltIn ( ..)
80+ | TokenExpander :: BuiltInEager ( ..)
81+ | TokenExpander :: BuiltInAttr ( ..)
82+ | TokenExpander :: BuiltInDerive ( ..)
8583 | TokenExpander :: ProcMacro ( ..) => ( id, mbe:: Origin :: Call ) ,
8684 }
8785 }
@@ -124,7 +122,14 @@ pub trait ExpandDatabase: SourceDatabase {
124122 fn macro_arg_text ( & self , id : MacroCallId ) -> Option < GreenNode > ;
125123 /// Gets the expander for this macro. This compiles declarative macros, and
126124 /// just fetches procedural ones.
127- fn macro_def ( & self , id : MacroDefId ) -> Result < Arc < TokenExpander > , mbe:: ParseError > ;
125+ // FIXME: Rename this
126+ #[ salsa:: transparent]
127+ fn macro_def ( & self , id : MacroDefId ) -> TokenExpander ;
128+ fn decl_macro_expander (
129+ & self ,
130+ def_crate : CrateId ,
131+ id : AstId < ast:: Macro > ,
132+ ) -> Arc < DeclarativeMacroExpander > ;
128133
129134 /// Expand macro call to a token tree.
130135 // This query is LRU cached
@@ -162,7 +167,7 @@ pub fn expand_speculative(
162167 token_to_map : SyntaxToken ,
163168) -> Option < ( SyntaxNode , SyntaxToken ) > {
164169 let loc = db. lookup_intern_macro_call ( actual_macro_call) ;
165- let macro_def = db. macro_def ( loc. def ) . ok ( ) ? ;
170+ let macro_def = db. macro_def ( loc. def ) ;
166171 let token_range = token_to_map. text_range ( ) ;
167172
168173 // Build the subtree and token mapping for the speculative args
@@ -239,7 +244,12 @@ pub fn expand_speculative(
239244 let adt = ast:: Adt :: cast ( speculative_args. clone ( ) ) . unwrap ( ) ;
240245 expander. expand ( db, actual_macro_call, & adt, & spec_args_tmap)
241246 }
242- _ => macro_def. expand ( db, actual_macro_call, & tt) ,
247+ MacroDefKind :: Declarative ( it) => db. decl_macro_expander ( loc. krate , it) . expand ( & tt) ,
248+ MacroDefKind :: BuiltIn ( it, _) => it. expand ( db, actual_macro_call, & tt) . map_err ( Into :: into) ,
249+ MacroDefKind :: BuiltInEager ( it, _) => {
250+ it. expand ( db, actual_macro_call, & tt) . map_err ( Into :: into)
251+ }
252+ MacroDefKind :: BuiltInAttr ( it, _) => it. expand ( db, actual_macro_call, & tt) ,
243253 } ;
244254
245255 let expand_to = macro_expand_to ( db, actual_macro_call) ;
@@ -412,44 +422,55 @@ fn macro_arg_text(db: &dyn ExpandDatabase, id: MacroCallId) -> Option<GreenNode>
412422 }
413423}
414424
415- fn macro_def (
425+ fn decl_macro_expander (
416426 db : & dyn ExpandDatabase ,
417- id : MacroDefId ,
418- ) -> Result < Arc < TokenExpander > , mbe:: ParseError > {
427+ def_crate : CrateId ,
428+ id : AstId < ast:: Macro > ,
429+ ) -> Arc < DeclarativeMacroExpander > {
430+ let is_2021 = db. crate_graph ( ) [ def_crate] . edition >= Edition :: Edition2021 ;
431+ let ( mac, def_site_token_map) = match id. to_node ( db) {
432+ ast:: Macro :: MacroRules ( macro_rules) => match macro_rules. token_tree ( ) {
433+ Some ( arg) => {
434+ let ( tt, def_site_token_map) = mbe:: syntax_node_to_token_tree ( arg. syntax ( ) ) ;
435+ let mac = mbe:: DeclarativeMacro :: parse_macro_rules ( & tt, is_2021) ;
436+ ( mac, def_site_token_map)
437+ }
438+ None => (
439+ mbe:: DeclarativeMacro :: from_err (
440+ mbe:: ParseError :: Expected ( "expected a token tree" . into ( ) ) ,
441+ is_2021,
442+ ) ,
443+ Default :: default ( ) ,
444+ ) ,
445+ } ,
446+ ast:: Macro :: MacroDef ( macro_def) => match macro_def. body ( ) {
447+ Some ( arg) => {
448+ let ( tt, def_site_token_map) = mbe:: syntax_node_to_token_tree ( arg. syntax ( ) ) ;
449+ let mac = mbe:: DeclarativeMacro :: parse_macro2 ( & tt, is_2021) ;
450+ ( mac, def_site_token_map)
451+ }
452+ None => (
453+ mbe:: DeclarativeMacro :: from_err (
454+ mbe:: ParseError :: Expected ( "expected a token tree" . into ( ) ) ,
455+ is_2021,
456+ ) ,
457+ Default :: default ( ) ,
458+ ) ,
459+ } ,
460+ } ;
461+ Arc :: new ( DeclarativeMacroExpander { mac, def_site_token_map } )
462+ }
463+
464+ fn macro_def ( db : & dyn ExpandDatabase , id : MacroDefId ) -> TokenExpander {
419465 match id. kind {
420466 MacroDefKind :: Declarative ( ast_id) => {
421- let is_2021 = db. crate_graph ( ) [ id. krate ] . edition >= Edition :: Edition2021 ;
422- let ( mac, def_site_token_map) = match ast_id. to_node ( db) {
423- ast:: Macro :: MacroRules ( macro_rules) => {
424- let arg = macro_rules
425- . token_tree ( )
426- . ok_or_else ( || mbe:: ParseError :: Expected ( "expected a token tree" . into ( ) ) ) ?;
427- let ( tt, def_site_token_map) = mbe:: syntax_node_to_token_tree ( arg. syntax ( ) ) ;
428- let mac = mbe:: DeclarativeMacro :: parse_macro_rules ( & tt, is_2021) ?;
429- ( mac, def_site_token_map)
430- }
431- ast:: Macro :: MacroDef ( macro_def) => {
432- let arg = macro_def
433- . body ( )
434- . ok_or_else ( || mbe:: ParseError :: Expected ( "expected a token tree" . into ( ) ) ) ?;
435- let ( tt, def_site_token_map) = mbe:: syntax_node_to_token_tree ( arg. syntax ( ) ) ;
436- let mac = mbe:: DeclarativeMacro :: parse_macro2 ( & tt, is_2021) ?;
437- ( mac, def_site_token_map)
438- }
439- } ;
440- Ok ( Arc :: new ( TokenExpander :: DeclarativeMacro { mac, def_site_token_map } ) )
441- }
442- MacroDefKind :: BuiltIn ( expander, _) => Ok ( Arc :: new ( TokenExpander :: Builtin ( expander) ) ) ,
443- MacroDefKind :: BuiltInAttr ( expander, _) => {
444- Ok ( Arc :: new ( TokenExpander :: BuiltinAttr ( expander) ) )
445- }
446- MacroDefKind :: BuiltInDerive ( expander, _) => {
447- Ok ( Arc :: new ( TokenExpander :: BuiltinDerive ( expander) ) )
448- }
449- MacroDefKind :: BuiltInEager ( expander, ..) => {
450- Ok ( Arc :: new ( TokenExpander :: BuiltinEager ( expander) ) )
467+ TokenExpander :: DeclarativeMacro ( db. decl_macro_expander ( id. krate , ast_id) )
451468 }
452- MacroDefKind :: ProcMacro ( expander, ..) => Ok ( Arc :: new ( TokenExpander :: ProcMacro ( expander) ) ) ,
469+ MacroDefKind :: BuiltIn ( expander, _) => TokenExpander :: BuiltIn ( expander) ,
470+ MacroDefKind :: BuiltInAttr ( expander, _) => TokenExpander :: BuiltInAttr ( expander) ,
471+ MacroDefKind :: BuiltInDerive ( expander, _) => TokenExpander :: BuiltInDerive ( expander) ,
472+ MacroDefKind :: BuiltInEager ( expander, ..) => TokenExpander :: BuiltInEager ( expander) ,
473+ MacroDefKind :: ProcMacro ( expander, ..) => TokenExpander :: ProcMacro ( expander) ,
453474 }
454475}
455476
@@ -483,20 +504,6 @@ fn macro_expand(db: &dyn ExpandDatabase, id: MacroCallId) -> ExpandResult<Arc<tt
483504 ( expander. expand ( db, id, & adt, & tmap) , Some ( ( tmap, fixups. undo_info ) ) )
484505 }
485506 _ => {
486- let expander = match db. macro_def ( loc. def ) {
487- Ok ( it) => it,
488- // FIXME: We should make sure to enforce a variant that invalid macro
489- // definitions do not get expanders that could reach this call path!
490- Err ( err) => {
491- return ExpandResult {
492- value : Arc :: new ( tt:: Subtree {
493- delimiter : tt:: Delimiter :: UNSPECIFIED ,
494- token_trees : vec ! [ ] ,
495- } ) ,
496- err : Some ( ExpandError :: other ( format ! ( "invalid macro definition: {err}" ) ) ) ,
497- }
498- }
499- } ;
500507 let Some ( macro_arg) = db. macro_arg ( id) else {
501508 return ExpandResult {
502509 value : Arc :: new ( tt:: Subtree {
@@ -509,7 +516,15 @@ fn macro_expand(db: &dyn ExpandDatabase, id: MacroCallId) -> ExpandResult<Arc<tt
509516 } ;
510517 } ;
511518 let ( arg, arg_tm, undo_info) = & * macro_arg;
512- let mut res = expander. expand ( db, id, arg) ;
519+ let mut res = match loc. def . kind {
520+ MacroDefKind :: Declarative ( id) => {
521+ db. decl_macro_expander ( loc. def . krate , id) . expand ( & arg)
522+ }
523+ MacroDefKind :: BuiltIn ( it, _) => it. expand ( db, id, & arg) . map_err ( Into :: into) ,
524+ MacroDefKind :: BuiltInEager ( it, _) => it. expand ( db, id, & arg) . map_err ( Into :: into) ,
525+ MacroDefKind :: BuiltInAttr ( it, _) => it. expand ( db, id, & arg) ,
526+ _ => unreachable ! ( ) ,
527+ } ;
513528 fixup:: reverse_fixups ( & mut res. value , arg_tm, undo_info) ;
514529 ( res, None )
515530 }
0 commit comments