`empty_enums` doesn't account for how the type is used
Author: JarchoCreated Jun 23, 2026Updated Sep 18, 2026
LabelsC-bugI-false-positiveL-nursery
Description
Empty enums are used as an existential type and in the typestate pattern. These uses need the nominal type and cannot simply be aliases of !.
Typestate example:
enum State1 {}
enum State2 {}
struct Machine<S>(PhantomData<S>);
impl Machine<State1> {
fn do1(self) -> Machine<State2> {}
}
impl Machine<State2> {
fn do2(self) {}
}Existential example:
enum Foo {}
unsafe extern "C" {
fn create_foo() -> *mut Foo;
fn read_foo(x: *const Foo) -> u32;
fn write_foo(x: *mut Foo, y: u32);
}In both cases the enum is not ever used as a generic argument in an enum like Option<!> or Result<u32, Infallible>. A good way to filter this out would be to check if the type is ever returned from a function as a generic parameter to a type which holds that type by-value only on some, potentially nested, variants.
Version
Additional Labels
No response
Source: rust-lang/rust-clippy