Skip to content

Commit 19f94d5

Browse files
committed
remove large_enum_variant suggestion for Copy types
1 parent 1dd5547 commit 19f94d5

File tree

3 files changed

+99
-31
lines changed

3 files changed

+99
-31
lines changed

clippy_lints/src/large_enum_variant.rs

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! lint when there is a large size difference between variants on an enum
22
3-
use clippy_utils::diagnostics::span_lint_and_then;
43
use clippy_utils::source::snippet_with_applicability;
4+
use clippy_utils::{diagnostics::span_lint_and_then, ty::is_copy};
55
use rustc_errors::Applicability;
66
use rustc_hir::{Item, ItemKind};
77
use rustc_lint::{LateContext, LateLintPass};
@@ -132,37 +132,43 @@ impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant {
132132
let fields = def.variants[variants_size[0].ind].data.fields();
133133
variants_size[0].fields_size.sort_by(|a, b| (a.size.cmp(&b.size)));
134134
let mut applicability = Applicability::MaybeIncorrect;
135-
let sugg: Vec<(Span, String)> = variants_size[0]
136-
.fields_size
137-
.iter()
138-
.rev()
139-
.map_while(|val| {
140-
if difference > self.maximum_size_difference_allowed {
141-
difference = difference.saturating_sub(val.size);
142-
Some((
143-
fields[val.ind].ty.span,
144-
format!(
145-
"Box<{}>",
146-
snippet_with_applicability(
147-
cx,
148-
fields[val.ind].ty.span,
149-
"..",
150-
&mut applicability
151-
)
152-
.into_owned()
153-
),
154-
))
155-
} else {
156-
None
157-
}
158-
})
159-
.collect();
135+
if is_copy(cx, ty) {
136+
diag.span_note(
137+
item.ident.span,
138+
"boxing a variant would require the type no longer be `Copy`",
139+
);
140+
} else {
141+
let sugg: Vec<(Span, String)> = variants_size[0]
142+
.fields_size
143+
.iter()
144+
.rev()
145+
.map_while(|val| {
146+
if difference > self.maximum_size_difference_allowed {
147+
difference = difference.saturating_sub(val.size);
148+
Some((
149+
fields[val.ind].ty.span,
150+
format!(
151+
"Box<{}>",
152+
snippet_with_applicability(
153+
cx,
154+
fields[val.ind].ty.span,
155+
"..",
156+
&mut applicability
157+
)
158+
.into_owned()
159+
),
160+
))
161+
} else {
162+
None
163+
}
164+
})
165+
.collect();
160166

161-
if !sugg.is_empty() {
162-
diag.multipart_suggestion(help_text, sugg, Applicability::MaybeIncorrect);
163-
return;
167+
if !sugg.is_empty() {
168+
diag.multipart_suggestion(help_text, sugg, Applicability::MaybeIncorrect);
169+
return;
170+
}
164171
}
165-
166172
diag.span_help(def.variants[variants_size[0].ind].span, help_text);
167173
},
168174
);

tests/ui/large_enum_variant.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,24 @@ struct Struct2 {
9898
a: [i32; 8000],
9999
}
100100

101+
#[derive(Copy, Clone)]
102+
enum CopyableLargeEnum {
103+
A(bool),
104+
B([u128; 4000]),
105+
}
106+
107+
enum ManuallyCopyLargeEnum {
108+
A(bool),
109+
B([u128; 4000]),
110+
}
111+
112+
impl Clone for ManuallyCopyLargeEnum {
113+
fn clone(&self) -> Self {
114+
*self
115+
}
116+
}
117+
impl Copy for ManuallyCopyLargeEnum {}
118+
101119
fn main() {
102120
large_enum_variant!();
103121
}

tests/ui/large_enum_variant.stderr

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,5 +127,49 @@ help: consider boxing the large fields to reduce the total size of the enum
127127
LL | B(Box<Struct2>),
128128
| ~~~~~~~~~~~~
129129

130-
error: aborting due to 8 previous errors
130+
error: large size difference between variants
131+
--> $DIR/large_enum_variant.rs:104:5
132+
|
133+
LL | B([u128; 4000]),
134+
| ^^^^^^^^^^^^^^^ this variant is 64000 bytes
135+
|
136+
note: and the second-largest variant is 1 bytes:
137+
--> $DIR/large_enum_variant.rs:103:5
138+
|
139+
LL | A(bool),
140+
| ^^^^^^^
141+
note: boxing a variant would require the type no longer be `Copy`
142+
--> $DIR/large_enum_variant.rs:102:6
143+
|
144+
LL | enum CopyableLargeEnum {
145+
| ^^^^^^^^^^^^^^^^^
146+
help: consider boxing the large fields to reduce the total size of the enum
147+
--> $DIR/large_enum_variant.rs:104:5
148+
|
149+
LL | B([u128; 4000]),
150+
| ^^^^^^^^^^^^^^^
151+
152+
error: large size difference between variants
153+
--> $DIR/large_enum_variant.rs:109:5
154+
|
155+
LL | B([u128; 4000]),
156+
| ^^^^^^^^^^^^^^^ this variant is 64000 bytes
157+
|
158+
note: and the second-largest variant is 1 bytes:
159+
--> $DIR/large_enum_variant.rs:108:5
160+
|
161+
LL | A(bool),
162+
| ^^^^^^^
163+
note: boxing a variant would require the type no longer be `Copy`
164+
--> $DIR/large_enum_variant.rs:107:6
165+
|
166+
LL | enum ManuallyCopyLargeEnum {
167+
| ^^^^^^^^^^^^^^^^^^^^^
168+
help: consider boxing the large fields to reduce the total size of the enum
169+
--> $DIR/large_enum_variant.rs:109:5
170+
|
171+
LL | B([u128; 4000]),
172+
| ^^^^^^^^^^^^^^^
173+
174+
error: aborting due to 10 previous errors
131175

0 commit comments

Comments
 (0)