]> git.lizzy.rs Git - rust.git/commitdiff
large_enum_variant: Report sizes of variants
authorPhilipp Hansch <dev@phansch.net>
Wed, 15 Apr 2020 07:55:02 +0000 (09:55 +0200)
committerPhilipp Hansch <dev@phansch.net>
Wed, 15 Apr 2020 07:56:32 +0000 (09:56 +0200)
This reports the sizes of the largest and second-largest variants.

clippy_lints/src/large_enum_variant.rs
tests/ui/large_enum_variant.stderr

index 00bbba64841a997b5eabd36c4f9d67c955413414..7ac83739be67bd6bb9286db8c705d4a7d0fec3ba 100644 (file)
     /// 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 @@ fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &Item<'_>) {
                 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 @@ fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &Item<'_>) {
                                 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);
                         },
                     );
                 }
index 5d659611533a5c42450e753a88317af8828f7eeb..8ce641a81f29746289c9b750b11cad95ba133cf2 100644 (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]> },