bevyengine / bevyengine/bevy

Error registering generic type with `PhantomData`

Open
#19,171 0 comments 0 reactions 0 assignees View on GitHub
A-Reflection C-Bug
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 22h
Merged PRs (30d)
161

Description

## Bevy version

0.16.0

## What you did

Tried to compile this code:

```rust
use bevy::prelude::*;

#[derive(Reflect)]
struct Foo(#[reflect(ignore)] core::marker::PhantomData);

fn plugin(app: &mut App) {
app.register_type::>();
}
```

## What went wrong

Got 3 long error messages complaining that `Foo` isn't `GetTypeRegistration` because `T` isn't `TypePath + Send + Sync`:

```
error[E0277]: `T` does not implement `TypePath` so cannot provide static type path information
--> src/lib.rs:7:25
|
7 | app.register_type::>();
| ------------- ^^^^^^ the trait `TypePath` is not implemented for `T`
| |
| required by a bound introduced by this call
|
= note: consider annotating `T` with `#[derive(Reflect)]` or `#[derive(TypePath)]`
note: required for `Foo` to implement `GetTypeRegistration`
--> src/lib.rs:3:10
|
3 | #[derive(Reflect)]
| ^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
4 | struct Foo(#[reflect(ignore)] core::marker::PhantomData);
| ^^^^^^
note: required by a bound in `bevy::prelude::App::register_type`
--> /home/benfrankel/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bevy_app-0.16.0/src/app.rs:595:29
|
595 | pub fn register_type(&mut self) -> &mut Self {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `App::register_type`
= note: this error originates in the derive macro `Reflect` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider restricting type parameter `T` with trait `TypePath`
|
6 | fn plugin(app: &mut App) {
| +++++++++++++++++++++++++

error[E0277]: `T` cannot be sent between threads safely
--> src/lib.rs:7:25
|
7 | app.register_type::>();
| ------------- ^^^^^^ `T` cannot be sent between threads safely
| |
| required by a bound introduced by this call
|
note: required because it appears within the type `PhantomData`
--> /home/benfrankel/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/marker.rs:774:12
|
774 | pub struct PhantomData;
| ^^^^^^^^^^^
note: required because it appears within the type `Foo`
--> src/lib.rs:4:8
|
4 | struct Foo(#[reflect(ignore)] core::marker::PhantomData);
| ^^^
note: required for `Foo` to implement `GetTypeRegistration`
--> src/lib.rs:3:10
|
3 | #[derive(Reflect)]
| ^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
4 | struct Foo(#[reflect(ignore)] core::marker::PhantomData);
| ^^^^^^
note: required by a bound in `bevy::prelude::App::register_type`
--> /home/benfrankel/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bevy_app-0.16.0/src/app.rs:595:29
|
595 | pub fn register_type(&mut self) -> &mut Self {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `App::register_type`
= note: this error originates in the derive macro `Reflect` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider restricting type parameter `T` with trait `Send`
|
6 | fn plugin(app: &mut App) {
| +++++++++++++++++++

error[E0277]: `T` cannot be shared between threads safely
--> src/lib.rs:7:25
|
7 | app.register_type::>();
| ------------- ^^^^^^ `T` cannot be shared between threads safely
| |
| required by a bound introduced by this call
|
note: required because it appears within the type `PhantomData`
--> /home/benfrankel/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/marker.rs:774:12
|
774 | pub struct PhantomData;
| ^^^^^^^^^^^
note: required because it appears within the type `Foo`
--> src/lib.rs:4:8
|
4 | struct Foo(#[reflect(ignore)] core::marker::PhantomData);
| ^^^
note: required for `Foo` to implement `GetTypeRegistration`
--> src/lib.rs:3:10
|
3 | #[derive(Reflect)]
| ^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
4 | struct Foo(#[reflect(ignore)] core::marker::PhantomData);
| ^^^^^^
note: required by a bound in `bevy::prelude::App::register_type`
--> /home/benfrankel/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bevy_app-0.16.0/src/app.rs:595:29
|
595 | pub fn register_type(&mut self) -> &mut Self {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `App::register_type`
= note: this error originates in the derive macro `Reflect` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider restricting type parameter `T` with trait `Sync`
|
6 | fn plugin(app: &mut App) {
| +++++++++++++++++++

For more information about this error, try `rustc --explain E0277`.
```

Contributor guide

Open the contributing guide

Research direction

Reproduce the generic Foo example in src/lib.rs, then inspect the Reflect derive behavior and the App::register_type requirement shown in bevy_app's app.rs. Determine why an ignored PhantomData field still imposes TypePath, Send, and Sync bounds. Done means the example registers Foo without unnecessary bounds and regression coverage verifies the behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
developer-experience
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.