@@ -25,7 +25,9 @@ use ra_ap_syntax::{
2525#[ macro_export]
2626macro_rules! pre_emit {
2727 ( Item , $self: ident, $node: ident) => {
28- $self. setup_item_expansion( $node) ;
28+ if let Some ( label) = $self. prepare_item_expansion( $node) {
29+ return Some ( label) ;
30+ }
2931 } ;
3032 ( $( $_: tt) * ) => { } ;
3133}
@@ -687,6 +689,14 @@ impl<'a> Translator<'a> {
687689 {
688690 return true ;
689691 }
692+ if syntax
693+ . parent ( )
694+ . and_then ( ast:: MacroCall :: cast)
695+ . and_then ( |x| x. token_tree ( ) )
696+ . is_some_and ( |tt| tt. syntax ( ) == syntax)
697+ {
698+ return true ;
699+ }
690700 }
691701 false
692702 }
@@ -723,52 +733,75 @@ impl<'a> Translator<'a> {
723733 }
724734 }
725735
726- pub ( crate ) fn setup_item_expansion ( & mut self , node : & ast:: Item ) {
727- if self . semantics . is_some_and ( |s| {
728- let file = s. hir_file_for ( node. syntax ( ) ) ;
729- let node = InFile :: new ( file, node) ;
730- s. is_attr_macro_call ( node)
731- } ) {
736+ pub ( crate ) fn prepare_item_expansion (
737+ & mut self ,
738+ node : & ast:: Item ,
739+ ) -> Option < Label < generated:: Item > > {
740+ if self . source_kind == SourceKind :: Library {
741+ // if the item expands via an attribute macro, we want to only emit the expansion
742+ if let Some ( expanded) = self . emit_attribute_macro_expansion ( node) {
743+ // we wrap it in a dummy MacroCall to get a single Item label that can replace
744+ // the original Item
745+ let label = self . trap . emit ( generated:: MacroCall {
746+ id : TrapId :: Star ,
747+ attrs : vec ! [ ] ,
748+ path : None ,
749+ token_tree : None ,
750+ } ) ;
751+ generated:: MacroCall :: emit_macro_call_expansion (
752+ label,
753+ expanded. into ( ) ,
754+ & mut self . trap . writer ,
755+ ) ;
756+ return Some ( label. into ( ) ) ;
757+ }
758+ }
759+ let semantics = self . semantics . as_ref ( ) ?;
760+ let file = semantics. hir_file_for ( node. syntax ( ) ) ;
761+ let node = InFile :: new ( file, node) ;
762+ if semantics. is_attr_macro_call ( node) {
732763 self . macro_context_depth += 1 ;
733764 }
765+ None
734766 }
735767
736- pub ( crate ) fn emit_item_expansion ( & mut self , node : & ast:: Item , label : Label < generated:: Item > ) {
737- // TODO: remove this after fixing exponential expansion on libraries like funty-2.0.0
738- if self . source_kind == SourceKind :: Library {
739- return ;
768+ fn emit_attribute_macro_expansion (
769+ & mut self ,
770+ node : & ast:: Item ,
771+ ) -> Option < Label < generated:: MacroItems > > {
772+ let semantics = self . semantics ?;
773+ let file = semantics. hir_file_for ( node. syntax ( ) ) ;
774+ let infile_node = InFile :: new ( file, node) ;
775+ if !semantics. is_attr_macro_call ( infile_node) {
776+ return None ;
740777 }
741- ( || {
742- let semantics = self . semantics ?;
743- let file = semantics. hir_file_for ( node. syntax ( ) ) ;
744- let infile_node = InFile :: new ( file, node) ;
745- if !semantics. is_attr_macro_call ( infile_node) {
746- return None ;
747- }
748- self . macro_context_depth -= 1 ;
749- if self . macro_context_depth > 0 {
750- // only expand the outermost attribute macro
751- return None ;
752- }
753- let ExpandResult {
754- value : expanded, ..
755- } = semantics. expand_attr_macro ( node) ?;
756- self . emit_macro_expansion_parse_errors ( node, & expanded) ;
757- let macro_items = ast:: MacroItems :: cast ( expanded) . or_else ( || {
758- let message = "attribute macro expansion cannot be cast to MacroItems" . to_owned ( ) ;
759- let location = self . location_for_node ( node) ;
760- self . emit_diagnostic (
761- DiagnosticSeverity :: Warning ,
762- "item_expansion" . to_owned ( ) ,
763- message. clone ( ) ,
764- message,
765- location. unwrap_or ( UNKNOWN_LOCATION ) ,
766- ) ;
767- None
768- } ) ?;
769- let expanded = self . emit_macro_items ( & macro_items) ?;
778+ self . macro_context_depth -= 1 ;
779+ if self . macro_context_depth > 0 {
780+ // only expand the outermost attribute macro
781+ return None ;
782+ }
783+ let ExpandResult {
784+ value : expanded, ..
785+ } = semantics. expand_attr_macro ( node) ?;
786+ self . emit_macro_expansion_parse_errors ( node, & expanded) ;
787+ let macro_items = ast:: MacroItems :: cast ( expanded) . or_else ( || {
788+ let message = "attribute macro expansion cannot be cast to MacroItems" . to_owned ( ) ;
789+ let location = self . location_for_node ( node) ;
790+ self . emit_diagnostic (
791+ DiagnosticSeverity :: Warning ,
792+ "item_expansion" . to_owned ( ) ,
793+ message. clone ( ) ,
794+ message,
795+ location. unwrap_or ( UNKNOWN_LOCATION ) ,
796+ ) ;
797+ None
798+ } ) ?;
799+ self . emit_macro_items ( & macro_items)
800+ }
801+
802+ pub ( crate ) fn emit_item_expansion ( & mut self , node : & ast:: Item , label : Label < generated:: Item > ) {
803+ if let Some ( expanded) = self . emit_attribute_macro_expansion ( node) {
770804 generated:: Item :: emit_attribute_macro_expansion ( label, expanded, & mut self . trap . writer ) ;
771- Some ( ( ) )
772- } ) ( ) ;
805+ }
773806 }
774807}
0 commit comments