Confusing trait bounds on `MaterialPlugin`
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 22h
- Merged PRs (30d)
- 161
Description
```rust
use bevy::{prelude::*, render::render_resource::AsBindGroup};
//#[derive(Clone, Copy, PartialEq, Eq, Hash)]
struct TestMaterialKey {
data: u8,
}
impl From<&TestMaterial> for TestMaterialKey {
fn from(value: &TestMaterial) -> Self {
Self {
data: value.data
}
}
}
#[derive(Clone, TypePath, AsBindGroup, Asset)]
#[bind_group_data(TestMaterialKey)]
struct TestMaterial {
data: u8
}
impl Material for TestMaterial { }
fn main() {
App::new().add_plugins(MaterialPlugin::::default()).run();
}
```
Does not compile, with the error:
```rust
error[E0277]: the trait bound `bevy::prelude::MaterialPlugin: Plugins<_>` is not satisfied
--> src/main.rs:23:28
|
23 | App::new().add_plugins(MaterialPlugin::::default()).run();
| ----------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `bevy::bevy_app::plugin::sealed::Plugins<_>` is not implemented for `bevy::prelude::MaterialPlugin`
| |
| required by a bound introduced by this call
|
= help: the following other types implement trait `bevy::bevy_app::plugin::sealed::Plugins`:
`()` implements `bevy::bevy_app::plugin::sealed::Plugins<(bevy::bevy_app::plugin::sealed::PluginsTupleMarker,)>`
`(S,)` implements `bevy::bevy_app::plugin::sealed::Plugins<(bevy::bevy_app::plugin::sealed::PluginsTupleMarker, P)>`
`(S0, S1)` implements `bevy::bevy_app::plugin::sealed::Plugins<(bevy::bevy_app::plugin::sealed::PluginsTupleMarker, P0, P1)>`
`(S0, S1, S2)` implements `bevy::bevy_app::plugin::sealed::Plugins<(bevy::bevy_app::plugin::sealed::PluginsTupleMarker, P0, P1, P2)>`
`(S0, S1, S2, S3)` implements `bevy::bevy_app::plugin::sealed::Plugins<(bevy::bevy_app::plugin::sealed::PluginsTupleMarker, P0, P1, P2, P3)>`
`(S0, S1, S2, S3, S4)` implements `bevy::bevy_app::plugin::sealed::Plugins<(bevy::bevy_app::plugin::sealed::PluginsTupleMarker, P0, P1, P2, P3, P4)>`
`(S0, S1, S2, S3, S4, S5)` implements `bevy::bevy_app::plugin::sealed::Plugins<(bevy::bevy_app::plugin::sealed::PluginsTupleMarker, P0, P1, P2, P3, P4, P5)>`
`(S0, S1, S2, S3, S4, S5, S6)` implements `bevy::bevy_app::plugin::sealed::Plugins<(bevy::bevy_app::plugin::sealed::PluginsTupleMarker, P0, P1, P2, P3, P4, P5, P6)>`
and 8 others
= note: required for `bevy::prelude::MaterialPlugin` to implement `Plugins<_>`
note: required by a bound in `bevy::prelude::App::add_plugins`
--> /home/jacobs/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_app-0.15.1/src/app.rs:548:52
|
548 | pub fn add_plugins(&mut self, plugins: impl Plugins) -> &mut Self {
| ^^^^^^^^^^ required by this bound in `App::add_plugins`
```
Uncommenting `#[derive(Clone, Copy, PartialEq, Eq, Hash)]` fixes the error.
The reason this does not work, is that `impl Plugin for MaterialPlugin` requires `::Data: PartialEq + Eq + Hash + Clone` however this is a pretty sneaky trait bound that is very easy to look over. I think that it should be a trait bound on `MaterialPlugin` too so that when a user attempts to do this they get a much more useful error. Failing that, I think more attention should be drawn to this in the docs because currently it's very easy to assume that any `MaterialPlugin` you are allowed to construct would implement `Plugin`. It's in the name after all.
Contributor guide
Assessment
This issue has not been assessed yet.