From 81307290e25edcb986bad7826ed6b832eb57bd8b Mon Sep 17 00:00:00 2001 From: JoJoJet <21144246+JoJoJet@users.noreply.github.com> Date: Thu, 16 Feb 2023 16:45:48 +0000 Subject: [PATCH] Fix trait bounds for run conditions (#7688) # Objective The trait `Condition<>` is implemented for any type that can be converted into a `ReadOnlySystem` which takes no inputs and returns a bool. However, due to the current implementation, consumers of the trait cannot rely on the fact that `::System` implements `ReadOnlySystem`. In cases such as the `not` combinator (added in #7559), we are required to add redundant `T::System: ReadOnlySystem` trait bounds, even though this should be implied by the `Condition<>` trait. ## Solution Add a hidden associated type which allows the compiler to figure out that the `System` associated type implements `ReadOnlySystem`. --- crates/bevy_ecs/src/schedule/condition.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/crates/bevy_ecs/src/schedule/condition.rs b/crates/bevy_ecs/src/schedule/condition.rs index 957eb806d150c..66b3f51644ea2 100644 --- a/crates/bevy_ecs/src/schedule/condition.rs +++ b/crates/bevy_ecs/src/schedule/condition.rs @@ -13,13 +13,20 @@ impl Condition for F where F: sealed::Condition {} mod sealed { use crate::system::{IntoSystem, ReadOnlySystem}; - pub trait Condition: IntoSystem<(), bool, Params> {} + pub trait Condition: + IntoSystem<(), bool, Params, System = Self::ReadOnlySystem> + { + // This associated type is necessary to let the compiler + // know that `Self::System` is `ReadOnlySystem`. + type ReadOnlySystem: ReadOnlySystem; + } impl Condition for F where F: IntoSystem<(), bool, Params>, F::System: ReadOnlySystem, { + type ReadOnlySystem = F::System; } } @@ -133,12 +140,9 @@ pub mod common_conditions { /// # /// # fn my_system() { unreachable!() } /// ``` - pub fn not>( - condition: C, - ) -> impl ReadOnlySystem - where - C::System: ReadOnlySystem, - { + pub fn not( + condition: impl Condition, + ) -> impl ReadOnlySystem { condition.pipe(|In(val): In| !val) } }