From e3b5cac3c8d4dcbfd767dc8ba99380ab4ac86a91 Mon Sep 17 00:00:00 2001 From: tamaron Date: Mon, 21 Feb 2022 13:25:53 +0900 Subject: [PATCH] fix --- clippy_lints/src/large_enum_variant.rs | 50 ++++++++++++-------------- tests/ui/large_enum_variant.rs | 24 +++++++++++++ tests/ui/large_enum_variant.stderr | 18 +++++++++- 3 files changed, 64 insertions(+), 28 deletions(-) diff --git a/clippy_lints/src/large_enum_variant.rs b/clippy_lints/src/large_enum_variant.rs index 0191713f60d3..d1dc6b775c56 100644 --- a/clippy_lints/src/large_enum_variant.rs +++ b/clippy_lints/src/large_enum_variant.rs @@ -84,34 +84,30 @@ impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant { if adt.variants.len() <= 1 { return; } - let mut variants_size: Vec = adt - .variants - .iter() - .enumerate() - .map(|(i, variant)| { - let mut fields_size = Vec::new(); - let size: u64 = variant - .fields - .iter() - .enumerate() - .filter_map(|(i, f)| { - let ty = cx.tcx.type_of(f.did); - // don't count generics by filtering out everything - // that does not have a layout - cx.layout_of(ty).ok().map(|l| { - let size = l.size.bytes(); - fields_size.push(FieldInfo { ind: i, size }); - size - }) - }) - .sum(); - VariantInfo { - ind: i, - size, - fields_size, + let mut variants_size: Vec = Vec::new(); + for (i, variant) in adt.variants.iter().enumerate() { + let mut fields_size = Vec::new(); + for (i, f) in variant.fields.iter().enumerate() { + let ty = cx.tcx.type_of(f.did); + // don't lint variants which have a field of generic type. + match cx.layout_of(ty) { + Ok(l) => { + let fsize = l.size.bytes(); + fields_size.push(FieldInfo { ind: i, size: fsize }); + }, + Err(_) => { + return; + }, } - }) - .collect(); + } + let size: u64 = fields_size.iter().map(|info| info.size).sum(); + + variants_size.push(VariantInfo { + ind: i, + size, + fields_size, + }); + } variants_size.sort_by(|a, b| (b.size.cmp(&a.size))); diff --git a/tests/ui/large_enum_variant.rs b/tests/ui/large_enum_variant.rs index b45cc849eaec..cee9e2372c22 100644 --- a/tests/ui/large_enum_variant.rs +++ b/tests/ui/large_enum_variant.rs @@ -74,6 +74,30 @@ enum LargeEnum8 { ContainingMoreThanOneField([i32; 8000], [i32; 2], [i32; 9500], [i32; 30]), } +enum LargeEnum9 { + A(Struct<()>), + B(Struct2), +} + +enum LargeEnumOk2 { + A(T), + B(Struct2), +} + +enum LargeEnumOk3 { + A(Struct), + B(Struct2), +} + +struct Struct { + a: i32, + t: T, +} + +struct Struct2 { + a: [i32; 8000], +} + fn main() { large_enum_variant!(); } diff --git a/tests/ui/large_enum_variant.stderr b/tests/ui/large_enum_variant.stderr index 899f97ce2e1e..cbf2ac972e2b 100644 --- a/tests/ui/large_enum_variant.stderr +++ b/tests/ui/large_enum_variant.stderr @@ -111,5 +111,21 @@ help: consider boxing the large fields to reduce the total size of the enum LL | ContainingMoreThanOneField(Box<[i32; 8000]>, [i32; 2], Box<[i32; 9500]>, [i32; 30]), | ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ -error: aborting due to 7 previous errors +error: large size difference between variants + --> $DIR/large_enum_variant.rs:79:5 + | +LL | B(Struct2), + | ^^^^^^^^^^ this variant is 32000 bytes + | +note: and the second-largest variant is 4 bytes: + --> $DIR/large_enum_variant.rs:78:5 + | +LL | A(Struct<()>), + | ^^^^^^^^^^^^^ +help: consider boxing the large fields to reduce the total size of the enum + | +LL | B(Box), + | ~~~~~~~~~~~~ + +error: aborting due to 8 previous errors