@@ -12,7 +12,7 @@ use rustc_ast::tokenstream::TokenStream;
1212use  rustc_ast:: visit:: { AssocCtxt ,  Visitor } ; 
1313use  rustc_ast:: { self  as  ast,  AttrVec ,  Attribute ,  HasAttrs ,  Item ,  NodeId ,  PatKind } ; 
1414use  rustc_attr_data_structures:: { AttributeKind ,  Deprecation ,  Stability ,  find_attr} ; 
15- use  rustc_data_structures:: fx:: FxIndexMap ; 
15+ use  rustc_data_structures:: fx:: { FxHashMap ,   FxIndexMap } ; 
1616use  rustc_data_structures:: sync; 
1717use  rustc_errors:: { DiagCtxtHandle ,  ErrorGuaranteed ,  PResult } ; 
1818use  rustc_feature:: Features ; 
@@ -727,6 +727,7 @@ pub enum SyntaxExtensionKind {
727727    /// A trivial attribute "macro" that does nothing, 
728728     /// only keeps the attribute and marks it as inert, 
729729     /// thus making it ineligible for further expansion. 
730+      /// E.g. `#[default]`, `#[rustfmt::skip]`. 
730731     NonMacroAttr , 
731732
732733    /// A token-based derive macro. 
@@ -1166,6 +1167,49 @@ pub struct ExpansionData {
11661167    pub  is_trailing_mac :  bool , 
11671168} 
11681169
1170+ #[ derive( Default ) ]  
1171+ pub  struct  MacroStat  { 
1172+     /// Number of invocations of the macro. 
1173+      pub  count :  usize , 
1174+ 
1175+     /// Net increase in number of lines of code (when pretty-printed), i.e. 
1176+      /// `lines(output) - lines(invocation)`. Can be negative because a macro 
1177+      /// output may be smaller than the invocation. 
1178+      pub  lines :  isize , 
1179+ 
1180+     /// Net increase in number of lines of code (when pretty-printed), i.e. 
1181+      /// `bytes(output) - bytes(invocation)`. Can be negative because a macro 
1182+      /// output may be smaller than the invocation. 
1183+      pub  bytes :  isize , 
1184+ } 
1185+ 
1186+ #[ derive( Clone ,  Copy ,  PartialEq ,  Eq ,  PartialOrd ,  Ord ,  Hash ) ]  
1187+ pub  enum  MacroStatKind  { 
1188+     Attr , 
1189+     Derive , 
1190+     // This covers declarative macros and fn-like proc macros. 
1191+     FnLike , 
1192+ } 
1193+ 
1194+ impl  MacroStatKind  { 
1195+     pub  fn  label ( & self )  -> String  { 
1196+         match  self  { 
1197+             MacroStatKind :: Attr  => "attr" . to_string ( ) , 
1198+             MacroStatKind :: Derive  => "derive" . to_string ( ) , 
1199+             MacroStatKind :: FnLike  => "fn-like" . to_string ( ) , 
1200+         } 
1201+     } 
1202+ 
1203+     // Decorate the name to look like the macro invocation. 
1204+     pub  fn  decorated_name ( & self ,  name :  & str )  -> String  { 
1205+         match  self  { 
1206+             MacroStatKind :: Attr  => format ! ( "#[{name}]" ) , 
1207+             MacroStatKind :: Derive  => name. to_string ( ) , 
1208+             MacroStatKind :: FnLike  => format ! ( "{name}!" ) , 
1209+         } 
1210+     } 
1211+ } 
1212+ 
11691213/// One of these is made during expansion and incrementally updated as we go; 
11701214/// when a macro expansion occurs, the resulting nodes have the `backtrace() 
11711215/// -> expn_data` of their expansion context stored into their span. 
@@ -1189,6 +1233,8 @@ pub struct ExtCtxt<'a> {
11891233     /// in the AST, but insert it here so that we know 
11901234     /// not to expand it again. 
11911235     pub ( super )  expanded_inert_attrs :  MarkedAttrs , 
1236+     /// `-Zmacro-stats` data. 
1237+      pub  macro_stats :  FxHashMap < ( String ,  MacroStatKind ) ,  MacroStat > , 
11921238} 
11931239
11941240impl < ' a >  ExtCtxt < ' a >  { 
@@ -1218,6 +1264,7 @@ impl<'a> ExtCtxt<'a> {
12181264            expansions :  FxIndexMap :: default ( ) , 
12191265            expanded_inert_attrs :  MarkedAttrs :: new ( ) , 
12201266            buffered_early_lint :  vec ! [ ] , 
1267+             macro_stats :  Default :: default ( ) , 
12211268        } 
12221269    } 
12231270
0 commit comments