mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
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
8 changed files with 18 additions and 10 deletions
|
@ -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 a new issue