@@ -8,6 +8,8 @@ use rustc_expand::base::{Annotatable, ExtCtxt};
8
8
use rustc_span:: symbol:: { sym, Ident , Symbol } ;
9
9
use rustc_span:: Span ;
10
10
use thin_vec:: { thin_vec, ThinVec } ;
11
+ use rustc_ast:: ItemKind ;
12
+ use rustc_ast:: VariantData ;
11
13
12
14
pub fn expand_deriving_debug (
13
15
cx : & mut ExtCtxt < ' _ > ,
@@ -20,6 +22,23 @@ pub fn expand_deriving_debug(
20
22
// &mut ::std::fmt::Formatter
21
23
let fmtr = Ref ( Box :: new ( Path ( path_std ! ( fmt:: Formatter ) ) ) , ast:: Mutability :: Mut ) ;
22
24
25
+ // We default to applying #[inline]
26
+ let mut attributes = thin_vec ! [ cx. attr_word( sym:: inline, span) ] ;
27
+ if let Annotatable :: Item ( item) = item {
28
+ match & item. kind {
29
+ ItemKind :: Struct ( VariantData :: Struct ( fields, _) | VariantData :: Tuple ( fields, _) , _) => {
30
+ // Except that we drop it for structs with more than 5 fields, because with less
31
+ // than 5 fields we implement Debug with a single function call, which makes
32
+ // Debug::fmt a trivial wrapper that always should be optimized away. But with more
33
+ // than 5 fields, Debug::fmt has a complicated body.
34
+ if fields. len ( ) > 5 {
35
+ attributes = ThinVec :: new ( ) ;
36
+ }
37
+ }
38
+ _ => { }
39
+ }
40
+ }
41
+
23
42
let trait_def = TraitDef {
24
43
span,
25
44
path : path_std ! ( fmt:: Debug ) ,
@@ -33,7 +52,7 @@ pub fn expand_deriving_debug(
33
52
explicit_self: true ,
34
53
nonself_args: vec![ ( fmtr, sym:: f) ] ,
35
54
ret_ty: Path ( path_std!( fmt:: Result ) ) ,
36
- attributes: thin_vec! [ cx . attr_word ( sym :: inline , span ) ] ,
55
+ attributes,
37
56
fieldless_variants_strategy:
38
57
FieldlessVariantsStrategy :: SpecializeIfAllVariantsFieldless ,
39
58
combine_substructure: combine_substructure( Box :: new( |a, b, c| {
0 commit comments