@@ -12,7 +12,7 @@ use rustc_ast::tokenstream::TokenStream;
12
12
use rustc_ast:: visit:: { AssocCtxt , Visitor } ;
13
13
use rustc_ast:: { self as ast, AttrVec , Attribute , HasAttrs , Item , NodeId , PatKind } ;
14
14
use rustc_attr_data_structures:: { AttributeKind , Deprecation , Stability , find_attr} ;
15
- use rustc_data_structures:: fx:: FxIndexMap ;
15
+ use rustc_data_structures:: fx:: { FxHashMap , FxIndexMap } ;
16
16
use rustc_data_structures:: sync;
17
17
use rustc_errors:: { DiagCtxtHandle , ErrorGuaranteed , PResult } ;
18
18
use rustc_feature:: Features ;
@@ -727,6 +727,7 @@ pub enum SyntaxExtensionKind {
727
727
/// A trivial attribute "macro" that does nothing,
728
728
/// only keeps the attribute and marks it as inert,
729
729
/// thus making it ineligible for further expansion.
730
+ /// E.g. `#[default]`, `#[rustfmt::skip]`.
730
731
NonMacroAttr ,
731
732
732
733
/// A token-based derive macro.
@@ -1166,6 +1167,49 @@ pub struct ExpansionData {
1166
1167
pub is_trailing_mac : bool ,
1167
1168
}
1168
1169
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
+
1169
1213
/// One of these is made during expansion and incrementally updated as we go;
1170
1214
/// when a macro expansion occurs, the resulting nodes have the `backtrace()
1171
1215
/// -> expn_data` of their expansion context stored into their span.
@@ -1189,6 +1233,8 @@ pub struct ExtCtxt<'a> {
1189
1233
/// in the AST, but insert it here so that we know
1190
1234
/// not to expand it again.
1191
1235
pub ( super ) expanded_inert_attrs : MarkedAttrs ,
1236
+ /// `-Zmacro-stats` data.
1237
+ pub macro_stats : FxHashMap < ( String , MacroStatKind ) , MacroStat > ,
1192
1238
}
1193
1239
1194
1240
impl < ' a > ExtCtxt < ' a > {
@@ -1218,6 +1264,7 @@ impl<'a> ExtCtxt<'a> {
1218
1264
expansions : FxIndexMap :: default ( ) ,
1219
1265
expanded_inert_attrs : MarkedAttrs :: new ( ) ,
1220
1266
buffered_early_lint : vec ! [ ] ,
1267
+ macro_stats : Default :: default ( ) ,
1221
1268
}
1222
1269
}
1223
1270
0 commit comments