bevyengine / bevyengine/bevy-website

Example in new book uses invalid trait object `Box<dyn Command + Clone>`

Open
#2,423 1 comment 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.