Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion crates/bevy_ecs/src/system/system_registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,16 @@ impl World {

/// Runs a cached system, registering it if necessary.
///
/// # Type Inference Note
/// If the system returns `()`, you may need to explicitly constrain the output
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think inference actually works for system functions that return plain (), and we only get errors for systems that return Result.

Suggested change
/// If the system returns `()`, you may need to explicitly constrain the output
/// If the system returns `Result`, you may need to explicitly constrain the output

/// type for error handling:
///
/// ```rust
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll need to declare world and my_system for the doc tests to compile, like

Suggested change
/// ```rust
/// ```rust
/// # use bevy_ecs::prelude::*;
/// # fn my_system() -> Result { Ok(()) }
/// # let mut world = World::new();

And you'll also need input for the run_system_cached test.

/// () = world.run_system_cached(my_system)?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should also recommend using a turbofish, both here and below. It is more verbose, but it's idiomatic rust, while () = e; is an unusual construction.

Suggested change
/// () = world.run_system_cached(my_system)?;
/// // Either constrain the output type
/// () = world.run_system_cached(my_system)?;
/// // or supply the type parameter explicitly
/// world.run_system_cached::<(), _, _>(my_system)?;

/// ```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And since you're using ?, you'll need a trailing Ok expression for rustdoc to make the test fallible:

Suggested change
/// ```
/// # Ok::<(), BevyError>(())
/// ```

///
/// Without this, Rust may fail to infer the system’s output type and produce
/// a `IntoResult<!>` inference error.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh, I thought the error was "cannot infer type of the type parameter O declared on the method run_system_cached".

... Oh, I see, world.run_system_cached(my_system).unwrap() gives the helpful "cannot infer type" message, but world.run_system_cached(my_system)? gives the unhelpful "the trait function_system::IntoResult<!> is not implemented for core::result::Result<(), bevy_error::BevyError>". I wonder why that is. ... Huh, and if my_system returns !, then unwrap() still gives "cannot infer type", but ? actually compiles. So the compiler really assumes it's ! for some reason.


Anyway, it might be helpful to give a little more detail on the inference error, like:

Suggested change
/// a `IntoResult<!>` inference error.
/// an error either of the form
///
/// ```text
/// the trait `IntoResult<!>` is not implemented for `Result<(), BevyError>`
/// ```
///
/// or
///
/// ```text
/// cannot infer type of the type parameter `O` declared on the method `run_system_cached`
/// ```

/// See [`World::register_system_cached`] for more information.
pub fn run_system_cached<O: 'static, M, S: IntoSystem<(), O, M> + 'static>(
&mut self,
Expand All @@ -508,8 +518,21 @@ impl World {
self.run_system_cached_with(system, ())
}

/// Runs a cached system with an input, registering it if necessary.
/// Runs a cached system with the provided input, registering it if necessary.
///
/// This is a more general version of [`World::run_system_cached`], allowing
/// callers to supply an explicit system input.
///
/// # Type Inference Note
/// If the system returns `()`, you may need to explicitly constrain the
/// output type for proper error inference:
///
/// ```rust
/// () = world.run_system_cached_with(my_system, input)?;
/// ```
///
/// Without this, Rust may fail to infer the system’s output type and produce
/// a `IntoResult<!>` inference error.
/// See [`World::register_system_cached`] for more information.
pub fn run_system_cached_with<I, O, M, S>(
&mut self,
Expand Down
Loading