@@ -24,7 +24,8 @@ use crate::{
24
24
HirFileId , HirFileIdRepr , MacroCallId , MacroCallKind , MacroCallLoc , MacroDefId , MacroDefKind ,
25
25
MacroFileId ,
26
26
} ;
27
-
27
+ /// This is just to ensure the types of smart_macro_arg and macro_arg are the same
28
+ type MacroArgResult = ( Arc < tt:: Subtree > , SyntaxFixupUndoInfo , Span ) ;
28
29
/// Total limit on the number of tokens produced by any macro invocation.
29
30
///
30
31
/// If an invocation produces more tokens than this limit, it will not be stored in the database and
@@ -98,7 +99,13 @@ pub trait ExpandDatabase: SourceDatabase {
98
99
/// Lowers syntactic macro call to a token tree representation. That's a firewall
99
100
/// query, only typing in the macro call itself changes the returned
100
101
/// subtree.
101
- fn macro_arg ( & self , id : MacroCallId ) -> ( Arc < tt:: Subtree > , SyntaxFixupUndoInfo , Span ) ;
102
+ fn macro_arg ( & self , id : MacroCallId ) -> MacroArgResult ;
103
+ #[ salsa:: transparent]
104
+ fn macro_arg_considering_derives (
105
+ & self ,
106
+ id : MacroCallId ,
107
+ kind : & MacroCallKind ,
108
+ ) -> MacroArgResult ;
102
109
/// Fetches the expander for this macro.
103
110
#[ salsa:: transparent]
104
111
#[ salsa:: invoke( TokenExpander :: macro_expander) ]
@@ -144,7 +151,7 @@ pub fn expand_speculative(
144
151
let span_map = RealSpanMap :: absolute ( FileId :: BOGUS ) ;
145
152
let span_map = SpanMapRef :: RealSpanMap ( & span_map) ;
146
153
147
- let ( _, _, span) = db. macro_arg ( actual_macro_call) ;
154
+ let ( _, _, span) = db. macro_arg_considering_derives ( actual_macro_call, & loc . kind ) ;
148
155
149
156
// Build the subtree and token mapping for the speculative args
150
157
let ( mut tt, undo_info) = match loc. kind {
@@ -339,12 +346,24 @@ pub(crate) fn parse_with_map(
339
346
}
340
347
}
341
348
342
- // FIXME: for derive attributes, this will return separate copies of the same structures! Though
343
- // they may differ in spans due to differing call sites...
344
- fn macro_arg (
349
+ /// This resolves the [MacroCallId] to check if it is a derive macro if so get the [macro_arg] for the derive.
350
+ /// Other wise return the [macro_arg] for the macro_call_id.
351
+ ///
352
+ /// This is not connected to the database so it does not cached the result. However, the inner [macro_arg] query is
353
+ fn macro_arg_considering_derives (
345
354
db : & dyn ExpandDatabase ,
346
355
id : MacroCallId ,
347
- ) -> ( Arc < tt:: Subtree > , SyntaxFixupUndoInfo , Span ) {
356
+ kind : & MacroCallKind ,
357
+ ) -> MacroArgResult {
358
+ match kind {
359
+ // Get the macro arg for the derive macro
360
+ MacroCallKind :: Derive { derive_macro_id, .. } => db. macro_arg ( * derive_macro_id) ,
361
+ // Normal macro arg
362
+ _ => db. macro_arg ( id) ,
363
+ }
364
+ }
365
+
366
+ fn macro_arg ( db : & dyn ExpandDatabase , id : MacroCallId ) -> MacroArgResult {
348
367
let loc = db. lookup_intern_macro_call ( id) ;
349
368
350
369
if let MacroCallLoc {
@@ -414,29 +433,30 @@ fn macro_arg(
414
433
}
415
434
return ( Arc :: new ( tt) , SyntaxFixupUndoInfo :: NONE , span) ;
416
435
}
417
- MacroCallKind :: Derive { ast_id, derive_attr_index, .. } => {
418
- let node = ast_id. to_ptr ( db) . to_node ( & root) ;
419
- let censor_derive_input = censor_derive_input ( derive_attr_index, & node) ;
420
- let item_node = node. into ( ) ;
421
- let attr_source = attr_source ( derive_attr_index, & item_node) ;
422
- // FIXME: This is wrong, this should point to the path of the derive attribute`
423
- let span =
424
- map. span_for_range ( attr_source. as_ref ( ) . and_then ( |it| it. path ( ) ) . map_or_else (
425
- || item_node. syntax ( ) . text_range ( ) ,
426
- |it| it. syntax ( ) . text_range ( ) ,
427
- ) ) ;
428
- ( censor_derive_input, item_node, span)
436
+ // MacroCallKind::Derive should not be here. As we are getting the argument for the derive macro
437
+ MacroCallKind :: Derive { .. } => {
438
+ unreachable ! ( "`ExpandDatabase::macro_arg` called with `MacroCallKind::Derive`" )
429
439
}
430
440
MacroCallKind :: Attr { ast_id, invoc_attr_index, .. } => {
431
441
let node = ast_id. to_ptr ( db) . to_node ( & root) ;
432
442
let attr_source = attr_source ( invoc_attr_index, & node) ;
443
+
433
444
let span = map. span_for_range (
434
445
attr_source
435
446
. as_ref ( )
436
447
. and_then ( |it| it. path ( ) )
437
448
. map_or_else ( || node. syntax ( ) . text_range ( ) , |it| it. syntax ( ) . text_range ( ) ) ,
438
449
) ;
439
- ( attr_source. into_iter ( ) . map ( |it| it. syntax ( ) . clone ( ) . into ( ) ) . collect ( ) , node, span)
450
+ // If derive attribute we need to censor the derive input
451
+ if matches ! ( loc. def. kind, MacroDefKind :: BuiltInAttr ( expander, ..) if expander. is_derive( ) )
452
+ && ast:: Adt :: can_cast ( node. syntax ( ) . kind ( ) )
453
+ {
454
+ let adt = ast:: Adt :: cast ( node. syntax ( ) . clone ( ) ) . unwrap ( ) ;
455
+ let censor_derive_input = censor_derive_input ( invoc_attr_index, & adt) ;
456
+ ( censor_derive_input, node, span)
457
+ } else {
458
+ ( attr_source. into_iter ( ) . map ( |it| it. syntax ( ) . clone ( ) . into ( ) ) . collect ( ) , node, span)
459
+ }
440
460
}
441
461
} ;
442
462
@@ -526,7 +546,8 @@ fn macro_expand(
526
546
let ( ExpandResult { value : tt, err } , span) = match loc. def . kind {
527
547
MacroDefKind :: ProcMacro ( ..) => return db. expand_proc_macro ( macro_call_id) . map ( CowArc :: Arc ) ,
528
548
_ => {
529
- let ( macro_arg, undo_info, span) = db. macro_arg ( macro_call_id) ;
549
+ let ( macro_arg, undo_info, span) =
550
+ db. macro_arg_considering_derives ( macro_call_id, & loc. kind ) ;
530
551
531
552
let arg = & * macro_arg;
532
553
let res =
@@ -603,7 +624,7 @@ fn proc_macro_span(db: &dyn ExpandDatabase, ast: AstId<ast::Fn>) -> Span {
603
624
604
625
fn expand_proc_macro ( db : & dyn ExpandDatabase , id : MacroCallId ) -> ExpandResult < Arc < tt:: Subtree > > {
605
626
let loc = db. lookup_intern_macro_call ( id) ;
606
- let ( macro_arg, undo_info, span) = db. macro_arg ( id) ;
627
+ let ( macro_arg, undo_info, span) = db. macro_arg_considering_derives ( id, & loc . kind ) ;
607
628
608
629
let ( expander, ast) = match loc. def . kind {
609
630
MacroDefKind :: ProcMacro ( expander, _, ast) => ( expander, ast) ,
0 commit comments