Calculate the 2 largest variants using iterators

No need to store all sizes in a vector
This commit is contained in:
Jonas Schievink 2016-07-11 01:43:55 +02:00
parent 66fb62baf7
commit dd0505cefc
1 changed files with 21 additions and 20 deletions

View File

@ -697,7 +697,6 @@ impl LateLintPass for VariantSizeDifferences {
fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
if let hir::ItemEnum(ref enum_definition, ref gens) = it.node {
if gens.ty_params.is_empty() { // sizes only make sense for non-generic types
let mut sizes = vec![];
let t = cx.tcx.node_id_to_type(it.id);
let layout = cx.tcx.normalizing_infer_ctxt(ProjectionMode::Any).enter(|infcx| {
t.layout(&infcx).unwrap_or_else(|e| {
@ -710,26 +709,28 @@ impl LateLintPass for VariantSizeDifferences {
debug!("enum `{}` is {} bytes large", t, size.bytes());
for (variant, variant_layout) in enum_definition.variants.iter().zip(variants) {
// Subtract the size of the enum discriminant
let bytes = variant_layout.min_size().bytes().saturating_sub(discr_size);
sizes.push(bytes);
let (largest, slargest, largest_index) = enum_definition.variants
.iter()
.zip(variants)
.map(|(variant, variant_layout)| {
// Subtract the size of the enum discriminant
let bytes = variant_layout.min_size().bytes()
.saturating_sub(discr_size);
debug!("- variant `{}` is {} bytes large", variant.node.name, bytes);
}
let (largest, slargest, largest_index) = sizes.iter()
.enumerate()
.fold((0, 0, 0),
|(l, s, li), (idx, &size)|
if size > l {
(size, l, idx)
} else if size > s {
(l, size, li)
} else {
(l, s, li)
}
);
debug!("- variant `{}` is {} bytes large", variant.node.name, bytes);
bytes
})
.enumerate()
.fold((0, 0, 0),
|(l, s, li), (idx, size)|
if size > l {
(size, l, idx)
} else if size > s {
(l, size, li)
} else {
(l, s, li)
}
);
// we only warn if the largest variant is at least thrice as large as
// the second-largest.