From 9bda699c80a686f9d86a24be5b75d98893e2ca84 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Tue, 31 Jan 2017 08:36:39 +0100 Subject: [PATCH] improve messages and add suggestions --- clippy_lints/src/large_enum_variant.rs | 30 ++++++++++++++++++++---- tests/compile-fail/large_enum_variant.rs | 27 ++++++++++++++++----- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/clippy_lints/src/large_enum_variant.rs b/clippy_lints/src/large_enum_variant.rs index 659275e0105..485266429aa 100644 --- a/clippy_lints/src/large_enum_variant.rs +++ b/clippy_lints/src/large_enum_variant.rs @@ -2,12 +2,12 @@ use rustc::lint::*; use rustc::hir::*; -use utils::span_help_and_lint; +use utils::{span_lint_and_then, snippet_opt}; use rustc::ty::layout::TargetDataLayout; use rustc::ty::TypeFoldable; use rustc::traits::Reveal; -/// **What it does:** Checks for large variants on enums. +/// **What it does:** Checks for large variants on `enum`s. /// /// **Why is this bad?** Enum size is bounded by the largest variant. Having a large variant /// can penalize the memory layout of that enum. @@ -68,11 +68,31 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LargeEnumVariant { }) .sum(); if size > self.maximum_variant_size_allowed { - span_help_and_lint(cx, + span_lint_and_then(cx, LARGE_ENUM_VARIANT, def.variants[i].span, - &format!("large enum variant found on variant `{}`", variant.name), - "consider boxing the large branches to reduce the total size of the enum"); + "large enum variant found", + |db| { + if variant.fields.len() == 1 { + let span = match def.variants[i].node.data { + VariantData::Struct(ref fields, _) | + VariantData::Tuple(ref fields, _) => fields[0].ty.span, + VariantData::Unit(_) => unreachable!(), + }; + 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", + format!("Box<{}>", snip), + ); + return; + } + } + db.span_help( + def.variants[i].span, + "consider boxing the large fields to reduce the total size of the enum", + ); + }); } }); } diff --git a/tests/compile-fail/large_enum_variant.rs b/tests/compile-fail/large_enum_variant.rs index f3c18648115..d4ce3229560 100644 --- a/tests/compile-fail/large_enum_variant.rs +++ b/tests/compile-fail/large_enum_variant.rs @@ -7,14 +7,19 @@ enum LargeEnum { A(i32), - B([i32; 8000]), //~ ERROR large enum variant found on variant `B` + B([i32; 8000]), //~ ERROR large enum variant found + //~^ HELP consider boxing the large fields to reduce the total size of the enum + //~| SUGGESTION Box<[i32; 8000]> } enum GenericEnum { A(i32), - B([i32; 8000]), //~ ERROR large enum variant found on variant `B` + B([i32; 8000]), //~ ERROR large enum variant found + //~^ HELP consider boxing the large fields to reduce the total size of the enum + //~| SUGGESTION Box<[i32; 8000]> C([T; 8000]), - D(T, [i32; 8000]), //~ ERROR large enum variant found on variant `D` + D(T, [i32; 8000]), //~ ERROR large enum variant found + //~^ HELP consider boxing the large fields to reduce the total size of the enum } trait SomeTrait { @@ -27,11 +32,21 @@ enum LargeEnumGeneric { enum AnotherLargeEnum { VariantOk(i32, u32), - ContainingLargeEnum(LargeEnum), //~ ERROR large enum variant found on variant `ContainingLargeEnum` - ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]), //~ ERROR large enum variant found on variant `ContainingMoreThanOneField` + ContainingLargeEnum(LargeEnum), //~ ERROR large enum variant found + //~^ HELP consider boxing the large fields to reduce the total size of the enum + //~| SUGGESTION Box + ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]), //~ ERROR large enum variant found + //~^ HELP consider boxing the large fields to reduce the total size of the enum VoidVariant, StructLikeLittle { x: i32, y: i32 }, - StructLikeLarge { x: [i32; 8000], y: i32 }, //~ ERROR large enum variant found on variant `StructLikeLarge` + StructLikeLarge { x: [i32; 8000], y: i32 }, //~ ERROR large enum variant found + //~^ HELP consider boxing the large fields to reduce the total size of the enum + StructLikeLarge2 { + x: + [i32; 8000] //~ SUGGESTION Box<[i32; 8000]> + }, + //~^ ERROR large enum variant found + //~^ HELP consider boxing the large fields to reduce the total size of the enum } fn main() {