@@ -25,7 +25,9 @@ use ra_ap_syntax::{
25
25
#[ macro_export]
26
26
macro_rules! pre_emit {
27
27
( 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
+ }
29
31
} ;
30
32
( $( $_: tt) * ) => { } ;
31
33
}
@@ -687,6 +689,14 @@ impl<'a> Translator<'a> {
687
689
{
688
690
return true ;
689
691
}
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
+ }
690
700
}
691
701
false
692
702
}
@@ -723,52 +733,75 @@ impl<'a> Translator<'a> {
723
733
}
724
734
}
725
735
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) {
732
763
self . macro_context_depth += 1 ;
733
764
}
765
+ None
734
766
}
735
767
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 ;
740
777
}
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) {
770
804
generated:: Item :: emit_attribute_macro_expansion ( label, expanded, & mut self . trap . writer ) ;
771
- Some ( ( ) )
772
- } ) ( ) ;
805
+ }
773
806
}
774
807
}
0 commit comments