bevy_ecs/
never.rs

1//! A workaround for the `!` type in stable Rust.
2//!
3//! This approach is taken from the [`never_say_never`] crate,
4//! reimplemented here to avoid adding a new dependency.
5//!
6//! This module exists due to a change in [never type fallback inference] in the Rust 2024 edition.
7//! This caused failures in `bevy_ecs`'s traits which are implemented for functions
8//! (like [`System`](crate::system::System)) when working with panicking closures.
9//!
10//! Note that using this hack is not recommended in general;
11//! by doing so you are knowingly opting out of rustc's stability guarantees.
12//! Code that compiles due to this hack may break in future versions of Rust.
13//!
14//! Please read [issue #18778](https://github.com/bevyengine/bevy/issues/18778) for an explanation of why
15//! Bevy has chosen to use this workaround.
16//!
17//! [`never_say_never`]: https://crates.io/crates/never_say_never
18//! [never type fallback inference]: https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html
19
20mod fn_ret {
21    /// A helper trait for naming the ! type.
22    #[doc(hidden)]
23    pub trait FnRet {
24        /// The return type of the function.
25        type Output;
26    }
27
28    /// This blanket implementation allows us to name the never type,
29    /// by using the associated type of this trait for `fn() -> !`.
30    impl<R> FnRet for fn() -> R {
31        type Output = R;
32    }
33}
34
35/// A hacky type alias for the `!` (never) type.
36///
37/// This knowingly opts out of rustc's stability guarantees.
38/// Read the module documentation carefully before using this!
39pub type Never = <fn() -> ! as fn_ret::FnRet>::Output;