@@ -3,6 +3,8 @@ use crate::deriving::generic::*;
33use crate :: deriving:: path_std;
44
55use ast:: EnumDef ;
6+ use rustc_ast:: ItemKind ;
7+ use rustc_ast:: VariantData ;
68use rustc_ast:: { self as ast, MetaItem } ;
79use rustc_expand:: base:: { Annotatable , ExtCtxt } ;
810use rustc_span:: symbol:: { sym, Ident , Symbol } ;
@@ -20,6 +22,23 @@ pub fn expand_deriving_debug(
2022 // &mut ::std::fmt::Formatter
2123 let fmtr = Ref ( Box :: new ( Path ( path_std ! ( fmt:: Formatter ) ) ) , ast:: Mutability :: Mut ) ;
2224
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+
2342 let trait_def = TraitDef {
2443 span,
2544 path : path_std ! ( fmt:: Debug ) ,
@@ -33,7 +52,7 @@ pub fn expand_deriving_debug(
3352 explicit_self: true ,
3453 nonself_args: vec![ ( fmtr, sym:: f) ] ,
3554 ret_ty: Path ( path_std!( fmt:: Result ) ) ,
36- attributes: thin_vec! [ cx . attr_word ( sym :: inline , span ) ] ,
55+ attributes,
3756 fieldless_variants_strategy:
3857 FieldlessVariantsStrategy :: SpecializeIfAllVariantsFieldless ,
3958 combine_substructure: combine_substructure( Box :: new( |a, b, c| {
0 commit comments