large_enum_variant: Report sizes of variants

This reports the sizes of the largest and second-largest variants.
This commit is contained in:
Philipp Hansch 2020-04-15 09:55:02 +02:00
parent c6cc07a851
commit 69c3e9c90f
No known key found for this signature in database
GPG Key ID: 2B4399C4BF4DCBDE
2 changed files with 43 additions and 10 deletions

View File

@ -21,11 +21,19 @@ declare_clippy_lint! {
/// measure the change this lint suggests.
///
/// **Example:**
///
/// ```rust
/// // Bad
/// enum Test {
/// A(i32),
/// B([i32; 8000]),
/// }
///
/// // Possibly better
/// enum Test2 {
/// A(i32),
/// B(Box<[i32; 8000]>),
/// }
/// ```
pub LARGE_ENUM_VARIANT,
perf,
@ -84,12 +92,21 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LargeEnumVariant {
if difference > self.maximum_size_difference_allowed {
let (i, variant) = largest.1;
let help_text = "consider boxing the large fields to reduce the total size of the enum";
span_lint_and_then(
cx,
LARGE_ENUM_VARIANT,
def.variants[i].span,
"large size difference between variants",
|db| {
db.span_label(
def.variants[(largest.1).0].span,
&format!("this variant is {} bytes", largest.0),
);
db.span_note(
def.variants[(second.1).0].span,
&format!("and the second-largest variant is {} bytes:", second.0),
);
if variant.fields.len() == 1 {
let span = match def.variants[i].data {
VariantData::Struct(ref fields, ..) | VariantData::Tuple(ref fields, ..) => {
@ -100,18 +117,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LargeEnumVariant {
if let Some(snip) = snippet_opt(cx, span) {
db.span_suggestion(
span,
"consider boxing the large fields to reduce the total size of the \
enum",
help_text,
format!("Box<{}>", snip),
Applicability::MaybeIncorrect,
);
return;
}
}
db.span_help(
def.variants[i].span,
"consider boxing the large fields to reduce the total size of the enum",
);
db.span_help(def.variants[i].span, help_text);
},
);
}

View File

@ -2,9 +2,14 @@ error: large size difference between variants
--> $DIR/large_enum_variant.rs:7:5
|
LL | B([i32; 8000]),
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ this variant is 32000 bytes
|
= note: `-D clippy::large-enum-variant` implied by `-D warnings`
note: and the second-largest variant is 4 bytes:
--> $DIR/large_enum_variant.rs:6:5
|
LL | A(i32),
| ^^^^^^
help: consider boxing the large fields to reduce the total size of the enum
|
LL | B(Box<[i32; 8000]>),
@ -14,8 +19,13 @@ error: large size difference between variants
--> $DIR/large_enum_variant.rs:31:5
|
LL | ContainingLargeEnum(LargeEnum),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this variant is 32004 bytes
|
note: and the second-largest variant is 8 bytes:
--> $DIR/large_enum_variant.rs:30:5
|
LL | VariantOk(i32, u32),
| ^^^^^^^^^^^^^^^^^^^
help: consider boxing the large fields to reduce the total size of the enum
|
LL | ContainingLargeEnum(Box<LargeEnum>),
@ -25,8 +35,13 @@ error: large size difference between variants
--> $DIR/large_enum_variant.rs:41:5
|
LL | StructLikeLarge { x: [i32; 8000], y: i32 },
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this variant is 32004 bytes
|
note: and the second-largest variant is 8 bytes:
--> $DIR/large_enum_variant.rs:40:5
|
LL | VariantOk(i32, u32),
| ^^^^^^^^^^^^^^^^^^^
help: consider boxing the large fields to reduce the total size of the enum
--> $DIR/large_enum_variant.rs:41:5
|
@ -37,8 +52,13 @@ error: large size difference between variants
--> $DIR/large_enum_variant.rs:46:5
|
LL | StructLikeLarge2 { x: [i32; 8000] },
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this variant is 32000 bytes
|
note: and the second-largest variant is 8 bytes:
--> $DIR/large_enum_variant.rs:45:5
|
LL | VariantOk(i32, u32),
| ^^^^^^^^^^^^^^^^^^^
help: consider boxing the large fields to reduce the total size of the enum
|
LL | StructLikeLarge2 { x: Box<[i32; 8000]> },