bevyengine / bevyengine/bevy

Assertion that run conditions are `Send` does not work in most cases

Open
#21,230 0 comments 1 reaction 0 assignees View on GitHub
A-ECS C-Bug I-Unsound
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 16h
Merged PRs (30d)
171

Description

## Bevy version

main

## What you did

I ran this:

```rs
use bevy::prelude::*;
use bevy::system::NonSendMarker;

fn noop() {}
fn non_send_condition(_: NonSendMarker) -> bool { true }

#[test]
#[should_panic]
fn should_panic() {
let mut world = World::new();
let mut schedule = Schedule::default();
schedule.add_systems(noop.run_if(non_send_condition));
schedule.initialize(&mut world).unwrap();
schedule.run(&mut world);
}
```

## What went wrong

The test did not succeed, no panic occurred.

## Additional information

While skimming the code I noticed [this function](https://dev-docs.bevy.org/src/bevy_ecs/schedule/config.rs.html#15-24):

```rs
fn new_condition(condition: impl SystemCondition) -> BoxedCondition {
let condition_system = IntoSystem::into_system(condition);
assert!(
condition_system.is_send(),
"SystemCondition `{}` accesses `NonSend` resources. This is not currently supported.",
condition_system.name()
);

Box::new(condition_system)
}
```

This cannot work in most cases, where the system is a `FunctionSystem`, because `System::is_send` is usually returned from `SystemMeta.flags`. These flags are [initially empty](https://dev-docs.bevy.org/src/bevy_ecs/system/function_system.rs.html#53), only after `System::initialize` for example `NonSend` [will update the flag](https://dev-docs.bevy.org/src/bevy_ecs/system/system_param.rs.html#1439). But no initialization happens here yet.

Personally I think it is a footgun that system methods like these do not return `Option`s or at least panic when they are not initialized.

Contributor guide

Open the contributing guide

Research direction

Start with the reproduction in the issue and inspect bevy_ecs/schedule/config.rs, then follow the referenced System::is_send and initialization code in bevy_ecs/system/function_system.rs and bevy_ecs/system/system_param.rs. Run the example test and trace when the condition system's flags are populated. Done means the documented assertion behavior is correctly exercised for a non-Send run condition.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
game-dev
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.