From ea5d7b68c0b89313aaea1843e4b4d7327af11aa0 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 28 Jul 2026 14:40:19 +0000 Subject: [PATCH] Warn on exhaustive exported enums Enable clippy::exhaustive_enums in every crate so new exported enums are either #[non_exhaustive] or explicitly allowed as a closed set. --- winit-android/src/lib.rs | 2 ++ winit-appkit/src/lib.rs | 3 +++ winit-common/src/lib.rs | 2 ++ winit-core/src/cursor.rs | 1 + winit-core/src/event.rs | 5 +++++ winit-core/src/event_loop/mod.rs | 2 ++ winit-core/src/event_loop/pump_events.rs | 1 + winit-core/src/keyboard.rs | 3 +++ winit-core/src/lib.rs | 6 ++++++ winit-core/src/window.rs | 5 +++++ winit-orbital/src/event_loop.rs | 2 ++ winit-orbital/src/lib.rs | 2 ++ winit-uikit/src/lib.rs | 2 ++ winit-wayland/src/lib.rs | 2 ++ winit-web/src/lib.rs | 4 ++++ winit-win32/src/lib.rs | 2 ++ winit-x11/src/lib.rs | 2 ++ 17 files changed, 46 insertions(+) diff --git a/winit-android/src/lib.rs b/winit-android/src/lib.rs index 989c9716d..049fd9f22 100644 --- a/winit-android/src/lib.rs +++ b/winit-android/src/lib.rs @@ -71,6 +71,8 @@ //! event loop (as shown above). #![cfg(target_os = "android")] +#![warn(clippy::exhaustive_enums)] + mod event_loop; mod keycodes; diff --git a/winit-appkit/src/lib.rs b/winit-appkit/src/lib.rs index e08026995..b58f03586 100644 --- a/winit-appkit/src/lib.rs +++ b/winit-appkit/src/lib.rs @@ -65,6 +65,8 @@ //! ``` #![cfg(target_vendor = "apple")] // TODO: Remove once `objc2` allows compiling on all platforms +#![warn(clippy::exhaustive_enums)] + #[macro_use] mod util; @@ -632,6 +634,7 @@ impl ActiveEventLoopExtMacOS for dyn ActiveEventLoop + '_ { /// The default is `None`. #[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[allow(clippy::exhaustive_enums)] pub enum OptionAsAlt { /// The left `Option` key is treated as `Alt`. OnlyLeft, diff --git a/winit-common/src/lib.rs b/winit-common/src/lib.rs index f1997da16..33db2d67c 100644 --- a/winit-common/src/lib.rs +++ b/winit-common/src/lib.rs @@ -1,5 +1,7 @@ //! Winit implementation helpers. +#![warn(clippy::exhaustive_enums)] + #[cfg(feature = "core-foundation")] pub mod core_foundation; #[cfg(feature = "event-handler")] diff --git a/winit-core/src/cursor.rs b/winit-core/src/cursor.rs index 94de602d3..c411e0d3e 100644 --- a/winit-core/src/cursor.rs +++ b/winit-core/src/cursor.rs @@ -17,6 +17,7 @@ const PIXEL_SIZE: usize = 4; /// See [`Window::set_cursor()`][crate::window::Window::set_cursor] for more details. #[derive(Clone, Debug, Eq, Hash, PartialEq)] +#[allow(clippy::exhaustive_enums)] pub enum Cursor { Icon(CursorIcon), Custom(CustomCursor), diff --git a/winit-core/src/event.rs b/winit-core/src/event.rs index afc068719..ec459cafd 100644 --- a/winit-core/src/event.rs +++ b/winit-core/src/event.rs @@ -1107,6 +1107,7 @@ pub enum Ime { /// Describes touch-screen input state. #[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[allow(clippy::exhaustive_enums)] pub enum TouchPhase { /// Initial touch contact or gesture start, for example when one or more fingers touch the /// screen or touchpad. @@ -1126,6 +1127,7 @@ pub enum TouchPhase { #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[doc(alias = "Pressure")] +#[allow(clippy::exhaustive_enums)] pub enum Force { /// On iOS, the force is calibrated so that the same number corresponds to /// roughly the same amount of pressure on the screen regardless of the @@ -1436,6 +1438,7 @@ impl TabletToolAngle { /// Describes the input state of a key. #[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[allow(clippy::exhaustive_enums)] pub enum ElementState { Pressed, Released, @@ -1466,6 +1469,7 @@ impl ElementState { #[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[repr(u8)] +#[allow(clippy::exhaustive_enums)] pub enum MouseButton { /// The primary (usually left) button Left = 0, @@ -1561,6 +1565,7 @@ impl MouseButton { /// Describes a button of a tool, e.g. a pen. #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] +#[allow(clippy::exhaustive_enums)] pub enum TabletToolButton { Contact, Barrel, diff --git a/winit-core/src/event_loop/mod.rs b/winit-core/src/event_loop/mod.rs index 32988b558..f0b62aeed 100644 --- a/winit-core/src/event_loop/mod.rs +++ b/winit-core/src/event_loop/mod.rs @@ -415,6 +415,7 @@ impl Eq for OwnedDisplayHandle {} /// [`Wait`]: Self::Wait /// [`about_to_wait`]: crate::application::ApplicationHandler::about_to_wait #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)] +#[allow(clippy::exhaustive_enums)] pub enum ControlFlow { /// When the current loop iteration finishes, immediately begin a new iteration regardless of /// whether or not new events are available to process. @@ -454,6 +455,7 @@ impl ControlFlow { /// Control when device events are captured. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[allow(clippy::exhaustive_enums)] pub enum DeviceEvents { /// Report device events regardless of window focus. Always, diff --git a/winit-core/src/event_loop/pump_events.rs b/winit-core/src/event_loop/pump_events.rs index e817d0bc4..26d14c66b 100644 --- a/winit-core/src/event_loop/pump_events.rs +++ b/winit-core/src/event_loop/pump_events.rs @@ -108,6 +108,7 @@ pub trait EventLoopExtPumpEvents { /// The return status for `pump_events` #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +#[allow(clippy::exhaustive_enums)] pub enum PumpStatus { /// Continue running external loop. Continue, diff --git a/winit-core/src/keyboard.rs b/winit-core/src/keyboard.rs index 652165686..110c5255e 100644 --- a/winit-core/src/keyboard.rs +++ b/winit-core/src/keyboard.rs @@ -169,6 +169,7 @@ impl PartialEq for NativeKey { /// emit [`PhysicalKey::Unidentified`] with additional data about the key. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[allow(clippy::exhaustive_enums)] pub enum PhysicalKey { /// A known key code Code(KeyCode), @@ -250,6 +251,7 @@ impl PartialEq for NativeKeyCode { /// [`KeyboardEvent.key`]: https://w3c.github.io/uievents-key/ #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[allow(clippy::exhaustive_enums)] pub enum Key { /// A simple (unparameterised) action Named(NamedKey), @@ -447,6 +449,7 @@ impl ModifiersState { /// [^2]: platform-dependent #[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[allow(clippy::exhaustive_enums)] pub enum ModifiersKeyState { /// The particular modifier is active or logically, but not necessarily physically, pressed. Pressed, diff --git a/winit-core/src/lib.rs b/winit-core/src/lib.rs index 2fe5fc82e..6ea1e2535 100644 --- a/winit-core/src/lib.rs +++ b/winit-core/src/lib.rs @@ -7,6 +7,12 @@ //! //! [`winit`]: https://docs.rs/winit +// Every newly exported enum should either be `#[non_exhaustive]`, or carry an `#[allow]` of +// this lint when the set of variants can never grow. +// `clippy::exhaustive_structs` is deliberately not enabled: event structs must stay +// constructible by the backend crates, which `#[non_exhaustive]` would forbid. +#![warn(clippy::exhaustive_enums)] + #[macro_use] pub mod as_any; pub mod cursor; diff --git a/winit-core/src/window.rs b/winit-core/src/window.rs index 70992abc0..0bda71233 100644 --- a/winit-core/src/window.rs +++ b/winit-core/src/window.rs @@ -1544,6 +1544,7 @@ impl rwh_06::HasWindowHandle for dyn Window + '_ { /// Use this enum with [`Window::set_cursor_grab`] to grab the cursor. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[allow(clippy::exhaustive_enums)] pub enum CursorGrabMode { /// No grabbing of the cursor is performed. None, @@ -1574,6 +1575,7 @@ pub enum CursorGrabMode { /// Defines the orientation that a window resize will be performed. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[allow(clippy::exhaustive_enums)] pub enum ResizeDirection { East, North, @@ -1604,6 +1606,7 @@ impl From for CursorIcon { /// The theme variant to use. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[allow(clippy::exhaustive_enums)] pub enum Theme { /// Use the light variant. Light, @@ -1621,6 +1624,7 @@ pub enum Theme { /// [`Informational`]: Self::Informational #[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[allow(clippy::exhaustive_enums)] pub enum UserAttentionType { /// ## Platform-specific /// @@ -1656,6 +1660,7 @@ bitflags::bitflags! { /// - **iOS / Android / Web / Wayland:** Unsupported. #[derive(Debug, Default, PartialEq, Eq, Clone, Copy, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[allow(clippy::exhaustive_enums)] pub enum WindowLevel { /// The window will always be below normal windows. /// diff --git a/winit-orbital/src/event_loop.rs b/winit-orbital/src/event_loop.rs index 2c1aa43c1..f94ad1d16 100644 --- a/winit-orbital/src/event_loop.rs +++ b/winit-orbital/src/event_loop.rs @@ -1,3 +1,5 @@ +// `EventSource` is macro-generated; the lint can't be allowed on the enum itself. +#![allow(clippy::exhaustive_enums)] use std::cell::Cell; use std::collections::VecDeque; use std::sync::atomic::{AtomicBool, Ordering}; diff --git a/winit-orbital/src/lib.rs b/winit-orbital/src/lib.rs index 23fd58e29..8b65678bf 100644 --- a/winit-orbital/src/lib.rs +++ b/winit-orbital/src/lib.rs @@ -3,6 +3,8 @@ //! Redox OS has some functionality not yet present that will be implemented //! when its orbital display server provides it. +#![warn(clippy::exhaustive_enums)] + use std::fs::{File, OpenOptions}; use std::io::{Read, Result, Write}; use std::os::fd::AsRawFd; diff --git a/winit-uikit/src/lib.rs b/winit-uikit/src/lib.rs index 919dbc822..4ea6b9f5b 100644 --- a/winit-uikit/src/lib.rs +++ b/winit-uikit/src/lib.rs @@ -100,6 +100,8 @@ //! [app-delegate]: https://developer.apple.com/documentation/uikit/uiapplicationdelegate?language=objc #![cfg(target_vendor = "apple")] // TODO: Remove once `objc2` allows compiling on all platforms +#![warn(clippy::exhaustive_enums)] + mod app_state; mod event_loop; mod monitor; diff --git a/winit-wayland/src/lib.rs b/winit-wayland/src/lib.rs index de640aed9..8ec52cbc3 100644 --- a/winit-wayland/src/lib.rs +++ b/winit-wayland/src/lib.rs @@ -17,6 +17,8 @@ #![allow(clippy::mutable_key_type)] +#![warn(clippy::exhaustive_enums)] + use std::ffi::c_void; use std::hash::BuildHasher; use std::ptr::NonNull; diff --git a/winit-web/src/lib.rs b/winit-web/src/lib.rs index b34d16875..0b4d40643 100644 --- a/winit-web/src/lib.rs +++ b/winit-web/src/lib.rs @@ -41,6 +41,8 @@ //! [`WindowEvent::PointerLeft`]: crate::event::WindowEvent::PointerLeft //! [`Window::set_outer_position()`]: crate::window::Window::set_outer_position +#![warn(clippy::exhaustive_enums)] + // Brief introduction to the internals of the Web backend: // The Web backend used to support both wasm-bindgen and stdweb as methods of binding to the // environment. Because they are both supporting the same underlying APIs, the actual Web bindings @@ -623,6 +625,7 @@ pub struct OrientationData { /// Screen orientation. #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +#[allow(clippy::exhaustive_enums)] pub enum Orientation { /// The screen's aspect ratio has a width greater than the height. Landscape, @@ -632,6 +635,7 @@ pub enum Orientation { /// Screen orientation lock options. Represents which orientations a user can use. #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +#[allow(clippy::exhaustive_enums)] pub enum OrientationLock { /// User is free to use any orientation. Any, diff --git a/winit-win32/src/lib.rs b/winit-win32/src/lib.rs index c5a4cd41d..78053202b 100644 --- a/winit-win32/src/lib.rs +++ b/winit-win32/src/lib.rs @@ -4,6 +4,8 @@ //! tested regularly. #![cfg(target_os = "windows")] // FIXME(madsmtm): Allow compiling on all platforms. +#![warn(clippy::exhaustive_enums)] + #[macro_use] mod util; mod dark_mode; diff --git a/winit-x11/src/lib.rs b/winit-x11/src/lib.rs index 1551ed1a6..638101541 100644 --- a/winit-x11/src/lib.rs +++ b/winit-x11/src/lib.rs @@ -1,5 +1,7 @@ //! # X11 +#![warn(clippy::exhaustive_enums)] + use dpi::Size; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize};