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 `<T as Condition>::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`.
This commit is contained in:
JoJoJet 2023-02-16 16:45:48 +00:00
parent 95c8d88d59
commit 81307290e2

View File

@ -13,13 +13,20 @@ impl<Params, F> Condition<Params> for F where F: sealed::Condition<Params> {}
mod sealed {
use crate::system::{IntoSystem, ReadOnlySystem};
pub trait Condition<Params>: IntoSystem<(), bool, Params> {}
pub trait Condition<Params>:
IntoSystem<(), bool, Params, System = Self::ReadOnlySystem>
{
// This associated type is necessary to let the compiler
// know that `Self::System` is `ReadOnlySystem`.
type ReadOnlySystem: ReadOnlySystem<In = (), Out = bool>;
}
impl<Params, F> Condition<Params> 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<Params, C: Condition<Params>>(
condition: C,
) -> impl ReadOnlySystem<In = (), Out = bool>
where
C::System: ReadOnlySystem,
{
pub fn not<Params>(
condition: impl Condition<Params>,
) -> impl ReadOnlySystem<In = (), Out = bool> {
condition.pipe(|In(val): In<bool>| !val)
}
}