@@ -12,10 +12,13 @@ declare_clippy_lint! {
12
12
/// `enum`s.
13
13
///
14
14
/// **Why is this bad?** Enum size is bounded by the largest variant. Having a
15
- /// large variant
16
- /// can penalize the memory layout of that enum.
15
+ /// large variant can penalize the memory layout of that enum.
17
16
///
18
- /// **Known problems:** None.
17
+ /// **Known problems:** This lint obviously cannot take the distribution of
18
+ /// variants in your running program into account. It is possible that the
19
+ /// smaller variants make up less than 1% of all instances, in which case
20
+ /// the overhead is negligible and the boxing is counter-productive. Always
21
+ /// measure the change this lint suggests.
19
22
///
20
23
/// **Example:**
21
24
/// ```rust
@@ -52,8 +55,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LargeEnumVariant {
52
55
let ty = cx. tcx . type_of ( did) ;
53
56
let adt = ty. ty_adt_def ( ) . expect ( "already checked whether this is an enum" ) ;
54
57
55
- let mut smallest_variant: Option < ( _ , _ ) > = None ;
56
58
let mut largest_variant: Option < ( _ , _ ) > = None ;
59
+ let mut second_variant: Option < ( _ , _ ) > = None ;
57
60
58
61
for ( i, variant) in adt. variants . iter ( ) . enumerate ( ) {
59
62
let size: u64 = variant
@@ -69,12 +72,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LargeEnumVariant {
69
72
70
73
let grouped = ( size, ( i, variant) ) ;
71
74
72
- update_if ( & mut smallest_variant, grouped, |a, b| b. 0 <= a. 0 ) ;
73
- update_if ( & mut largest_variant, grouped, |a, b| b. 0 >= a. 0 ) ;
75
+ if grouped. 0 >= largest_variant. map_or ( 0 , |x| x. 0 ) {
76
+ second_variant = largest_variant;
77
+ largest_variant = Some ( grouped) ;
78
+ }
74
79
}
75
80
76
- if let ( Some ( smallest ) , Some ( largest ) ) = ( smallest_variant , largest_variant ) {
77
- let difference = largest. 0 - smallest . 0 ;
81
+ if let ( Some ( largest ) , Some ( second ) ) = ( largest_variant , second_variant ) {
82
+ let difference = largest. 0 - second . 0 ;
78
83
79
84
if difference > self . maximum_size_difference_allowed {
80
85
let ( i, variant) = largest. 1 ;
@@ -114,16 +119,3 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LargeEnumVariant {
114
119
}
115
120
}
116
121
}
117
-
118
- fn update_if < T , F > ( old : & mut Option < T > , new : T , f : F )
119
- where
120
- F : Fn ( & T , & T ) -> bool ,
121
- {
122
- if let Some ( ref mut val) = * old {
123
- if f ( val, & new) {
124
- * val = new;
125
- }
126
- } else {
127
- * old = Some ( new) ;
128
- }
129
- }
0 commit comments