bevyengine / bevyengine/bevy-website
Example in new book uses invalid trait object `Box<dyn Command + Clone>`
- Dominant language
- JavaScript
- Stars
- 249
- Forks
- 450
- Avg merge
- 16h 20m
- Merged PRs (30d)
- 6
Description
## Describe the issue
In the Designing Components chapter, under Storing Functions Inside of Components, the example uses `Box`. Unfortunately, this type doesn't compile:
```
error[E0225]: only auto traits can be used as additional traits in a trait object
--> src/main.rs:5:31
|
5 | fn bar(bar: Box) {}
| ------- ^^^^^ additional non-auto trait
| |
| first non-auto trait
|
= help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: bevy::prelude::Command + Clone {}`
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit
```
The error's proposed solution doesn't work either:
```rust
trait NewTrait: Command + Clone {}
fn bar(bar: Box) {}
```
```
error[E0038]: the trait `NewTrait` is not dyn compatible
--> src/main.rs:7:17
|
7 | fn bar(bar: Box) {}
| ^^^^^^^^^^^^ `NewTrait` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit
--> src/main.rs:5:27
|
5 | trait NewTrait: Command + Clone {}
| -------- ^^^^^ ...because it requires `Self: Sized`
| |
| this trait is not dyn compatible...
```
## Proposed Solution
At work, when I ran into this problem, I'd make a subtrait like `ClonableCommand: Command` with a method `fn clone(&self) -> Box`. That would detract from the focus of the example, though. I guess this example needs a use case where each command is only used once, so doesn't need `Clone`. Maybe something like
```rust
#[derive(Component)]
struct Projectile {
on_hit: Vec>,
}
```
In this case, when the projectile hits, you'd drain `on_hit`, running each command, and then despawn the entity.
Another solution would be to not encourage this pattern. Ime, it's rarely better than one-shot systems, but your mileage may vary.
Contributor guide
Research direction
Start in the Designing Components chapter under “Storing Functions Inside of Components” and review the example using `Box`. Check the example by compiling it, then update the documentation so it no longer presents an invalid trait-object pattern; the work is done when the documented example compiles and matches the intended use case.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- documentation
- Issue type
- Documentation
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100