@@ -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