Skip to content

Commit 245d03a

Browse files
authored
bevy_reflect: Update on_unimplemented attributes (#15110)
# Objective Some of the new compile error messages are a little unclear (at least to me). For example: ``` error[E0277]: `tests::foo::Bar` can not be created through reflection --> crates/bevy_reflect/src/lib.rs:679:18 | 679 | #[derive(Reflect)] | ^^^^^^^ the trait `from_reflect::FromReflect` is not implemented for `tests::foo::Bar` | = note: consider annotating `tests::foo::Bar` with `#[derive(Reflect)]` or `#[derive(FromReflect)]` ``` While the annotation makes it clear that `FromReflect` is missing, it's not very clear from the main error message. My IDE lists errors with only their message immediately present: <p align="center"> <img width="700" alt="Image of said IDE listing errors with only their message immediately present. These errors are as follows: \"`tests::foo::Bar` can not be created through reflection\", \"The trait bound `tests::foo::Bar: RegisterForReflection` is not satisfied\", and \"The trait bound `tests::foo::Bar: type_info::MaybeTyped` is not satisfied\"" src="https://github.com/user-attachments/assets/42c24051-9e8e-4555-8477-51a9407446aa"> </p> This makes it hard to tell at a glance why my code isn't compiling. ## Solution Updated all `on_unimplemented` attributes in `bevy_reflect` to mention the relevant trait—either the actual trait or the one users actually need to implement—as well as a small snippet of what not implementing them means. For example, failing to implement `TypePath` now mentions missing a `TypePath` implementation. And failing to implement `DynamicTypePath` now also mentions missing a `TypePath` implementation, since that's the actual trait users need to implement (i.e. they shouldn't implement `DynamicTypePath` directly). Lastly, I also added some missing `on_unimplemented` attributes for `MaybeTyped` and `RegisterForReflection` (which you can see in the image above). Here's how this looks in my IDE now: <p align="center"> <img width="700" alt="Similar image as before showing the errors listed by the IDE. This time the errors read as follows: \"`tests::foo::Bar` does not implement `FromReflect` so cannot be reified through reflection\", \"`tests::foo::Bar` does not implement `GetTypeRegistration` so cannot be registered for reflection\", and \"`tests::foo::Bar` does not implement `Typed` so cannot provide static type information\"" src="https://github.com/user-attachments/assets/f6f8501f-0450-4f78-b84f-00e7a18d0533"> </p> ## Testing You can test by adding the following code and verifying the compile errors are correct: ```rust #[derive(Reflect)] struct Foo(Bar); struct Bar; ```
1 parent 5adacf0 commit 245d03a

File tree

8 files changed

+18
-10
lines changed

8 files changed

+18
-10
lines changed

crates/bevy_reflect/compile_fail/tests/reflect_derive/generics_fail.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ struct NoReflect(f32);
1212

1313
fn main() {
1414
let mut foo: Box<dyn Struct> = Box::new(Foo::<NoReflect> { a: NoReflect(42.0) });
15-
//~^ ERROR: `NoReflect` does not provide type registration information
16-
//~| ERROR: `NoReflect` can not provide type information through reflection
15+
//~^ ERROR: `NoReflect` does not implement `GetTypeRegistration` so cannot provide type registration information
16+
//~| ERROR: `NoReflect` does not implement `Typed` so cannot provide static type information
1717

1818
// foo doesn't implement Reflect because NoReflect doesn't implement Reflect
1919
foo.get_field::<NoReflect>("a").unwrap();

crates/bevy_reflect/compile_fail/tests/reflect_remote/nested_fail.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ mod incorrect_inner_type {
2525
//~^ ERROR: `TheirInner<T>` does not implement `PartialReflect` so cannot be introspected
2626
//~| ERROR: `TheirInner<T>` does not implement `PartialReflect` so cannot be introspected
2727
//~| ERROR: `TheirInner<T>` does not implement `PartialReflect` so cannot be introspected
28-
//~| ERROR: `TheirInner<T>` can not be used as a dynamic type path
28+
//~| ERROR: `TheirInner<T>` does not implement `TypePath` so cannot provide dynamic type path information
2929
//~| ERROR: `?` operator has incompatible types
3030
struct MyOuter<T: FromReflect + GetTypeRegistration> {
3131
// Reason: Should not use `MyInner<T>` directly

crates/bevy_reflect/src/from_reflect.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ use crate::{FromType, PartialReflect, Reflect};
2222
/// [`DynamicStruct`]: crate::DynamicStruct
2323
/// [crate-level documentation]: crate
2424
#[diagnostic::on_unimplemented(
25-
message = "`{Self}` can not be created through reflection",
26-
note = "consider annotating `{Self}` with `#[derive(FromReflect)]`"
25+
message = "`{Self}` does not implement `FromReflect` so cannot be created through reflection",
26+
note = "consider annotating `{Self}` with `#[derive(Reflect)]`"
2727
)]
2828
pub trait FromReflect: Reflect + Sized {
2929
/// Constructs a concrete instance of `Self` from a reflected value.

crates/bevy_reflect/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,10 @@ pub mod __macro_exports {
620620
///
621621
/// This trait has a blanket implementation for all types that implement `GetTypeRegistration`
622622
/// and manual implementations for all dynamic types (which simply do nothing).
623+
#[diagnostic::on_unimplemented(
624+
message = "`{Self}` does not implement `GetTypeRegistration` so cannot be registered for reflection",
625+
note = "consider annotating `{Self}` with `#[derive(Reflect)]`"
626+
)]
623627
pub trait RegisterForReflection {
624628
#[allow(unused_variables)]
625629
fn __register(registry: &mut TypeRegistry) {}

crates/bevy_reflect/src/path/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ impl<'a> ReflectPath<'a> for &'a str {
237237
/// [`Array`]: crate::Array
238238
/// [`Enum`]: crate::Enum
239239
#[diagnostic::on_unimplemented(
240-
message = "`{Self}` does not provide a reflection path",
240+
message = "`{Self}` does not implement `GetPath` so cannot be accessed by reflection path",
241241
note = "consider annotating `{Self}` with `#[derive(Reflect)]`"
242242
)]
243243
pub trait GetPath: PartialReflect {

crates/bevy_reflect/src/type_info.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ use thiserror::Error;
8383
///
8484
/// [utility]: crate::utility
8585
#[diagnostic::on_unimplemented(
86-
message = "`{Self}` can not provide type information through reflection",
86+
message = "`{Self}` does not implement `Typed` so cannot provide static type information",
8787
note = "consider annotating `{Self}` with `#[derive(Reflect)]`"
8888
)]
8989
pub trait Typed: Reflect + TypePath {
@@ -103,6 +103,10 @@ pub trait Typed: Reflect + TypePath {
103103
/// This trait has a blanket implementation for all types that implement `Typed`
104104
/// and manual implementations for all dynamic types (which simply return `None`).
105105
#[doc(hidden)]
106+
#[diagnostic::on_unimplemented(
107+
message = "`{Self}` does not implement `Typed` so cannot provide static type information",
108+
note = "consider annotating `{Self}` with `#[derive(Reflect)]`"
109+
)]
106110
pub trait MaybeTyped: PartialReflect {
107111
/// Returns the compile-time [info] for the underlying type, if it exists.
108112
///

crates/bevy_reflect/src/type_path.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ use std::fmt;
8080
/// [`module_path`]: TypePath::module_path
8181
/// [`type_ident`]: TypePath::type_ident
8282
#[diagnostic::on_unimplemented(
83-
message = "`{Self}` does not have a type path",
83+
message = "`{Self}` does not implement `TypePath` so cannot provide static type path information",
8484
note = "consider annotating `{Self}` with `#[derive(Reflect)]` or `#[derive(TypePath)]`"
8585
)]
8686
pub trait TypePath: 'static {
@@ -134,7 +134,7 @@ pub trait TypePath: 'static {
134134
///
135135
/// [`Reflect`]: crate::Reflect
136136
#[diagnostic::on_unimplemented(
137-
message = "`{Self}` can not be used as a dynamic type path",
137+
message = "`{Self}` does not implement `TypePath` so cannot provide dynamic type path information",
138138
note = "consider annotating `{Self}` with `#[derive(Reflect)]` or `#[derive(TypePath)]`"
139139
)]
140140
pub trait DynamicTypePath {

crates/bevy_reflect/src/type_registry.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ impl Debug for TypeRegistryArc {
5757
///
5858
/// [crate-level documentation]: crate
5959
#[diagnostic::on_unimplemented(
60-
message = "`{Self}` does not provide type registration information",
60+
message = "`{Self}` does not implement `GetTypeRegistration` so cannot provide type registration information",
6161
note = "consider annotating `{Self}` with `#[derive(Reflect)]`"
6262
)]
6363
pub trait GetTypeRegistration: 'static {

0 commit comments

Comments
 (0)