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;
```
This commit is contained in:
parent
5adacf014c
commit
245d03a78a
@ -12,8 +12,8 @@ struct NoReflect(f32);
|
||||
|
||||
fn main() {
|
||||
let mut foo: Box<dyn Struct> = Box::new(Foo::<NoReflect> { a: NoReflect(42.0) });
|
||||
//~^ ERROR: `NoReflect` does not provide type registration information
|
||||
//~| ERROR: `NoReflect` can not provide type information through reflection
|
||||
//~^ ERROR: `NoReflect` does not implement `GetTypeRegistration` so cannot provide type registration information
|
||||
//~| ERROR: `NoReflect` does not implement `Typed` so cannot provide static type information
|
||||
|
||||
// foo doesn't implement Reflect because NoReflect doesn't implement Reflect
|
||||
foo.get_field::<NoReflect>("a").unwrap();
|
||||
|
||||
@ -25,7 +25,7 @@ mod incorrect_inner_type {
|
||||
//~^ ERROR: `TheirInner<T>` does not implement `PartialReflect` so cannot be introspected
|
||||
//~| ERROR: `TheirInner<T>` does not implement `PartialReflect` so cannot be introspected
|
||||
//~| ERROR: `TheirInner<T>` does not implement `PartialReflect` so cannot be introspected
|
||||
//~| ERROR: `TheirInner<T>` can not be used as a dynamic type path
|
||||
//~| ERROR: `TheirInner<T>` does not implement `TypePath` so cannot provide dynamic type path information
|
||||
//~| ERROR: `?` operator has incompatible types
|
||||
struct MyOuter<T: FromReflect + GetTypeRegistration> {
|
||||
// Reason: Should not use `MyInner<T>` directly
|
||||
|
||||
@ -22,8 +22,8 @@ use crate::{FromType, PartialReflect, Reflect};
|
||||
/// [`DynamicStruct`]: crate::DynamicStruct
|
||||
/// [crate-level documentation]: crate
|
||||
#[diagnostic::on_unimplemented(
|
||||
message = "`{Self}` can not be created through reflection",
|
||||
note = "consider annotating `{Self}` with `#[derive(FromReflect)]`"
|
||||
message = "`{Self}` does not implement `FromReflect` so cannot be created through reflection",
|
||||
note = "consider annotating `{Self}` with `#[derive(Reflect)]`"
|
||||
)]
|
||||
pub trait FromReflect: Reflect + Sized {
|
||||
/// Constructs a concrete instance of `Self` from a reflected value.
|
||||
|
||||
@ -620,6 +620,10 @@ pub mod __macro_exports {
|
||||
///
|
||||
/// This trait has a blanket implementation for all types that implement `GetTypeRegistration`
|
||||
/// and manual implementations for all dynamic types (which simply do nothing).
|
||||
#[diagnostic::on_unimplemented(
|
||||
message = "`{Self}` does not implement `GetTypeRegistration` so cannot be registered for reflection",
|
||||
note = "consider annotating `{Self}` with `#[derive(Reflect)]`"
|
||||
)]
|
||||
pub trait RegisterForReflection {
|
||||
#[allow(unused_variables)]
|
||||
fn __register(registry: &mut TypeRegistry) {}
|
||||
|
||||
@ -237,7 +237,7 @@ impl<'a> ReflectPath<'a> for &'a str {
|
||||
/// [`Array`]: crate::Array
|
||||
/// [`Enum`]: crate::Enum
|
||||
#[diagnostic::on_unimplemented(
|
||||
message = "`{Self}` does not provide a reflection path",
|
||||
message = "`{Self}` does not implement `GetPath` so cannot be accessed by reflection path",
|
||||
note = "consider annotating `{Self}` with `#[derive(Reflect)]`"
|
||||
)]
|
||||
pub trait GetPath: PartialReflect {
|
||||
|
||||
@ -83,7 +83,7 @@ use thiserror::Error;
|
||||
///
|
||||
/// [utility]: crate::utility
|
||||
#[diagnostic::on_unimplemented(
|
||||
message = "`{Self}` can not provide type information through reflection",
|
||||
message = "`{Self}` does not implement `Typed` so cannot provide static type information",
|
||||
note = "consider annotating `{Self}` with `#[derive(Reflect)]`"
|
||||
)]
|
||||
pub trait Typed: Reflect + TypePath {
|
||||
@ -103,6 +103,10 @@ pub trait Typed: Reflect + TypePath {
|
||||
/// This trait has a blanket implementation for all types that implement `Typed`
|
||||
/// and manual implementations for all dynamic types (which simply return `None`).
|
||||
#[doc(hidden)]
|
||||
#[diagnostic::on_unimplemented(
|
||||
message = "`{Self}` does not implement `Typed` so cannot provide static type information",
|
||||
note = "consider annotating `{Self}` with `#[derive(Reflect)]`"
|
||||
)]
|
||||
pub trait MaybeTyped: PartialReflect {
|
||||
/// Returns the compile-time [info] for the underlying type, if it exists.
|
||||
///
|
||||
|
||||
@ -80,7 +80,7 @@ use std::fmt;
|
||||
/// [`module_path`]: TypePath::module_path
|
||||
/// [`type_ident`]: TypePath::type_ident
|
||||
#[diagnostic::on_unimplemented(
|
||||
message = "`{Self}` does not have a type path",
|
||||
message = "`{Self}` does not implement `TypePath` so cannot provide static type path information",
|
||||
note = "consider annotating `{Self}` with `#[derive(Reflect)]` or `#[derive(TypePath)]`"
|
||||
)]
|
||||
pub trait TypePath: 'static {
|
||||
@ -134,7 +134,7 @@ pub trait TypePath: 'static {
|
||||
///
|
||||
/// [`Reflect`]: crate::Reflect
|
||||
#[diagnostic::on_unimplemented(
|
||||
message = "`{Self}` can not be used as a dynamic type path",
|
||||
message = "`{Self}` does not implement `TypePath` so cannot provide dynamic type path information",
|
||||
note = "consider annotating `{Self}` with `#[derive(Reflect)]` or `#[derive(TypePath)]`"
|
||||
)]
|
||||
pub trait DynamicTypePath {
|
||||
|
||||
@ -57,7 +57,7 @@ impl Debug for TypeRegistryArc {
|
||||
///
|
||||
/// [crate-level documentation]: crate
|
||||
#[diagnostic::on_unimplemented(
|
||||
message = "`{Self}` does not provide type registration information",
|
||||
message = "`{Self}` does not implement `GetTypeRegistration` so cannot provide type registration information",
|
||||
note = "consider annotating `{Self}` with `#[derive(Reflect)]`"
|
||||
)]
|
||||
pub trait GetTypeRegistration: 'static {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user