mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-24 05:33:27 +00:00
Use approx_ty_size
for large_enum_variant
This commit is contained in:
parent
30e4532153
commit
584000a792
6 changed files with 269 additions and 141 deletions
|
@ -1,13 +1,12 @@
|
||||||
//! lint when there is a large size difference between variants on an enum
|
//! lint when there is a large size difference between variants on an enum
|
||||||
|
|
||||||
use clippy_utils::source::snippet_with_applicability;
|
use clippy_utils::source::snippet_with_applicability;
|
||||||
use clippy_utils::{diagnostics::span_lint_and_then, ty::is_copy};
|
use clippy_utils::{diagnostics::span_lint_and_then, ty::approx_ty_size, ty::is_copy};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{Item, ItemKind};
|
use rustc_hir::{Item, ItemKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::lint::in_external_macro;
|
use rustc_middle::lint::in_external_macro;
|
||||||
use rustc_middle::ty::layout::LayoutOf;
|
use rustc_middle::ty::{Adt, AdtDef, GenericArg, List, Ty};
|
||||||
use rustc_middle::ty::{Adt, Ty};
|
|
||||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||||
use rustc_span::source_map::Span;
|
use rustc_span::source_map::Span;
|
||||||
|
|
||||||
|
@ -17,7 +16,7 @@ declare_clippy_lint! {
|
||||||
/// `enum`s.
|
/// `enum`s.
|
||||||
///
|
///
|
||||||
/// ### Why is this bad?
|
/// ### Why is this bad?
|
||||||
/// Enum size is bounded by the largest variant. Having a
|
/// Enum size is bounded by the largest variant. Having one
|
||||||
/// large variant can penalize the memory layout of that enum.
|
/// large variant can penalize the memory layout of that enum.
|
||||||
///
|
///
|
||||||
/// ### Known problems
|
/// ### Known problems
|
||||||
|
@ -33,8 +32,9 @@ declare_clippy_lint! {
|
||||||
/// use case it may be possible to store the large data in an auxiliary
|
/// use case it may be possible to store the large data in an auxiliary
|
||||||
/// structure (e.g. Arena or ECS).
|
/// structure (e.g. Arena or ECS).
|
||||||
///
|
///
|
||||||
/// The lint will ignore generic types if the layout depends on the
|
/// The lint will ignore the impact of generic types to the type layout by
|
||||||
/// generics, even if the size difference will be large anyway.
|
/// assuming every type parameter is zero-sized. Depending on your use case,
|
||||||
|
/// this may lead to a false positive.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust
|
/// ```rust
|
||||||
|
@ -83,6 +83,38 @@ struct VariantInfo {
|
||||||
fields_size: Vec<FieldInfo>,
|
fields_size: Vec<FieldInfo>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn variants_size<'tcx>(
|
||||||
|
cx: &LateContext<'tcx>,
|
||||||
|
adt: AdtDef<'tcx>,
|
||||||
|
subst: &'tcx List<GenericArg<'tcx>>,
|
||||||
|
) -> Vec<VariantInfo> {
|
||||||
|
let mut variants_size = adt
|
||||||
|
.variants()
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, variant)| {
|
||||||
|
let mut fields_size = variant
|
||||||
|
.fields
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, f)| FieldInfo {
|
||||||
|
ind: i,
|
||||||
|
size: approx_ty_size(cx, f.ty(cx.tcx, subst)),
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
fields_size.sort_by(|a, b| (a.size.cmp(&b.size)));
|
||||||
|
|
||||||
|
VariantInfo {
|
||||||
|
ind: i,
|
||||||
|
size: fields_size.iter().map(|info| info.size).sum(),
|
||||||
|
fields_size,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
variants_size.sort_by(|a, b| (b.size.cmp(&a.size)));
|
||||||
|
variants_size
|
||||||
|
}
|
||||||
|
|
||||||
impl_lint_pass!(LargeEnumVariant => [LARGE_ENUM_VARIANT]);
|
impl_lint_pass!(LargeEnumVariant => [LARGE_ENUM_VARIANT]);
|
||||||
|
|
||||||
impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant {
|
impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant {
|
||||||
|
@ -92,36 +124,14 @@ impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant {
|
||||||
}
|
}
|
||||||
if let ItemKind::Enum(ref def, _) = item.kind {
|
if let ItemKind::Enum(ref def, _) = item.kind {
|
||||||
let ty = cx.tcx.type_of(item.def_id);
|
let ty = cx.tcx.type_of(item.def_id);
|
||||||
let adt = ty.ty_adt_def().expect("already checked whether this is an enum");
|
let (adt, subst) = match ty.kind() {
|
||||||
|
Adt(adt, subst) => (adt, subst),
|
||||||
|
_ => panic!("already checked whether this is an enum"),
|
||||||
|
};
|
||||||
if adt.variants().len() <= 1 {
|
if adt.variants().len() <= 1 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let mut variants_size: Vec<VariantInfo> = Vec::new();
|
let variants_size = variants_size(cx, *adt, subst);
|
||||||
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;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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)));
|
|
||||||
|
|
||||||
let mut difference = variants_size[0].size - variants_size[1].size;
|
let mut difference = variants_size[0].size - variants_size[1].size;
|
||||||
if difference > self.maximum_size_difference_allowed {
|
if difference > self.maximum_size_difference_allowed {
|
||||||
|
@ -129,20 +139,30 @@ impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant {
|
||||||
span_lint_and_then(
|
span_lint_and_then(
|
||||||
cx,
|
cx,
|
||||||
LARGE_ENUM_VARIANT,
|
LARGE_ENUM_VARIANT,
|
||||||
def.variants[variants_size[0].ind].span,
|
item.span,
|
||||||
"large size difference between variants",
|
"large size difference between variants",
|
||||||
|diag| {
|
|diag| {
|
||||||
diag.span_label(
|
diag.span_label(
|
||||||
def.variants[variants_size[0].ind].span,
|
item.span,
|
||||||
&format!("this variant is {} bytes", variants_size[0].size),
|
format!("the entire enum is at least {} bytes", approx_ty_size(cx, ty)),
|
||||||
);
|
);
|
||||||
diag.span_note(
|
diag.span_label(
|
||||||
|
def.variants[variants_size[0].ind].span,
|
||||||
|
format!("the largest variant contains at least {} bytes", variants_size[0].size),
|
||||||
|
);
|
||||||
|
diag.span_label(
|
||||||
def.variants[variants_size[1].ind].span,
|
def.variants[variants_size[1].ind].span,
|
||||||
&format!("and the second-largest variant is {} bytes:", variants_size[1].size),
|
&if variants_size[1].fields_size.is_empty() {
|
||||||
|
"the second-largest variant carries no data at all".to_owned()
|
||||||
|
} else {
|
||||||
|
format!(
|
||||||
|
"the second-largest variant contains at least {} bytes",
|
||||||
|
variants_size[1].size
|
||||||
|
)
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
let fields = def.variants[variants_size[0].ind].data.fields();
|
let fields = def.variants[variants_size[0].ind].data.fields();
|
||||||
variants_size[0].fields_size.sort_by(|a, b| (a.size.cmp(&b.size)));
|
|
||||||
let mut applicability = Applicability::MaybeIncorrect;
|
let mut applicability = Applicability::MaybeIncorrect;
|
||||||
if is_copy(cx, ty) || maybe_copy(cx, ty) {
|
if is_copy(cx, ty) || maybe_copy(cx, ty) {
|
||||||
diag.span_note(
|
diag.span_note(
|
||||||
|
|
|
@ -3,7 +3,7 @@ Checks for large size differences between variants on
|
||||||
`enum`s.
|
`enum`s.
|
||||||
|
|
||||||
### Why is this bad?
|
### Why is this bad?
|
||||||
Enum size is bounded by the largest variant. Having a
|
Enum size is bounded by the largest variant. Having one
|
||||||
large variant can penalize the memory layout of that enum.
|
large variant can penalize the memory layout of that enum.
|
||||||
|
|
||||||
### Known problems
|
### Known problems
|
||||||
|
@ -19,8 +19,9 @@ still be `Clone`, but that is worse ergonomically. Depending on the
|
||||||
use case it may be possible to store the large data in an auxiliary
|
use case it may be possible to store the large data in an auxiliary
|
||||||
structure (e.g. Arena or ECS).
|
structure (e.g. Arena or ECS).
|
||||||
|
|
||||||
The lint will ignore generic types if the layout depends on the
|
The lint will ignore the impact of generic types to the type layout by
|
||||||
generics, even if the size difference will be large anyway.
|
assuming every type parameter is zero-sized. Depending on your use case,
|
||||||
|
this may lead to a false positive.
|
||||||
|
|
||||||
### Example
|
### Example
|
||||||
```
|
```
|
||||||
|
|
|
@ -130,6 +130,30 @@ impl<T: Copy> Clone for SomeGenericPossiblyCopyEnum<T> {
|
||||||
|
|
||||||
impl<T: Copy> Copy for SomeGenericPossiblyCopyEnum<T> {}
|
impl<T: Copy> Copy for SomeGenericPossiblyCopyEnum<T> {}
|
||||||
|
|
||||||
|
enum LargeEnumWithGenerics<T> {
|
||||||
|
Small,
|
||||||
|
Large((T, [u8; 512])),
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Foo<T> {
|
||||||
|
foo: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum WithGenerics {
|
||||||
|
Large([Foo<u64>; 64]),
|
||||||
|
Small(u8),
|
||||||
|
}
|
||||||
|
|
||||||
|
enum PossiblyLargeEnumWithConst<const U: usize> {
|
||||||
|
SmallBuffer([u8; 4]),
|
||||||
|
MightyBuffer([u16; U]),
|
||||||
|
}
|
||||||
|
|
||||||
|
enum LargeEnumOfConst {
|
||||||
|
Ok,
|
||||||
|
Error(PossiblyLargeEnumWithConst<256>),
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
large_enum_variant!();
|
large_enum_variant!();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,143 +1,177 @@
|
||||||
error: large size difference between variants
|
error: large size difference between variants
|
||||||
--> $DIR/large_enum_variant.rs:12:5
|
--> $DIR/large_enum_variant.rs:10:1
|
||||||
|
|
|
|
||||||
LL | B([i32; 8000]),
|
LL | / enum LargeEnum {
|
||||||
| ^^^^^^^^^^^^^^ this variant is 32000 bytes
|
LL | | A(i32),
|
||||||
|
| | ------ the second-largest variant contains at least 4 bytes
|
||||||
|
LL | | B([i32; 8000]),
|
||||||
|
| | -------------- the largest variant contains at least 32000 bytes
|
||||||
|
LL | | }
|
||||||
|
| |_^ the entire enum is at least 32004 bytes
|
||||||
|
|
|
|
||||||
= note: `-D clippy::large-enum-variant` implied by `-D warnings`
|
= note: `-D clippy::large-enum-variant` implied by `-D warnings`
|
||||||
note: and the second-largest variant is 4 bytes:
|
|
||||||
--> $DIR/large_enum_variant.rs:11:5
|
|
||||||
|
|
|
||||||
LL | A(i32),
|
|
||||||
| ^^^^^^
|
|
||||||
help: consider boxing the large fields to reduce the total size of the enum
|
help: consider boxing the large fields to reduce the total size of the enum
|
||||||
|
|
|
|
||||||
LL | B(Box<[i32; 8000]>),
|
LL | B(Box<[i32; 8000]>),
|
||||||
| ~~~~~~~~~~~~~~~~
|
| ~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: large size difference between variants
|
error: large size difference between variants
|
||||||
--> $DIR/large_enum_variant.rs:36:5
|
--> $DIR/large_enum_variant.rs:34:1
|
||||||
|
|
|
|
||||||
LL | ContainingLargeEnum(LargeEnum),
|
LL | / enum LargeEnum2 {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this variant is 32004 bytes
|
LL | | VariantOk(i32, u32),
|
||||||
|
| | ------------------- the second-largest variant contains at least 8 bytes
|
||||||
|
LL | | ContainingLargeEnum(LargeEnum),
|
||||||
|
| | ------------------------------ the largest variant contains at least 32004 bytes
|
||||||
|
LL | | }
|
||||||
|
| |_^ the entire enum is at least 32008 bytes
|
||||||
|
|
|
|
||||||
note: and the second-largest variant is 8 bytes:
|
|
||||||
--> $DIR/large_enum_variant.rs:35:5
|
|
||||||
|
|
|
||||||
LL | VariantOk(i32, u32),
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
|
||||||
help: consider boxing the large fields to reduce the total size of the enum
|
help: consider boxing the large fields to reduce the total size of the enum
|
||||||
|
|
|
|
||||||
LL | ContainingLargeEnum(Box<LargeEnum>),
|
LL | ContainingLargeEnum(Box<LargeEnum>),
|
||||||
| ~~~~~~~~~~~~~~
|
| ~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: large size difference between variants
|
error: large size difference between variants
|
||||||
--> $DIR/large_enum_variant.rs:40:5
|
--> $DIR/large_enum_variant.rs:39:1
|
||||||
|
|
|
|
||||||
LL | ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]),
|
LL | / enum LargeEnum3 {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this variant is 70004 bytes
|
LL | | ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]),
|
||||||
|
| | --------------------------------------------------------- the largest variant contains at least 70004 bytes
|
||||||
|
LL | | VoidVariant,
|
||||||
|
LL | | StructLikeLittle { x: i32, y: i32 },
|
||||||
|
| | ----------------------------------- the second-largest variant contains at least 8 bytes
|
||||||
|
LL | | }
|
||||||
|
| |_^ the entire enum is at least 70008 bytes
|
||||||
|
|
|
|
||||||
note: and the second-largest variant is 8 bytes:
|
|
||||||
--> $DIR/large_enum_variant.rs:42:5
|
|
||||||
|
|
|
||||||
LL | StructLikeLittle { x: i32, y: i32 },
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
help: consider boxing the large fields to reduce the total size of the enum
|
help: consider boxing the large fields to reduce the total size of the enum
|
||||||
|
|
|
|
||||||
LL | ContainingMoreThanOneField(i32, Box<[i32; 8000]>, Box<[i32; 9500]>),
|
LL | ContainingMoreThanOneField(i32, Box<[i32; 8000]>, Box<[i32; 9500]>),
|
||||||
| ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
|
| ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: large size difference between variants
|
error: large size difference between variants
|
||||||
--> $DIR/large_enum_variant.rs:47:5
|
--> $DIR/large_enum_variant.rs:45:1
|
||||||
|
|
|
|
||||||
LL | StructLikeLarge { x: [i32; 8000], y: i32 },
|
LL | / enum LargeEnum4 {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this variant is 32004 bytes
|
LL | | VariantOk(i32, u32),
|
||||||
|
| | ------------------- the second-largest variant contains at least 8 bytes
|
||||||
|
LL | | StructLikeLarge { x: [i32; 8000], y: i32 },
|
||||||
|
| | ------------------------------------------ the largest variant contains at least 32004 bytes
|
||||||
|
LL | | }
|
||||||
|
| |_^ the entire enum is at least 32008 bytes
|
||||||
|
|
|
|
||||||
note: and the second-largest variant is 8 bytes:
|
|
||||||
--> $DIR/large_enum_variant.rs:46:5
|
|
||||||
|
|
|
||||||
LL | VariantOk(i32, u32),
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
|
||||||
help: consider boxing the large fields to reduce the total size of the enum
|
help: consider boxing the large fields to reduce the total size of the enum
|
||||||
|
|
|
|
||||||
LL | StructLikeLarge { x: Box<[i32; 8000]>, y: i32 },
|
LL | StructLikeLarge { x: Box<[i32; 8000]>, y: i32 },
|
||||||
| ~~~~~~~~~~~~~~~~
|
| ~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: large size difference between variants
|
error: large size difference between variants
|
||||||
--> $DIR/large_enum_variant.rs:52:5
|
--> $DIR/large_enum_variant.rs:50:1
|
||||||
|
|
|
|
||||||
LL | StructLikeLarge2 { x: [i32; 8000] },
|
LL | / enum LargeEnum5 {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this variant is 32000 bytes
|
LL | | VariantOk(i32, u32),
|
||||||
|
| | ------------------- the second-largest variant contains at least 8 bytes
|
||||||
|
LL | | StructLikeLarge2 { x: [i32; 8000] },
|
||||||
|
| | ----------------------------------- the largest variant contains at least 32000 bytes
|
||||||
|
LL | | }
|
||||||
|
| |_^ the entire enum is at least 32004 bytes
|
||||||
|
|
|
|
||||||
note: and the second-largest variant is 8 bytes:
|
|
||||||
--> $DIR/large_enum_variant.rs:51:5
|
|
||||||
|
|
|
||||||
LL | VariantOk(i32, u32),
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
|
||||||
help: consider boxing the large fields to reduce the total size of the enum
|
help: consider boxing the large fields to reduce the total size of the enum
|
||||||
|
|
|
|
||||||
LL | StructLikeLarge2 { x: Box<[i32; 8000]> },
|
LL | StructLikeLarge2 { x: Box<[i32; 8000]> },
|
||||||
| ~~~~~~~~~~~~~~~~
|
| ~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: large size difference between variants
|
error: large size difference between variants
|
||||||
--> $DIR/large_enum_variant.rs:68:5
|
--> $DIR/large_enum_variant.rs:66:1
|
||||||
|
|
|
|
||||||
LL | B([u8; 1255]),
|
LL | / enum LargeEnum7 {
|
||||||
| ^^^^^^^^^^^^^ this variant is 1255 bytes
|
LL | | A,
|
||||||
|
LL | | B([u8; 1255]),
|
||||||
|
| | ------------- the largest variant contains at least 1255 bytes
|
||||||
|
LL | | C([u8; 200]),
|
||||||
|
| | ------------ the second-largest variant contains at least 200 bytes
|
||||||
|
LL | | }
|
||||||
|
| |_^ the entire enum is at least 1256 bytes
|
||||||
|
|
|
|
||||||
note: and the second-largest variant is 200 bytes:
|
|
||||||
--> $DIR/large_enum_variant.rs:69:5
|
|
||||||
|
|
|
||||||
LL | C([u8; 200]),
|
|
||||||
| ^^^^^^^^^^^^
|
|
||||||
help: consider boxing the large fields to reduce the total size of the enum
|
help: consider boxing the large fields to reduce the total size of the enum
|
||||||
|
|
|
|
||||||
LL | B(Box<[u8; 1255]>),
|
LL | B(Box<[u8; 1255]>),
|
||||||
| ~~~~~~~~~~~~~~~
|
| ~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: large size difference between variants
|
error: large size difference between variants
|
||||||
--> $DIR/large_enum_variant.rs:74:5
|
--> $DIR/large_enum_variant.rs:72:1
|
||||||
|
|
|
|
||||||
LL | ContainingMoreThanOneField([i32; 8000], [i32; 2], [i32; 9500], [i32; 30]),
|
LL | / enum LargeEnum8 {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this variant is 70128 bytes
|
LL | | VariantOk(i32, u32),
|
||||||
|
| | ------------------- the second-largest variant contains at least 8 bytes
|
||||||
|
LL | | ContainingMoreThanOneField([i32; 8000], [i32; 2], [i32; 9500], [i32; 30]),
|
||||||
|
| | ------------------------------------------------------------------------- the largest variant contains at least 70128 bytes
|
||||||
|
LL | | }
|
||||||
|
| |_^ the entire enum is at least 70132 bytes
|
||||||
|
|
|
|
||||||
note: and the second-largest variant is 8 bytes:
|
|
||||||
--> $DIR/large_enum_variant.rs:73:5
|
|
||||||
|
|
|
||||||
LL | VariantOk(i32, u32),
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
|
||||||
help: consider boxing the large fields to reduce the total size of the enum
|
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]),
|
LL | ContainingMoreThanOneField(Box<[i32; 8000]>, [i32; 2], Box<[i32; 9500]>, [i32; 30]),
|
||||||
| ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
|
| ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: large size difference between variants
|
error: large size difference between variants
|
||||||
--> $DIR/large_enum_variant.rs:79:5
|
--> $DIR/large_enum_variant.rs:77:1
|
||||||
|
|
|
|
||||||
LL | B(Struct2),
|
LL | / enum LargeEnum9 {
|
||||||
| ^^^^^^^^^^ this variant is 32000 bytes
|
LL | | A(Struct<()>),
|
||||||
|
| | ------------- the second-largest variant contains at least 4 bytes
|
||||||
|
LL | | B(Struct2),
|
||||||
|
| | ---------- the largest variant contains at least 32000 bytes
|
||||||
|
LL | | }
|
||||||
|
| |_^ the entire enum is at least 32004 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
|
help: consider boxing the large fields to reduce the total size of the enum
|
||||||
|
|
|
|
||||||
LL | B(Box<Struct2>),
|
LL | B(Box<Struct2>),
|
||||||
| ~~~~~~~~~~~~
|
| ~~~~~~~~~~~~
|
||||||
|
|
||||||
error: large size difference between variants
|
error: large size difference between variants
|
||||||
--> $DIR/large_enum_variant.rs:104:5
|
--> $DIR/large_enum_variant.rs:82:1
|
||||||
|
|
|
|
||||||
LL | B([u128; 4000]),
|
LL | / enum LargeEnumOk2<T> {
|
||||||
| ^^^^^^^^^^^^^^^ this variant is 64000 bytes
|
LL | | A(T),
|
||||||
|
| | ---- the second-largest variant contains at least 0 bytes
|
||||||
|
LL | | B(Struct2),
|
||||||
|
| | ---------- the largest variant contains at least 32000 bytes
|
||||||
|
LL | | }
|
||||||
|
| |_^ the entire enum is at least 32000 bytes
|
||||||
|
|
|
|
||||||
note: and the second-largest variant is 1 bytes:
|
help: consider boxing the large fields to reduce the total size of the enum
|
||||||
--> $DIR/large_enum_variant.rs:103:5
|
|
|
||||||
|
LL | B(Box<Struct2>),
|
||||||
|
| ~~~~~~~~~~~~
|
||||||
|
|
||||||
|
error: large size difference between variants
|
||||||
|
--> $DIR/large_enum_variant.rs:87:1
|
||||||
|
|
|
||||||
|
LL | / enum LargeEnumOk3<T> {
|
||||||
|
LL | | A(Struct<T>),
|
||||||
|
| | ------------ the second-largest variant contains at least 4 bytes
|
||||||
|
LL | | B(Struct2),
|
||||||
|
| | ---------- the largest variant contains at least 32000 bytes
|
||||||
|
LL | | }
|
||||||
|
| |_^ the entire enum is at least 32000 bytes
|
||||||
|
|
|
||||||
|
help: consider boxing the large fields to reduce the total size of the enum
|
||||||
|
|
|
||||||
|
LL | B(Box<Struct2>),
|
||||||
|
| ~~~~~~~~~~~~
|
||||||
|
|
||||||
|
error: large size difference between variants
|
||||||
|
--> $DIR/large_enum_variant.rs:102:1
|
||||||
|
|
|
||||||
|
LL | / enum CopyableLargeEnum {
|
||||||
|
LL | | A(bool),
|
||||||
|
| | ------- the second-largest variant contains at least 1 bytes
|
||||||
|
LL | | B([u128; 4000]),
|
||||||
|
| | --------------- the largest variant contains at least 64000 bytes
|
||||||
|
LL | | }
|
||||||
|
| |_^ the entire enum is at least 64008 bytes
|
||||||
|
|
|
|
||||||
LL | A(bool),
|
|
||||||
| ^^^^^^^
|
|
||||||
note: boxing a variant would require the type no longer be `Copy`
|
note: boxing a variant would require the type no longer be `Copy`
|
||||||
--> $DIR/large_enum_variant.rs:102:6
|
--> $DIR/large_enum_variant.rs:102:6
|
||||||
|
|
|
|
||||||
|
@ -150,16 +184,16 @@ LL | B([u128; 4000]),
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: large size difference between variants
|
error: large size difference between variants
|
||||||
--> $DIR/large_enum_variant.rs:109:5
|
--> $DIR/large_enum_variant.rs:107:1
|
||||||
|
|
|
|
||||||
LL | B([u128; 4000]),
|
LL | / enum ManuallyCopyLargeEnum {
|
||||||
| ^^^^^^^^^^^^^^^ this variant is 64000 bytes
|
LL | | A(bool),
|
||||||
|
| | ------- the second-largest variant contains at least 1 bytes
|
||||||
|
LL | | B([u128; 4000]),
|
||||||
|
| | --------------- the largest variant contains at least 64000 bytes
|
||||||
|
LL | | }
|
||||||
|
| |_^ the entire enum is at least 64008 bytes
|
||||||
|
|
|
|
||||||
note: and the second-largest variant is 1 bytes:
|
|
||||||
--> $DIR/large_enum_variant.rs:108:5
|
|
||||||
|
|
|
||||||
LL | A(bool),
|
|
||||||
| ^^^^^^^
|
|
||||||
note: boxing a variant would require the type no longer be `Copy`
|
note: boxing a variant would require the type no longer be `Copy`
|
||||||
--> $DIR/large_enum_variant.rs:107:6
|
--> $DIR/large_enum_variant.rs:107:6
|
||||||
|
|
|
|
||||||
|
@ -172,16 +206,16 @@ LL | B([u128; 4000]),
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: large size difference between variants
|
error: large size difference between variants
|
||||||
--> $DIR/large_enum_variant.rs:122:5
|
--> $DIR/large_enum_variant.rs:120:1
|
||||||
|
|
|
|
||||||
LL | B([u64; 4000]),
|
LL | / enum SomeGenericPossiblyCopyEnum<T> {
|
||||||
| ^^^^^^^^^^^^^^ this variant is 32000 bytes
|
LL | | A(bool, std::marker::PhantomData<T>),
|
||||||
|
| | ------------------------------------ the second-largest variant contains at least 1 bytes
|
||||||
|
LL | | B([u64; 4000]),
|
||||||
|
| | -------------- the largest variant contains at least 32000 bytes
|
||||||
|
LL | | }
|
||||||
|
| |_^ the entire enum is at least 32008 bytes
|
||||||
|
|
|
|
||||||
note: and the second-largest variant is 1 bytes:
|
|
||||||
--> $DIR/large_enum_variant.rs:121:5
|
|
||||||
|
|
|
||||||
LL | A(bool, std::marker::PhantomData<T>),
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
note: boxing a variant would require the type no longer be `Copy`
|
note: boxing a variant would require the type no longer be `Copy`
|
||||||
--> $DIR/large_enum_variant.rs:120:6
|
--> $DIR/large_enum_variant.rs:120:6
|
||||||
|
|
|
|
||||||
|
@ -193,5 +227,53 @@ help: consider boxing the large fields to reduce the total size of the enum
|
||||||
LL | B([u64; 4000]),
|
LL | B([u64; 4000]),
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 11 previous errors
|
error: large size difference between variants
|
||||||
|
--> $DIR/large_enum_variant.rs:133:1
|
||||||
|
|
|
||||||
|
LL | / enum LargeEnumWithGenerics<T> {
|
||||||
|
LL | | Small,
|
||||||
|
| | ----- the second-largest variant carries no data at all
|
||||||
|
LL | | Large((T, [u8; 512])),
|
||||||
|
| | --------------------- the largest variant contains at least 512 bytes
|
||||||
|
LL | | }
|
||||||
|
| |_^ the entire enum is at least 512 bytes
|
||||||
|
|
|
||||||
|
help: consider boxing the large fields to reduce the total size of the enum
|
||||||
|
|
|
||||||
|
LL | Large(Box<(T, [u8; 512])>),
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
error: large size difference between variants
|
||||||
|
--> $DIR/large_enum_variant.rs:142:1
|
||||||
|
|
|
||||||
|
LL | / enum WithGenerics {
|
||||||
|
LL | | Large([Foo<u64>; 64]),
|
||||||
|
| | --------------------- the largest variant contains at least 512 bytes
|
||||||
|
LL | | Small(u8),
|
||||||
|
| | --------- the second-largest variant contains at least 1 bytes
|
||||||
|
LL | | }
|
||||||
|
| |_^ the entire enum is at least 520 bytes
|
||||||
|
|
|
||||||
|
help: consider boxing the large fields to reduce the total size of the enum
|
||||||
|
|
|
||||||
|
LL | Large(Box<[Foo<u64>; 64]>),
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
error: large size difference between variants
|
||||||
|
--> $DIR/large_enum_variant.rs:152:1
|
||||||
|
|
|
||||||
|
LL | / enum LargeEnumOfConst {
|
||||||
|
LL | | Ok,
|
||||||
|
| | -- the second-largest variant carries no data at all
|
||||||
|
LL | | Error(PossiblyLargeEnumWithConst<256>),
|
||||||
|
| | -------------------------------------- the largest variant contains at least 514 bytes
|
||||||
|
LL | | }
|
||||||
|
| |_^ the entire enum is at least 514 bytes
|
||||||
|
|
|
||||||
|
help: consider boxing the large fields to reduce the total size of the enum
|
||||||
|
|
|
||||||
|
LL | Error(Box<PossiblyLargeEnumWithConst<256>>),
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
error: aborting due to 16 previous errors
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#![warn(clippy::result_large_err)]
|
#![warn(clippy::result_large_err)]
|
||||||
|
#![allow(clippy::large_enum_variant)]
|
||||||
|
|
||||||
pub fn small_err() -> Result<(), u128> {
|
pub fn small_err() -> Result<(), u128> {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: the `Err`-variant returned from this function is very large
|
error: the `Err`-variant returned from this function is very large
|
||||||
--> $DIR/result_large_err.rs:7:23
|
--> $DIR/result_large_err.rs:8:23
|
||||||
|
|
|
|
||||||
LL | pub fn large_err() -> Result<(), [u8; 512]> {
|
LL | pub fn large_err() -> Result<(), [u8; 512]> {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes
|
| ^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes
|
||||||
|
@ -8,7 +8,7 @@ LL | pub fn large_err() -> Result<(), [u8; 512]> {
|
||||||
= help: try reducing the size of `[u8; 512]`, for example by boxing large elements or replacing it with `Box<[u8; 512]>`
|
= help: try reducing the size of `[u8; 512]`, for example by boxing large elements or replacing it with `Box<[u8; 512]>`
|
||||||
|
|
||||||
error: the `Err`-variant returned from this function is very large
|
error: the `Err`-variant returned from this function is very large
|
||||||
--> $DIR/result_large_err.rs:18:21
|
--> $DIR/result_large_err.rs:19:21
|
||||||
|
|
|
|
||||||
LL | pub fn ret() -> Result<(), Self> {
|
LL | pub fn ret() -> Result<(), Self> {
|
||||||
| ^^^^^^^^^^^^^^^^ the `Err`-variant is at least 240 bytes
|
| ^^^^^^^^^^^^^^^^ the `Err`-variant is at least 240 bytes
|
||||||
|
@ -16,7 +16,7 @@ LL | pub fn ret() -> Result<(), Self> {
|
||||||
= help: try reducing the size of `FullyDefinedLargeError`, for example by boxing large elements or replacing it with `Box<FullyDefinedLargeError>`
|
= help: try reducing the size of `FullyDefinedLargeError`, for example by boxing large elements or replacing it with `Box<FullyDefinedLargeError>`
|
||||||
|
|
||||||
error: the `Err`-variant returned from this function is very large
|
error: the `Err`-variant returned from this function is very large
|
||||||
--> $DIR/result_large_err.rs:23:26
|
--> $DIR/result_large_err.rs:24:26
|
||||||
|
|
|
|
||||||
LL | pub fn struct_error() -> Result<(), FullyDefinedLargeError> {
|
LL | pub fn struct_error() -> Result<(), FullyDefinedLargeError> {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 240 bytes
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 240 bytes
|
||||||
|
@ -24,7 +24,7 @@ LL | pub fn struct_error() -> Result<(), FullyDefinedLargeError> {
|
||||||
= help: try reducing the size of `FullyDefinedLargeError`, for example by boxing large elements or replacing it with `Box<FullyDefinedLargeError>`
|
= help: try reducing the size of `FullyDefinedLargeError`, for example by boxing large elements or replacing it with `Box<FullyDefinedLargeError>`
|
||||||
|
|
||||||
error: the `Err`-variant returned from this function is very large
|
error: the `Err`-variant returned from this function is very large
|
||||||
--> $DIR/result_large_err.rs:28:45
|
--> $DIR/result_large_err.rs:29:45
|
||||||
|
|
|
|
||||||
LL | pub fn large_err_via_type_alias<T>(x: T) -> Fdlr<T> {
|
LL | pub fn large_err_via_type_alias<T>(x: T) -> Fdlr<T> {
|
||||||
| ^^^^^^^ the `Err`-variant is at least 240 bytes
|
| ^^^^^^^ the `Err`-variant is at least 240 bytes
|
||||||
|
@ -32,7 +32,7 @@ LL | pub fn large_err_via_type_alias<T>(x: T) -> Fdlr<T> {
|
||||||
= help: try reducing the size of `FullyDefinedLargeError`, for example by boxing large elements or replacing it with `Box<FullyDefinedLargeError>`
|
= help: try reducing the size of `FullyDefinedLargeError`, for example by boxing large elements or replacing it with `Box<FullyDefinedLargeError>`
|
||||||
|
|
||||||
error: the `Err`-variant returned from this function is very large
|
error: the `Err`-variant returned from this function is very large
|
||||||
--> $DIR/result_large_err.rs:36:34
|
--> $DIR/result_large_err.rs:37:34
|
||||||
|
|
|
|
||||||
LL | pub fn param_large_error<R>() -> Result<(), (u128, R, FullyDefinedLargeError)> {
|
LL | pub fn param_large_error<R>() -> Result<(), (u128, R, FullyDefinedLargeError)> {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 256 bytes
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 256 bytes
|
||||||
|
@ -40,7 +40,7 @@ LL | pub fn param_large_error<R>() -> Result<(), (u128, R, FullyDefinedLargeErro
|
||||||
= help: try reducing the size of `(u128, R, FullyDefinedLargeError)`, for example by boxing large elements or replacing it with `Box<(u128, R, FullyDefinedLargeError)>`
|
= help: try reducing the size of `(u128, R, FullyDefinedLargeError)`, for example by boxing large elements or replacing it with `Box<(u128, R, FullyDefinedLargeError)>`
|
||||||
|
|
||||||
error: the `Err`-variant returned from this function is very large
|
error: the `Err`-variant returned from this function is very large
|
||||||
--> $DIR/result_large_err.rs:47:34
|
--> $DIR/result_large_err.rs:48:34
|
||||||
|
|
|
|
||||||
LL | pub fn large_enum_error() -> Result<(), Self> {
|
LL | pub fn large_enum_error() -> Result<(), Self> {
|
||||||
| ^^^^^^^^^^^^^^^^ the `Err`-variant is at least 513 bytes
|
| ^^^^^^^^^^^^^^^^ the `Err`-variant is at least 513 bytes
|
||||||
|
@ -48,7 +48,7 @@ LL | pub fn large_enum_error() -> Result<(), Self> {
|
||||||
= help: try reducing the size of `LargeErrorVariants<()>`, for example by boxing large elements or replacing it with `Box<LargeErrorVariants<()>>`
|
= help: try reducing the size of `LargeErrorVariants<()>`, for example by boxing large elements or replacing it with `Box<LargeErrorVariants<()>>`
|
||||||
|
|
||||||
error: the `Err`-variant returned from this function is very large
|
error: the `Err`-variant returned from this function is very large
|
||||||
--> $DIR/result_large_err.rs:53:25
|
--> $DIR/result_large_err.rs:54:25
|
||||||
|
|
|
|
||||||
LL | fn large_error() -> Result<(), [u8; 512]> {
|
LL | fn large_error() -> Result<(), [u8; 512]> {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes
|
| ^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes
|
||||||
|
@ -56,7 +56,7 @@ LL | fn large_error() -> Result<(), [u8; 512]> {
|
||||||
= help: try reducing the size of `[u8; 512]`, for example by boxing large elements or replacing it with `Box<[u8; 512]>`
|
= help: try reducing the size of `[u8; 512]`, for example by boxing large elements or replacing it with `Box<[u8; 512]>`
|
||||||
|
|
||||||
error: the `Err`-variant returned from this function is very large
|
error: the `Err`-variant returned from this function is very large
|
||||||
--> $DIR/result_large_err.rs:72:29
|
--> $DIR/result_large_err.rs:73:29
|
||||||
|
|
|
|
||||||
LL | pub fn large_union_err() -> Result<(), FullyDefinedUnionError> {
|
LL | pub fn large_union_err() -> Result<(), FullyDefinedUnionError> {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes
|
||||||
|
@ -64,7 +64,7 @@ LL | pub fn large_union_err() -> Result<(), FullyDefinedUnionError> {
|
||||||
= help: try reducing the size of `FullyDefinedUnionError`, for example by boxing large elements or replacing it with `Box<FullyDefinedUnionError>`
|
= help: try reducing the size of `FullyDefinedUnionError`, for example by boxing large elements or replacing it with `Box<FullyDefinedUnionError>`
|
||||||
|
|
||||||
error: the `Err`-variant returned from this function is very large
|
error: the `Err`-variant returned from this function is very large
|
||||||
--> $DIR/result_large_err.rs:81:40
|
--> $DIR/result_large_err.rs:82:40
|
||||||
|
|
|
|
||||||
LL | pub fn param_large_union<T: Copy>() -> Result<(), UnionError<T>> {
|
LL | pub fn param_large_union<T: Copy>() -> Result<(), UnionError<T>> {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes
|
||||||
|
@ -72,7 +72,7 @@ LL | pub fn param_large_union<T: Copy>() -> Result<(), UnionError<T>> {
|
||||||
= help: try reducing the size of `UnionError<T>`, for example by boxing large elements or replacing it with `Box<UnionError<T>>`
|
= help: try reducing the size of `UnionError<T>`, for example by boxing large elements or replacing it with `Box<UnionError<T>>`
|
||||||
|
|
||||||
error: the `Err`-variant returned from this function is very large
|
error: the `Err`-variant returned from this function is very large
|
||||||
--> $DIR/result_large_err.rs:90:34
|
--> $DIR/result_large_err.rs:91:34
|
||||||
|
|
|
|
||||||
LL | pub fn array_error_subst<U>() -> Result<(), ArrayError<i32, U>> {
|
LL | pub fn array_error_subst<U>() -> Result<(), ArrayError<i32, U>> {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 128 bytes
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 128 bytes
|
||||||
|
@ -80,7 +80,7 @@ LL | pub fn array_error_subst<U>() -> Result<(), ArrayError<i32, U>> {
|
||||||
= help: try reducing the size of `ArrayError<i32, U>`, for example by boxing large elements or replacing it with `Box<ArrayError<i32, U>>`
|
= help: try reducing the size of `ArrayError<i32, U>`, for example by boxing large elements or replacing it with `Box<ArrayError<i32, U>>`
|
||||||
|
|
||||||
error: the `Err`-variant returned from this function is very large
|
error: the `Err`-variant returned from this function is very large
|
||||||
--> $DIR/result_large_err.rs:94:31
|
--> $DIR/result_large_err.rs:95:31
|
||||||
|
|
|
|
||||||
LL | pub fn array_error<T, U>() -> Result<(), ArrayError<(i32, T), U>> {
|
LL | pub fn array_error<T, U>() -> Result<(), ArrayError<(i32, T), U>> {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 128 bytes
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 128 bytes
|
||||||
|
|
Loading…
Reference in a new issue