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.
This commit is contained in:
Olivier Goffart
2026-07-28 14:40:19 +00:00
parent 9c7e191407
commit ea5d7b68c0
17 changed files with 46 additions and 0 deletions

View File

@@ -71,6 +71,8 @@
//! event loop (as shown above). //! event loop (as shown above).
#![cfg(target_os = "android")] #![cfg(target_os = "android")]
#![warn(clippy::exhaustive_enums)]
mod event_loop; mod event_loop;
mod keycodes; mod keycodes;

View File

@@ -65,6 +65,8 @@
//! ``` //! ```
#![cfg(target_vendor = "apple")] // TODO: Remove once `objc2` allows compiling on all platforms #![cfg(target_vendor = "apple")] // TODO: Remove once `objc2` allows compiling on all platforms
#![warn(clippy::exhaustive_enums)]
#[macro_use] #[macro_use]
mod util; mod util;
@@ -632,6 +634,7 @@ impl ActiveEventLoopExtMacOS for dyn ActiveEventLoop + '_ {
/// The default is `None`. /// The default is `None`.
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[allow(clippy::exhaustive_enums)]
pub enum OptionAsAlt { pub enum OptionAsAlt {
/// The left `Option` key is treated as `Alt`. /// The left `Option` key is treated as `Alt`.
OnlyLeft, OnlyLeft,

View File

@@ -1,5 +1,7 @@
//! Winit implementation helpers. //! Winit implementation helpers.
#![warn(clippy::exhaustive_enums)]
#[cfg(feature = "core-foundation")] #[cfg(feature = "core-foundation")]
pub mod core_foundation; pub mod core_foundation;
#[cfg(feature = "event-handler")] #[cfg(feature = "event-handler")]

View File

@@ -17,6 +17,7 @@ const PIXEL_SIZE: usize = 4;
/// See [`Window::set_cursor()`][crate::window::Window::set_cursor] for more details. /// See [`Window::set_cursor()`][crate::window::Window::set_cursor] for more details.
#[derive(Clone, Debug, Eq, Hash, PartialEq)] #[derive(Clone, Debug, Eq, Hash, PartialEq)]
#[allow(clippy::exhaustive_enums)]
pub enum Cursor { pub enum Cursor {
Icon(CursorIcon), Icon(CursorIcon),
Custom(CustomCursor), Custom(CustomCursor),

View File

@@ -1107,6 +1107,7 @@ pub enum Ime {
/// Describes touch-screen input state. /// Describes touch-screen input state.
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)] #[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[allow(clippy::exhaustive_enums)]
pub enum TouchPhase { pub enum TouchPhase {
/// Initial touch contact or gesture start, for example when one or more fingers touch the /// Initial touch contact or gesture start, for example when one or more fingers touch the
/// screen or touchpad. /// screen or touchpad.
@@ -1126,6 +1127,7 @@ pub enum TouchPhase {
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[doc(alias = "Pressure")] #[doc(alias = "Pressure")]
#[allow(clippy::exhaustive_enums)]
pub enum Force { pub enum Force {
/// On iOS, the force is calibrated so that the same number corresponds to /// 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 /// 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. /// Describes the input state of a key.
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)] #[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[allow(clippy::exhaustive_enums)]
pub enum ElementState { pub enum ElementState {
Pressed, Pressed,
Released, Released,
@@ -1466,6 +1469,7 @@ impl ElementState {
#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] #[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[repr(u8)] #[repr(u8)]
#[allow(clippy::exhaustive_enums)]
pub enum MouseButton { pub enum MouseButton {
/// The primary (usually left) button /// The primary (usually left) button
Left = 0, Left = 0,
@@ -1561,6 +1565,7 @@ impl MouseButton {
/// Describes a button of a tool, e.g. a pen. /// Describes a button of a tool, e.g. a pen.
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[allow(clippy::exhaustive_enums)]
pub enum TabletToolButton { pub enum TabletToolButton {
Contact, Contact,
Barrel, Barrel,

View File

@@ -415,6 +415,7 @@ impl Eq for OwnedDisplayHandle {}
/// [`Wait`]: Self::Wait /// [`Wait`]: Self::Wait
/// [`about_to_wait`]: crate::application::ApplicationHandler::about_to_wait /// [`about_to_wait`]: crate::application::ApplicationHandler::about_to_wait
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)] #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
#[allow(clippy::exhaustive_enums)]
pub enum ControlFlow { pub enum ControlFlow {
/// When the current loop iteration finishes, immediately begin a new iteration regardless of /// When the current loop iteration finishes, immediately begin a new iteration regardless of
/// whether or not new events are available to process. /// whether or not new events are available to process.
@@ -454,6 +455,7 @@ impl ControlFlow {
/// Control when device events are captured. /// Control when device events are captured.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)] #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[allow(clippy::exhaustive_enums)]
pub enum DeviceEvents { pub enum DeviceEvents {
/// Report device events regardless of window focus. /// Report device events regardless of window focus.
Always, Always,

View File

@@ -108,6 +108,7 @@ pub trait EventLoopExtPumpEvents {
/// The return status for `pump_events` /// The return status for `pump_events`
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[allow(clippy::exhaustive_enums)]
pub enum PumpStatus { pub enum PumpStatus {
/// Continue running external loop. /// Continue running external loop.
Continue, Continue,

View File

@@ -169,6 +169,7 @@ impl PartialEq<NativeKeyCode> for NativeKey {
/// emit [`PhysicalKey::Unidentified`] with additional data about the key. /// emit [`PhysicalKey::Unidentified`] with additional data about the key.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[allow(clippy::exhaustive_enums)]
pub enum PhysicalKey { pub enum PhysicalKey {
/// A known key code /// A known key code
Code(KeyCode), Code(KeyCode),
@@ -250,6 +251,7 @@ impl PartialEq<PhysicalKey> for NativeKeyCode {
/// [`KeyboardEvent.key`]: https://w3c.github.io/uievents-key/ /// [`KeyboardEvent.key`]: https://w3c.github.io/uievents-key/
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[allow(clippy::exhaustive_enums)]
pub enum Key<Str = SmolStr> { pub enum Key<Str = SmolStr> {
/// A simple (unparameterised) action /// A simple (unparameterised) action
Named(NamedKey), Named(NamedKey),
@@ -447,6 +449,7 @@ impl ModifiersState {
/// [^2]: platform-dependent /// [^2]: platform-dependent
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] #[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[allow(clippy::exhaustive_enums)]
pub enum ModifiersKeyState { pub enum ModifiersKeyState {
/// The particular modifier is active or logically, but not necessarily physically, pressed. /// The particular modifier is active or logically, but not necessarily physically, pressed.
Pressed, Pressed,

View File

@@ -7,6 +7,12 @@
//! //!
//! [`winit`]: https://docs.rs/winit //! [`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] #[macro_use]
pub mod as_any; pub mod as_any;
pub mod cursor; pub mod cursor;

View File

@@ -1544,6 +1544,7 @@ impl rwh_06::HasWindowHandle for dyn Window + '_ {
/// Use this enum with [`Window::set_cursor_grab`] to grab the cursor. /// Use this enum with [`Window::set_cursor_grab`] to grab the cursor.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[allow(clippy::exhaustive_enums)]
pub enum CursorGrabMode { pub enum CursorGrabMode {
/// No grabbing of the cursor is performed. /// No grabbing of the cursor is performed.
None, None,
@@ -1574,6 +1575,7 @@ pub enum CursorGrabMode {
/// Defines the orientation that a window resize will be performed. /// Defines the orientation that a window resize will be performed.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[allow(clippy::exhaustive_enums)]
pub enum ResizeDirection { pub enum ResizeDirection {
East, East,
North, North,
@@ -1604,6 +1606,7 @@ impl From<ResizeDirection> for CursorIcon {
/// The theme variant to use. /// The theme variant to use.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[allow(clippy::exhaustive_enums)]
pub enum Theme { pub enum Theme {
/// Use the light variant. /// Use the light variant.
Light, Light,
@@ -1621,6 +1624,7 @@ pub enum Theme {
/// [`Informational`]: Self::Informational /// [`Informational`]: Self::Informational
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[allow(clippy::exhaustive_enums)]
pub enum UserAttentionType { pub enum UserAttentionType {
/// ## Platform-specific /// ## Platform-specific
/// ///
@@ -1656,6 +1660,7 @@ bitflags::bitflags! {
/// - **iOS / Android / Web / Wayland:** Unsupported. /// - **iOS / Android / Web / Wayland:** Unsupported.
#[derive(Debug, Default, PartialEq, Eq, Clone, Copy, Hash)] #[derive(Debug, Default, PartialEq, Eq, Clone, Copy, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[allow(clippy::exhaustive_enums)]
pub enum WindowLevel { pub enum WindowLevel {
/// The window will always be below normal windows. /// The window will always be below normal windows.
/// ///

View File

@@ -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::cell::Cell;
use std::collections::VecDeque; use std::collections::VecDeque;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};

View File

@@ -3,6 +3,8 @@
//! Redox OS has some functionality not yet present that will be implemented //! Redox OS has some functionality not yet present that will be implemented
//! when its orbital display server provides it. //! when its orbital display server provides it.
#![warn(clippy::exhaustive_enums)]
use std::fs::{File, OpenOptions}; use std::fs::{File, OpenOptions};
use std::io::{Read, Result, Write}; use std::io::{Read, Result, Write};
use std::os::fd::AsRawFd; use std::os::fd::AsRawFd;

View File

@@ -100,6 +100,8 @@
//! [app-delegate]: https://developer.apple.com/documentation/uikit/uiapplicationdelegate?language=objc //! [app-delegate]: https://developer.apple.com/documentation/uikit/uiapplicationdelegate?language=objc
#![cfg(target_vendor = "apple")] // TODO: Remove once `objc2` allows compiling on all platforms #![cfg(target_vendor = "apple")] // TODO: Remove once `objc2` allows compiling on all platforms
#![warn(clippy::exhaustive_enums)]
mod app_state; mod app_state;
mod event_loop; mod event_loop;
mod monitor; mod monitor;

View File

@@ -17,6 +17,8 @@
#![allow(clippy::mutable_key_type)] #![allow(clippy::mutable_key_type)]
#![warn(clippy::exhaustive_enums)]
use std::ffi::c_void; use std::ffi::c_void;
use std::hash::BuildHasher; use std::hash::BuildHasher;
use std::ptr::NonNull; use std::ptr::NonNull;

View File

@@ -41,6 +41,8 @@
//! [`WindowEvent::PointerLeft`]: crate::event::WindowEvent::PointerLeft //! [`WindowEvent::PointerLeft`]: crate::event::WindowEvent::PointerLeft
//! [`Window::set_outer_position()`]: crate::window::Window::set_outer_position //! [`Window::set_outer_position()`]: crate::window::Window::set_outer_position
#![warn(clippy::exhaustive_enums)]
// Brief introduction to the internals of the Web backend: // 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 // 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 // environment. Because they are both supporting the same underlying APIs, the actual Web bindings
@@ -623,6 +625,7 @@ pub struct OrientationData {
/// Screen orientation. /// Screen orientation.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[allow(clippy::exhaustive_enums)]
pub enum Orientation { pub enum Orientation {
/// The screen's aspect ratio has a width greater than the height. /// The screen's aspect ratio has a width greater than the height.
Landscape, Landscape,
@@ -632,6 +635,7 @@ pub enum Orientation {
/// Screen orientation lock options. Represents which orientations a user can use. /// Screen orientation lock options. Represents which orientations a user can use.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[allow(clippy::exhaustive_enums)]
pub enum OrientationLock { pub enum OrientationLock {
/// User is free to use any orientation. /// User is free to use any orientation.
Any, Any,

View File

@@ -4,6 +4,8 @@
//! tested regularly. //! tested regularly.
#![cfg(target_os = "windows")] // FIXME(madsmtm): Allow compiling on all platforms. #![cfg(target_os = "windows")] // FIXME(madsmtm): Allow compiling on all platforms.
#![warn(clippy::exhaustive_enums)]
#[macro_use] #[macro_use]
mod util; mod util;
mod dark_mode; mod dark_mode;

View File

@@ -1,5 +1,7 @@
//! # X11 //! # X11
#![warn(clippy::exhaustive_enums)]
use dpi::Size; use dpi::Size;
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};