From 69c3e9c90f9a7731dcfe129b10e55e440ee6f484 Mon Sep 17 00:00:00 2001 From: Philipp Hansch Date: Wed, 15 Apr 2020 09:55:02 +0200 Subject: [PATCH] large_enum_variant: Report sizes of variants This reports the sizes of the largest and second-largest variants. --- clippy_lints/src/large_enum_variant.rs | 25 +++++++++++++++++------ tests/ui/large_enum_variant.stderr | 28 ++++++++++++++++++++++---- 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/clippy_lints/src/large_enum_variant.rs b/clippy_lints/src/large_enum_variant.rs index 00bbba648..7ac83739b 100644 --- a/clippy_lints/src/large_enum_variant.rs +++ b/clippy_lints/src/large_enum_variant.rs @@ -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); }, ); } diff --git a/tests/ui/large_enum_variant.stderr b/tests/ui/large_enum_variant.stderr index 5d6596115..8ce641a81 100644 --- a/tests/ui/large_enum_variant.stderr +++ b/tests/ui/large_enum_variant.stderr @@ -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), @@ -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]> },