-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
large_enum_variant false positive (incorrect size calculation?) #9798
Comments
Before 1.65 |
Why do you think pub struct TlsStream<IO> {
pub(crate) io: IO,
pub(crate) session: ClientConnection,
pub(crate) state: TlsState,
#[cfg(feature = "early-data")]
pub(crate) early_waker: Option<std::task::Waker>,
} While this is pub struct TlsStream<IO> {
pub(crate) io: IO,
pub(crate) session: ServerConnection,
pub(crate) state: TlsState,
} If it is able to deduce that |
In serenity, this bug is happening even without any generics. /// A container for any channel.
#[derive(Clone, Debug, Serialize)]
#[serde(untagged)]
#[non_exhaustive]
pub enum Channel {
/// A channel within a [`Guild`].
Guild(GuildChannel),
/// A private channel to another [`User`] (Direct Message). No other users may access the
/// channel. For multi-user "private channels", use a group.
Private(PrivateChannel),
} warning: large size difference between variants
--> src/model/channel/mod.rs:47:1
|
47 | / pub enum Channel {
48 | | /// A channel within a [`Guild`].
49 | | Guild(GuildChannel),
| | ------------------- the largest variant contains at least 312 bytes
50 | | /// A private channel to another [`User`] (Direct Message). No other users may access the
51 | | /// channel. For multi-user "private channels", use a group.
52 | | Private(PrivateChannel),
| | ----------------------- the second-largest variant contains at least 0 bytes
53 | | }
| |_^ the entire enum is at least 0 bytes
|
= note: `#[warn(clippy::large_enum_variant)]` on by default
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#large_enum_variant
help: consider boxing the large fields to reduce the total size of the enum
|
49 | Guild(Box<GuildChannel>), |
Apparently, clippy's size calculation chokes on recursive types: pub struct Recursive(Box<Recursive>);
pub enum Foo {
A([u8; 201]),
B(Recursive),
}
// 5 | | B(Recursive),
// | | ------------ the second-largest variant contains at least 0 bytes (In serenity's case, |
Remove `is_normalizable` fixes #11915 fixes #9798 Fixes only the first ICE in #10508 `is_normalizable` is used in a few places to avoid an ICE due to a delayed bug in normalization which occurs when a projection type is used on a type which doesn't implement the correct trait. The only part of clippy that actually needed this check is `zero_sized_map_values` due to a quirk of how type aliases work (they don't a real `ParamEnv`). This fixes the need for the check there by manually walking the type to determine if it's zero sized, rather than attempting to compute the type's layout thereby avoid the normalization that triggers the delayed bug. For an example of the issue with type aliases: ```rust trait Foo { type Foo; } struct Bar<T: Foo>(T::Foo); // The `ParamEnv` here just has `T: Sized`, not `T: Sized + Foo`. type Baz<T> = &'static Bar<T>; ``` When trying to compute the layout of `&'static Bar<T>` we need to determine if what type `<Bar<T> as Pointee>::Metadata` is. Doing this requires knowing if `T::Foo: Sized`, but since `T` doesn't have an associated type `Foo` in the context of the type alias a delayed bug is issued. changelog: [`large_enum_variant`]: correctly get the size of `bytes::Bytes`.
I hit this today, and the text "the second-largest variant contains at least 0 bytes" makes it hard to trust this specific lint. I believe this is indicative of a genuine issue with my code, but just that the reporting is confused by a recursive type. |
Summary
There seems to be a regression in calculating the size for the type contained in a variant here.
https://github.com/tokio-rs/tls/actions/runs/3391306304/jobs/5636351880
Lint Name
large_enum_variant
Reproducer
I tried this code:
I saw this happen:
I expected to see this happen:
Smaller size difference, or maybe no lint at all.
Version
Additional Labels
Seems to be a regression in 1.65.
The text was updated successfully, but these errors were encountered: