@@ -168,8 +168,6 @@ pub enum MacroCallKind {
168168 /// Outer attributes are counted first, then inner attributes. This does not support
169169 /// out-of-line modules, which may have attributes spread across 2 files!
170170 invoc_attr_index : AttrId ,
171- /// Whether this attribute is the `#[derive]` attribute.
172- is_derive : bool ,
173171 } ,
174172}
175173
@@ -232,18 +230,17 @@ impl HirFileId {
232230 pub fn call_node ( self , db : & dyn db:: ExpandDatabase ) -> Option < InFile < SyntaxNode > > {
233231 let macro_file = self . macro_file ( ) ?;
234232 let loc: MacroCallLoc = db. lookup_intern_macro_call ( macro_file. macro_call_id ) ;
235- Some ( loc. kind . to_node ( db) )
233+ Some ( loc. to_node ( db) )
236234 }
237235
238236 /// If this is a macro call, returns the syntax node of the very first macro call this file resides in.
239237 pub fn original_call_node ( self , db : & dyn db:: ExpandDatabase ) -> Option < ( FileId , SyntaxNode ) > {
240- let mut call =
241- db. lookup_intern_macro_call ( self . macro_file ( ) ?. macro_call_id ) . kind . to_node ( db) ;
238+ let mut call = db. lookup_intern_macro_call ( self . macro_file ( ) ?. macro_call_id ) . to_node ( db) ;
242239 loop {
243240 match call. file_id . repr ( ) {
244241 HirFileIdRepr :: FileId ( file_id) => break Some ( ( file_id, call. value ) ) ,
245242 HirFileIdRepr :: MacroFile ( MacroFile { macro_call_id } ) => {
246- call = db. lookup_intern_macro_call ( macro_call_id) . kind . to_node ( db) ;
243+ call = db. lookup_intern_macro_call ( macro_call_id) . to_node ( db) ;
247244 }
248245 }
249246 }
@@ -306,7 +303,7 @@ impl HirFileId {
306303 let macro_file = self . macro_file ( ) ?;
307304 let loc: MacroCallLoc = db. lookup_intern_macro_call ( macro_file. macro_call_id ) ;
308305 let attr = match loc. def . kind {
309- MacroDefKind :: BuiltInDerive ( ..) => loc. kind . to_node ( db) ,
306+ MacroDefKind :: BuiltInDerive ( ..) => loc. to_node ( db) ,
310307 _ => return None ,
311308 } ;
312309 Some ( attr. with_value ( ast:: Attr :: cast ( attr. value . clone ( ) ) ?) )
@@ -350,7 +347,7 @@ impl HirFileId {
350347 match self . macro_file ( ) {
351348 Some ( macro_file) => {
352349 let loc: MacroCallLoc = db. lookup_intern_macro_call ( macro_file. macro_call_id ) ;
353- matches ! ( loc. kind , MacroCallKind :: Attr { is_derive : true , .. } )
350+ loc. def . is_attribute_derive ( )
354351 }
355352 None => false ,
356353 }
@@ -421,22 +418,15 @@ impl MacroDefId {
421418 MacroDefKind :: BuiltInAttr ( ..) | MacroDefKind :: ProcMacro ( _, ProcMacroKind :: Attr , _)
422419 )
423420 }
424- }
425-
426- // FIXME: attribute indices do not account for nested `cfg_attr`
427421
428- impl MacroCallKind {
429- /// Returns the file containing the macro invocation.
430- fn file_id ( & self ) -> HirFileId {
431- match * self {
432- MacroCallKind :: FnLike { ast_id : InFile { file_id, .. } , .. }
433- | MacroCallKind :: Derive { ast_id : InFile { file_id, .. } , .. }
434- | MacroCallKind :: Attr { ast_id : InFile { file_id, .. } , .. } => file_id,
435- }
422+ pub fn is_attribute_derive ( & self ) -> bool {
423+ matches ! ( self . kind, MacroDefKind :: BuiltInAttr ( expander, ..) if expander. is_derive( ) )
436424 }
425+ }
437426
427+ impl MacroCallLoc {
438428 pub fn to_node ( & self , db : & dyn db:: ExpandDatabase ) -> InFile < SyntaxNode > {
439- match self {
429+ match self . kind {
440430 MacroCallKind :: FnLike { ast_id, .. } => {
441431 ast_id. with_value ( ast_id. to_node ( db) . syntax ( ) . clone ( ) )
442432 }
@@ -452,23 +442,49 @@ impl MacroCallKind {
452442 . unwrap_or_else ( || it. syntax ( ) . clone ( ) )
453443 } )
454444 }
455- MacroCallKind :: Attr { ast_id, is_derive : true , invoc_attr_index, .. } => {
456- // FIXME: handle `cfg_attr`
457- ast_id. with_value ( ast_id. to_node ( db) ) . map ( |it| {
458- it. doc_comments_and_attrs ( )
459- . nth ( invoc_attr_index. ast_index ( ) )
460- . and_then ( |it| match it {
461- Either :: Left ( attr) => Some ( attr. syntax ( ) . clone ( ) ) ,
462- Either :: Right ( _) => None ,
463- } )
464- . unwrap_or_else ( || it. syntax ( ) . clone ( ) )
465- } )
445+ MacroCallKind :: Attr { ast_id, invoc_attr_index, .. } => {
446+ if self . def . is_attribute_derive ( ) {
447+ // FIXME: handle `cfg_attr`
448+ ast_id. with_value ( ast_id. to_node ( db) ) . map ( |it| {
449+ it. doc_comments_and_attrs ( )
450+ . nth ( invoc_attr_index. ast_index ( ) )
451+ . and_then ( |it| match it {
452+ Either :: Left ( attr) => Some ( attr. syntax ( ) . clone ( ) ) ,
453+ Either :: Right ( _) => None ,
454+ } )
455+ . unwrap_or_else ( || it. syntax ( ) . clone ( ) )
456+ } )
457+ } else {
458+ ast_id. with_value ( ast_id. to_node ( db) . syntax ( ) . clone ( ) )
459+ }
466460 }
467- MacroCallKind :: Attr { ast_id, .. } => {
468- ast_id. with_value ( ast_id. to_node ( db) . syntax ( ) . clone ( ) )
461+ }
462+ }
463+
464+ fn expand_to ( & self ) -> ExpandTo {
465+ match self . kind {
466+ MacroCallKind :: FnLike { expand_to, .. } => expand_to,
467+ MacroCallKind :: Derive { .. } => ExpandTo :: Items ,
468+ MacroCallKind :: Attr { .. } if self . def . is_attribute_derive ( ) => ExpandTo :: Statements ,
469+ MacroCallKind :: Attr { .. } => {
470+ // is this always correct?
471+ ExpandTo :: Items
469472 }
470473 }
471474 }
475+ }
476+
477+ // FIXME: attribute indices do not account for nested `cfg_attr`
478+
479+ impl MacroCallKind {
480+ /// Returns the file containing the macro invocation.
481+ fn file_id ( & self ) -> HirFileId {
482+ match * self {
483+ MacroCallKind :: FnLike { ast_id : InFile { file_id, .. } , .. }
484+ | MacroCallKind :: Derive { ast_id : InFile { file_id, .. } , .. }
485+ | MacroCallKind :: Attr { ast_id : InFile { file_id, .. } , .. } => file_id,
486+ }
487+ }
472488
473489 /// Returns the original file range that best describes the location of this macro call.
474490 ///
@@ -546,15 +562,6 @@ impl MacroCallKind {
546562 MacroCallKind :: Attr { ast_id, .. } => Some ( ast_id. to_node ( db) . syntax ( ) . clone ( ) ) ,
547563 }
548564 }
549-
550- fn expand_to ( & self ) -> ExpandTo {
551- match self {
552- MacroCallKind :: FnLike { expand_to, .. } => * expand_to,
553- MacroCallKind :: Derive { .. } => ExpandTo :: Items ,
554- MacroCallKind :: Attr { is_derive : true , .. } => ExpandTo :: Statements ,
555- MacroCallKind :: Attr { .. } => ExpandTo :: Items , // is this always correct?
556- }
557- }
558565}
559566
560567impl MacroCallId {
@@ -618,7 +625,7 @@ impl ExpansionInfo {
618625
619626 let token_range = token. value . text_range ( ) ;
620627 match & loc. kind {
621- MacroCallKind :: Attr { attr_args, invoc_attr_index, is_derive , .. } => {
628+ MacroCallKind :: Attr { attr_args, invoc_attr_index, .. } => {
622629 // FIXME: handle `cfg_attr`
623630 let attr = item
624631 . doc_comments_and_attrs ( )
@@ -634,7 +641,8 @@ impl ExpansionInfo {
634641 token. value . text_range ( ) . checked_sub ( attr_input_start) ?;
635642 // shift by the item's tree's max id
636643 let token_id = attr_args. 1 . token_by_range ( relative_range) ?;
637- let token_id = if * is_derive {
644+
645+ let token_id = if loc. def . is_attribute_derive ( ) {
638646 // we do not shift for `#[derive]`, as we only need to downmap the derive attribute tokens
639647 token_id
640648 } else {
@@ -697,18 +705,19 @@ impl ExpansionInfo {
697705
698706 // Attributes are a bit special for us, they have two inputs, the input tokentree and the annotated item.
699707 let ( token_map, tt) = match & loc. kind {
700- MacroCallKind :: Attr { attr_args, is_derive : true , .. } => {
701- ( & attr_args. 1 , self . attr_input_or_mac_def . clone ( ) ?. syntax ( ) . cloned ( ) )
702- }
703708 MacroCallKind :: Attr { attr_args, .. } => {
704- // try unshifting the token id, if unshifting fails, the token resides in the non-item attribute input
705- // note that the `TokenExpander::map_id_up` earlier only unshifts for declarative macros, so we don't double unshift with this
706- match self . macro_arg_shift . unshift ( token_id) {
707- Some ( unshifted) => {
708- token_id = unshifted;
709- ( & attr_args. 1 , self . attr_input_or_mac_def . clone ( ) ?. syntax ( ) . cloned ( ) )
709+ if loc. def . is_attribute_derive ( ) {
710+ ( & attr_args. 1 , self . attr_input_or_mac_def . clone ( ) ?. syntax ( ) . cloned ( ) )
711+ } else {
712+ // try unshifting the token id, if unshifting fails, the token resides in the non-item attribute input
713+ // note that the `TokenExpander::map_id_up` earlier only unshifts for declarative macros, so we don't double unshift with this
714+ match self . macro_arg_shift . unshift ( token_id) {
715+ Some ( unshifted) => {
716+ token_id = unshifted;
717+ ( & attr_args. 1 , self . attr_input_or_mac_def . clone ( ) ?. syntax ( ) . cloned ( ) )
718+ }
719+ None => ( & self . macro_arg . 1 , self . arg . clone ( ) ) ,
710720 }
711- None => ( & self . macro_arg . 1 , self . arg . clone ( ) ) ,
712721 }
713722 }
714723 _ => match origin {
0 commit comments