From 2bf80fcef4bfd7852d43e10b76be648ca97809ca Mon Sep 17 00:00:00 2001 From: Zac Harrold Date: Mon, 13 May 2024 12:02:06 +1000 Subject: [PATCH 1/7] Add `on_unimplemented` Diagnostics to Most Public Traits --- Cargo.toml | 2 +- crates/bevy_animation/src/animatable.rs | 4 ++++ crates/bevy_app/src/plugin.rs | 7 +++++- crates/bevy_app/src/plugin_group.rs | 4 ++++ crates/bevy_asset/src/direct_access_ext.rs | 1 + crates/bevy_asset/src/io/mod.rs | 24 +++++++++++++++++++ crates/bevy_asset/src/lib.rs | 10 ++++++++ crates/bevy_asset/src/loader.rs | 12 ++++++++++ crates/bevy_asset/src/meta.rs | 8 +++++++ crates/bevy_asset/src/processor/process.rs | 8 +++++++ crates/bevy_asset/src/saver.rs | 8 +++++++ crates/bevy_asset/src/transformer.rs | 4 ++++ crates/bevy_audio/src/audio_source.rs | 5 ++++ crates/bevy_audio/src/sinks.rs | 4 ++++ crates/bevy_color/src/color_difference.rs | 4 ++++ crates/bevy_color/src/color_ops.rs | 20 ++++++++++++++++ crates/bevy_color/src/color_range.rs | 4 ++++ crates/bevy_diagnostic/src/diagnostic.rs | 1 + crates/bevy_dynamic_plugin/src/loader.rs | 1 + crates/bevy_ecs/src/bundle.rs | 4 ++++ crates/bevy_ecs/src/change_detection.rs | 8 +++++++ crates/bevy_ecs/src/component.rs | 5 ++++ crates/bevy_ecs/src/entity/map_entities.rs | 6 ++++- crates/bevy_ecs/src/event.rs | 5 ++++ crates/bevy_ecs/src/intern.rs | 4 ++++ crates/bevy_ecs/src/label.rs | 6 +++++ crates/bevy_ecs/src/query/fetch.rs | 4 ++++ crates/bevy_ecs/src/query/filter.rs | 9 ++++++- .../bevy_ecs/src/reflect/entity_commands.rs | 1 + crates/bevy_ecs/src/schedule/condition.rs | 4 ++++ crates/bevy_ecs/src/schedule/config.rs | 8 +++++++ crates/bevy_ecs/src/schedule/set.rs | 4 ++++ crates/bevy_ecs/src/storage/sparse_set.rs | 4 ++++ crates/bevy_ecs/src/system/adapter_system.rs | 4 ++++ crates/bevy_ecs/src/system/combinator.rs | 4 ++++ crates/bevy_ecs/src/system/commands/mod.rs | 4 ++++ .../src/system/exclusive_function_system.rs | 6 ++++- .../src/system/exclusive_system_param.rs | 4 ++++ crates/bevy_ecs/src/system/function_system.rs | 1 + crates/bevy_ecs/src/system/mod.rs | 5 ++++ crates/bevy_ecs/src/system/system.rs | 5 ++++ crates/bevy_ecs/src/system/system_param.rs | 9 +++++++ crates/bevy_ecs/src/world/mod.rs | 2 ++ crates/bevy_gizmos/src/config.rs | 4 ++++ crates/bevy_gizmos/src/lib.rs | 1 + crates/bevy_gizmos/src/primitives/dim2.rs | 4 ++++ crates/bevy_gizmos/src/primitives/dim3.rs | 4 ++++ crates/bevy_hierarchy/src/child_builder.rs | 8 +++++++ crates/bevy_hierarchy/src/hierarchy.rs | 4 ++++ crates/bevy_hierarchy/src/query_extension.rs | 1 + .../bevy_math/src/bounding/bounded2d/mod.rs | 1 + .../bevy_math/src/bounding/bounded3d/mod.rs | 1 + crates/bevy_math/src/bounding/mod.rs | 8 +++++++ crates/bevy_math/src/common_traits.rs | 8 +++++++ crates/bevy_math/src/cubic_splines.rs | 8 +++++++ crates/bevy_math/src/primitives/mod.rs | 16 +++++++++++++ .../bevy_math/src/sampling/shape_sampling.rs | 1 + crates/bevy_math/src/sampling/standard.rs | 3 +++ crates/bevy_pbr/src/extended_material.rs | 4 ++++ crates/bevy_pbr/src/light_probe/mod.rs | 4 ++++ crates/bevy_pbr/src/material.rs | 4 ++++ .../bevy_pbr/src/meshlet/persistent_buffer.rs | 4 ++++ crates/bevy_ptr/src/lib.rs | 8 +++++++ .../tests/reflect_derive/generics_fail.rs | 4 ++-- .../tests/reflect_derive/generics_fail.stderr | 13 ++++++---- crates/bevy_reflect/src/array.rs | 1 + crates/bevy_reflect/src/enums/enum_trait.rs | 1 + crates/bevy_reflect/src/from_reflect.rs | 1 + crates/bevy_reflect/src/list.rs | 1 + crates/bevy_reflect/src/map.rs | 1 + crates/bevy_reflect/src/path/mod.rs | 9 +++++++ crates/bevy_reflect/src/reflect.rs | 4 ++++ crates/bevy_reflect/src/struct_trait.rs | 2 ++ crates/bevy_reflect/src/tuple.rs | 2 ++ crates/bevy_reflect/src/tuple_struct.rs | 8 +++++++ crates/bevy_reflect/src/type_info.rs | 1 + crates/bevy_reflect/src/type_path.rs | 9 +++++++ crates/bevy_reflect/src/type_registry.rs | 5 ++++ crates/bevy_render/src/camera/projection.rs | 1 + crates/bevy_render/src/extract_component.rs | 4 ++++ crates/bevy_render/src/extract_instances.rs | 4 ++++ crates/bevy_render/src/extract_resource.rs | 4 ++++ crates/bevy_render/src/mesh/primitives/mod.rs | 4 ++++ crates/bevy_render/src/render_asset.rs | 4 ++++ crates/bevy_render/src/render_graph/app.rs | 1 + crates/bevy_render/src/render_graph/node.rs | 10 +++++++- crates/bevy_render/src/render_phase/draw.rs | 9 +++++++ crates/bevy_render/src/render_phase/mod.rs | 13 ++++++++++ .../src/render_resource/bind_group.rs | 4 ++++ .../src/render_resource/gpu_array_buffer.rs | 4 ++++ crates/bevy_render/src/texture/image.rs | 8 +++++++ crates/bevy_sprite/src/mesh2d/material.rs | 4 ++++ .../bevy_state/src/state/computed_states.rs | 4 ++++ .../src/state/freely_mutable_state.rs | 5 ++++ crates/bevy_state/src/state/state_set.rs | 4 ++++ crates/bevy_state/src/state/states.rs | 5 ++++ crates/bevy_state/src/state/sub_states.rs | 5 ++++ crates/bevy_tasks/src/iter/mod.rs | 4 ++++ crates/bevy_tasks/src/slice.rs | 2 ++ crates/bevy_ui/src/measurement.rs | 1 + crates/bevy_ui/src/ui_material.rs | 4 ++++ 101 files changed, 500 insertions(+), 13 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b8ebfd23269d4..05773e978e52f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ keywords = ["game", "engine", "gamedev", "graphics", "bevy"] license = "MIT OR Apache-2.0" repository = "https://github.com/bevyengine/bevy" documentation = "https://docs.rs/bevy" -rust-version = "1.77.0" +rust-version = "1.78.0" [workspace] exclude = [ diff --git a/crates/bevy_animation/src/animatable.rs b/crates/bevy_animation/src/animatable.rs index 4e59ccc8b2875..f35e8846d2e51 100644 --- a/crates/bevy_animation/src/animatable.rs +++ b/crates/bevy_animation/src/animatable.rs @@ -16,6 +16,10 @@ pub struct BlendInput { } /// An animatable value type. +#[diagnostic::on_unimplemented( + message = "`{Self}` can not be animated", + label = "invalid animatable" +)] pub trait Animatable: Reflect + Sized + Send + Sync + 'static { /// Interpolates between `a` and `b` with a interpolation factor of `time`. /// diff --git a/crates/bevy_app/src/plugin.rs b/crates/bevy_app/src/plugin.rs index d3307485fecbb..7103a58dd8935 100644 --- a/crates/bevy_app/src/plugin.rs +++ b/crates/bevy_app/src/plugin.rs @@ -54,7 +54,8 @@ use std::any::Any; /// } /// } /// # fn damp_flickering() {} -/// ```` +/// ``` +#[diagnostic::on_unimplemented(message = "`{Self}` is not a plugin", label = "invalid plugin")] pub trait Plugin: Downcast + Any + Send + Sync { /// Configures the [`App`] to which this plugin is added. fn build(&self, app: &mut App); @@ -130,6 +131,10 @@ pub type CreatePlugin = unsafe fn() -> *mut dyn Plugin; /// /// This is implemented for all types which implement [`Plugin`], /// [`PluginGroup`](super::PluginGroup), and tuples over [`Plugins`]. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a set of plugins", + label = "invalid plugin set" +)] pub trait Plugins: sealed::Plugins {} impl Plugins for T where T: sealed::Plugins {} diff --git a/crates/bevy_app/src/plugin_group.rs b/crates/bevy_app/src/plugin_group.rs index b41a78f067a1a..b0082a8d0f5b0 100644 --- a/crates/bevy_app/src/plugin_group.rs +++ b/crates/bevy_app/src/plugin_group.rs @@ -3,6 +3,10 @@ use bevy_utils::{tracing::debug, tracing::warn, TypeIdMap}; use std::any::TypeId; /// Combines multiple [`Plugin`]s into a single unit. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a plugin group", + label = "invalid plugin group" +)] pub trait PluginGroup: Sized { /// Configures the [`Plugin`]s that are to be added. fn build(self) -> PluginGroupBuilder; diff --git a/crates/bevy_asset/src/direct_access_ext.rs b/crates/bevy_asset/src/direct_access_ext.rs index bfa7fa17b29c0..293ea05228ce6 100644 --- a/crates/bevy_asset/src/direct_access_ext.rs +++ b/crates/bevy_asset/src/direct_access_ext.rs @@ -5,6 +5,7 @@ use bevy_ecs::world::World; use crate::{meta::Settings, Asset, AssetPath, AssetServer, Assets, Handle}; +#[diagnostic::on_unimplemented(message = "`{Self}` is not a World", label = "invalid world")] pub trait DirectAssetAccessExt { /// Insert an asset similarly to [`Assets::add`]. fn add_asset(&mut self, asset: impl Into) -> Handle; diff --git a/crates/bevy_asset/src/io/mod.rs b/crates/bevy_asset/src/io/mod.rs index a249d7d06121b..4b15cb4c453ca 100644 --- a/crates/bevy_asset/src/io/mod.rs +++ b/crates/bevy_asset/src/io/mod.rs @@ -72,6 +72,10 @@ impl From for AssetReaderError { } } +#[diagnostic::on_unimplemented( + message = "`{Self}` is not an asynchronous and seekable reader", + label = "invalid reader" +)] pub trait AsyncReadAndSeek: AsyncRead + AsyncSeek {} impl AsyncReadAndSeek for T {} @@ -83,6 +87,10 @@ pub type Reader<'a> = dyn AsyncReadAndSeek + Unpin + Send + Sync + 'a; /// `path`. This trait is not object safe, if needed use a dyn [`ErasedAssetReader`] instead. /// /// Also see [`AssetWriter`]. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not an asset reader", + label = "invalid asset reader" +)] pub trait AssetReader: Send + Sync + 'static { /// Returns a future to load the full file data at the provided path. fn read<'a>( @@ -121,6 +129,10 @@ pub trait AssetReader: Send + Sync + 'static { /// Equivalent to an [`AssetReader`] but using boxed futures, necessary eg. when using a `dyn AssetReader`, /// as [`AssetReader`] isn't currently object safe. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not an erasable asset reader", + label = "invalid asset reader" +)] pub trait ErasedAssetReader: Send + Sync + 'static { /// Returns a future to load the full file data at the provided path. fn read<'a>(&'a self, path: &'a Path) @@ -192,6 +204,10 @@ pub enum AssetWriterError { /// `path`. This trait is not object safe, if needed use a dyn [`ErasedAssetWriter`] instead. /// /// Also see [`AssetReader`]. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not an asset writer", + label = "invalid asset writer" +)] pub trait AssetWriter: Send + Sync + 'static { /// Writes the full asset bytes at the provided path. fn write<'a>( @@ -274,6 +290,10 @@ pub trait AssetWriter: Send + Sync + 'static { /// Equivalent to an [`AssetWriter`] but using boxed futures, necessary eg. when using a `dyn AssetWriter`, /// as [`AssetWriter`] isn't currently object safe. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not an erasable asset writer", + label = "invalid asset writer" +)] pub trait ErasedAssetWriter: Send + Sync + 'static { /// Writes the full asset bytes at the provided path. fn write<'a>(&'a self, path: &'a Path) -> BoxedFuture, AssetWriterError>>; @@ -429,6 +449,10 @@ pub enum AssetSourceEvent { /// A handle to an "asset watcher" process, that will listen for and emit [`AssetSourceEvent`] values for as long as /// [`AssetWatcher`] has not been dropped. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not an asset watcher", + label = "invalid asset watcher" +)] pub trait AssetWatcher: Send + Sync + 'static {} /// An [`AsyncRead`] implementation capable of reading a [`Vec`]. diff --git a/crates/bevy_asset/src/lib.rs b/crates/bevy_asset/src/lib.rs index ea8caf003a1dd..db38ba0742dd8 100644 --- a/crates/bevy_asset/src/lib.rs +++ b/crates/bevy_asset/src/lib.rs @@ -223,8 +223,17 @@ impl Plugin for AssetPlugin { } } +#[diagnostic::on_unimplemented( + message = "`{Self}` is not an asset", + label = "invalid asset", + note = "consider annotating `{Self}` with `#[derive(Asset)]`" +)] pub trait Asset: VisitAssetDependencies + TypePath + Send + Sync + 'static {} +#[diagnostic::on_unimplemented( + message = "`{Self}` can not visit dependencies", + label = "invalid asset" +)] pub trait VisitAssetDependencies { fn visit_dependencies(&self, visit: &mut impl FnMut(UntypedAssetId)); } @@ -274,6 +283,7 @@ impl VisitAssetDependencies for Vec { } /// Adds asset-related builder methods to [`App`]. +#[diagnostic::on_unimplemented(message = "`{Self}` is not an App", label = "invalid `App`")] pub trait AssetApp { /// Registers the given `loader` in the [`App`]'s [`AssetServer`]. fn register_asset_loader(&mut self, loader: L) -> &mut Self; diff --git a/crates/bevy_asset/src/loader.rs b/crates/bevy_asset/src/loader.rs index 8630ffea8f1e5..333b4010522d0 100644 --- a/crates/bevy_asset/src/loader.rs +++ b/crates/bevy_asset/src/loader.rs @@ -22,6 +22,10 @@ use thiserror::Error; /// Loads an [`Asset`] from a given byte [`Reader`]. This can accept [`AssetLoader::Settings`], which configure how the [`Asset`] /// should be loaded. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not an asset loader", + label = "invalid asset loader" +)] pub trait AssetLoader: Send + Sync + 'static { /// The top level [`Asset`] loaded by this [`AssetLoader`]. type Asset: crate::Asset; @@ -45,6 +49,10 @@ pub trait AssetLoader: Send + Sync + 'static { } /// Provides type-erased access to an [`AssetLoader`]. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not an erasable asset loader", + label = "invalid asset loader" +)] pub trait ErasedAssetLoader: Send + Sync + 'static { /// Asynchronously loads the asset(s) from the bytes provided by [`Reader`]. fn load<'a>( @@ -231,6 +239,10 @@ impl ErasedLoadedAsset { } /// A type erased container for an [`Asset`] value that is capable of inserting the [`Asset`] into a [`World`]'s [`Assets`] collection. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not an asset container", + label = "invalid container" +)] pub trait AssetContainer: Downcast + Any + Send + Sync + 'static { fn insert(self: Box, id: UntypedAssetId, world: &mut World); fn asset_type_name(&self) -> &'static str; diff --git a/crates/bevy_asset/src/meta.rs b/crates/bevy_asset/src/meta.rs index dcfdd957a408a..7e8d51f039889 100644 --- a/crates/bevy_asset/src/meta.rs +++ b/crates/bevy_asset/src/meta.rs @@ -114,6 +114,10 @@ pub struct ProcessedInfoMinimal { /// A dynamic type-erased counterpart to [`AssetMeta`] that enables passing around and interacting with [`AssetMeta`] without knowing /// its type. +#[diagnostic::on_unimplemented( + message = "`{Self}` can not be used as an erased AssetMeta", + label = "invalid asset meta" +)] pub trait AssetMetaDyn: Downcast + Send + Sync { /// Returns a reference to the [`AssetLoader`] settings, if they exist. fn loader_settings(&self) -> Option<&dyn Settings>; @@ -160,6 +164,10 @@ impl_downcast!(AssetMetaDyn); /// Settings used by the asset system, such as by [`AssetLoader`], [`Process`], and [`AssetSaver`] /// /// [`AssetSaver`]: crate::saver::AssetSaver +#[diagnostic::on_unimplemented( + message = "`{Self}` can not be used as an asset setting", + label = "invalid settings" +)] pub trait Settings: Downcast + Send + Sync + 'static {} impl Settings for T where T: Send + Sync {} diff --git a/crates/bevy_asset/src/processor/process.rs b/crates/bevy_asset/src/processor/process.rs index 442c9451c868d..0cbe071dfffca 100644 --- a/crates/bevy_asset/src/processor/process.rs +++ b/crates/bevy_asset/src/processor/process.rs @@ -21,6 +21,10 @@ use thiserror::Error; /// /// This is a "low level", maximally flexible interface. Most use cases are better served by the [`LoadTransformAndSave`] implementation /// of [`Process`]. +#[diagnostic::on_unimplemented( + message = "`{Self}` can not process assets", + label = "invalid asset process" +)] pub trait Process: Send + Sync + Sized + 'static { /// The configuration / settings used to process the asset. This will be stored in the [`AssetMeta`] and is user-configurable per-asset. type Settings: Settings + Default + Serialize + for<'a> Deserialize<'a>; @@ -243,6 +247,10 @@ impl> Process /// A type-erased variant of [`Process`] that enables interacting with processor implementations without knowing /// their type. +#[diagnostic::on_unimplemented( + message = "`{Self}` can not be erased", + label = "invalid asset process" +)] pub trait ErasedProcessor: Send + Sync { /// Type-erased variant of [`Process::process`]. fn process<'a>( diff --git a/crates/bevy_asset/src/saver.rs b/crates/bevy_asset/src/saver.rs index 36408dd125f29..0ee2a87db9ab9 100644 --- a/crates/bevy_asset/src/saver.rs +++ b/crates/bevy_asset/src/saver.rs @@ -7,6 +7,10 @@ use std::{borrow::Borrow, hash::Hash, ops::Deref}; /// Saves an [`Asset`] of a given [`AssetSaver::Asset`] type. [`AssetSaver::OutputLoader`] will then be used to load the saved asset /// in the final deployed application. The saver should produce asset bytes in a format that [`AssetSaver::OutputLoader`] can read. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not an asset saver", + label = "invalid asset saver" +)] pub trait AssetSaver: Send + Sync + 'static { /// The top level [`Asset`] saved by this [`AssetSaver`]. type Asset: Asset; @@ -30,6 +34,10 @@ pub trait AssetSaver: Send + Sync + 'static { } /// A type-erased dynamic variant of [`AssetSaver`] that allows callers to save assets without knowing the actual type of the [`AssetSaver`]. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not an erasable asset saver", + label = "invalid asset saver" +)] pub trait ErasedAssetSaver: Send + Sync + 'static { /// Saves the given runtime [`ErasedLoadedAsset`] by writing it to a byte format using `writer`. The passed in `settings` can influence how the /// `asset` is saved. diff --git a/crates/bevy_asset/src/transformer.rs b/crates/bevy_asset/src/transformer.rs index 0ffddc4658a43..196fd7a8b576a 100644 --- a/crates/bevy_asset/src/transformer.rs +++ b/crates/bevy_asset/src/transformer.rs @@ -8,6 +8,10 @@ use std::{ }; /// Transforms an [`Asset`] of a given [`AssetTransformer::AssetInput`] type to an [`Asset`] of [`AssetTransformer::AssetOutput`] type. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not an asset transformer", + label = "invalid asset transformer" +)] pub trait AssetTransformer: Send + Sync + 'static { /// The [`Asset`] type which this [`AssetTransformer`] takes as and input. type AssetInput: Asset; diff --git a/crates/bevy_audio/src/audio_source.rs b/crates/bevy_audio/src/audio_source.rs index b501eaeea09af..11a78422d9e06 100644 --- a/crates/bevy_audio/src/audio_source.rs +++ b/crates/bevy_audio/src/audio_source.rs @@ -80,6 +80,10 @@ impl AssetLoader for AudioLoader { /// Types that implement this trait usually contain raw sound data that can be converted into an iterator of samples. /// This trait is implemented for [`AudioSource`]. /// Check the example [`decodable`](https://github.com/bevyengine/bevy/blob/latest/examples/audio/decodable.rs) for how to implement this trait on a custom type. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a decodable audio source", + label = "invalid Source" +)] pub trait Decodable: Send + Sync + 'static { /// The type of the audio samples. /// Usually a [`u16`], [`i16`] or [`f32`], as those implement [`rodio::Sample`]. @@ -106,6 +110,7 @@ impl Decodable for AudioSource { /// A trait that allows adding a custom audio source to the object. /// This is implemented for [`App`][bevy_app::App] to allow registering custom [`Decodable`] types. +#[diagnostic::on_unimplemented(message = "`{Self}` is not an App", label = "invalid `App`")] pub trait AddAudioSource { /// Registers an audio source. /// The type must implement [`Decodable`], diff --git a/crates/bevy_audio/src/sinks.rs b/crates/bevy_audio/src/sinks.rs index 68fa1e99c4543..734dfa17605fd 100644 --- a/crates/bevy_audio/src/sinks.rs +++ b/crates/bevy_audio/src/sinks.rs @@ -4,6 +4,10 @@ use bevy_transform::prelude::Transform; use rodio::{Sink, SpatialSink}; /// Common interactions with an audio sink. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not an audio sink", + label = "invalid audio sink" +)] pub trait AudioSinkPlayback { /// Gets the volume of the sound. /// diff --git a/crates/bevy_color/src/color_difference.rs b/crates/bevy_color/src/color_difference.rs index a2bdf10e14549..48a59a3bf7fb9 100644 --- a/crates/bevy_color/src/color_difference.rs +++ b/crates/bevy_color/src/color_difference.rs @@ -2,6 +2,10 @@ /// Calculate the distance between this and another color as if they were coordinates /// in a Euclidean space. Alpha is not considered in the distance calculation. +#[diagnostic::on_unimplemented( + message = "`{Self}` does not have a definition for distance", + label = "invalid color model" +)] pub trait EuclideanDistance: Sized { /// Distance from `self` to `other`. fn distance(&self, other: &Self) -> f32 { diff --git a/crates/bevy_color/src/color_ops.rs b/crates/bevy_color/src/color_ops.rs index e37592bdd4dba..ec9f4b9478988 100644 --- a/crates/bevy_color/src/color_ops.rs +++ b/crates/bevy_color/src/color_ops.rs @@ -3,6 +3,10 @@ use bevy_math::{Vec3, Vec4}; /// Methods for changing the luminance of a color. Note that these methods are not /// guaranteed to produce consistent results across color spaces, /// but will be within a given space. +#[diagnostic::on_unimplemented( + message = "`{Self}` does not have a definition of luminance", + label = "non-luminance color model" +)] pub trait Luminance: Sized { /// Return the luminance of this color (0.0 - 1.0). fn luminance(&self) -> f32; @@ -30,6 +34,10 @@ pub trait Luminance: Sized { } /// Linear interpolation of two colors within a given color space. +#[diagnostic::on_unimplemented( + message = "`{Self}` can not be mixed", + label = "unmixable color model" +)] pub trait Mix: Sized { /// Linearly interpolate between this and another color, by factor. /// Factor should be between 0.0 and 1.0. @@ -43,6 +51,10 @@ pub trait Mix: Sized { } /// Methods for manipulating alpha values. +#[diagnostic::on_unimplemented( + message = "`{Self}` does not have an alpha channel", + label = "opaque color model" +)] pub trait Alpha: Sized { /// Return a new version of this color with the given alpha value. fn with_alpha(&self, alpha: f32) -> Self; @@ -65,6 +77,10 @@ pub trait Alpha: Sized { } /// Trait for manipulating the hue of a color. +#[diagnostic::on_unimplemented( + message = "`{Self}` does not have a definition of hue", + label = "non-hue color model" +)] pub trait Hue: Sized { /// Return a new version of this color with the hue channel set to the given value. fn with_hue(&self, hue: f32) -> Self; @@ -83,6 +99,10 @@ pub trait Hue: Sized { } /// Trait with methods for converting colors to non-color types +#[diagnostic::on_unimplemented( + message = "`{Self}` cannot be decomposed into color components", + label = "invalid color model" +)] pub trait ColorToComponents { /// Convert to an f32 array fn to_f32_array(self) -> [f32; 4]; diff --git a/crates/bevy_color/src/color_range.rs b/crates/bevy_color/src/color_range.rs index 16d6f04866670..7c375831b6a16 100644 --- a/crates/bevy_color/src/color_range.rs +++ b/crates/bevy_color/src/color_range.rs @@ -7,6 +7,10 @@ use crate::Mix; /// implements [`Mix`]. /// /// This is useful for defining gradients or animated color transitions. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a valid color range", + label = "invalid color range" +)] pub trait ColorRange { /// Get the color value at the given interpolation factor, which should be between 0.0 (start) /// and 1.0 (end). diff --git a/crates/bevy_diagnostic/src/diagnostic.rs b/crates/bevy_diagnostic/src/diagnostic.rs index b45ee593cfab3..3eed83a91f657 100644 --- a/crates/bevy_diagnostic/src/diagnostic.rs +++ b/crates/bevy_diagnostic/src/diagnostic.rs @@ -382,6 +382,7 @@ impl SystemBuffer for DiagnosticsBuffer { } /// Extend [`App`] with new `register_diagnostic` function. +#[diagnostic::on_unimplemented(message = "`{Self}` is not an App", label = "invalid `App`")] pub trait RegisterDiagnostic { /// Register a new [`Diagnostic`] with an [`App`]. /// diff --git a/crates/bevy_dynamic_plugin/src/loader.rs b/crates/bevy_dynamic_plugin/src/loader.rs index 8b6517b237244..892321e825746 100644 --- a/crates/bevy_dynamic_plugin/src/loader.rs +++ b/crates/bevy_dynamic_plugin/src/loader.rs @@ -51,6 +51,7 @@ pub unsafe fn dynamically_load_plugin>( } /// An extension trait for [`App`] that allows loading dynamic plugins. +#[diagnostic::on_unimplemented(message = "`{Self}` is not an App", label = "invalid `App`")] pub trait DynamicPluginExt { /// Dynamically links a plugin at the given path, registering the plugin. /// diff --git a/crates/bevy_ecs/src/bundle.rs b/crates/bevy_ecs/src/bundle.rs index 7ba65e9ba42cd..eb1d4737dca28 100644 --- a/crates/bevy_ecs/src/bundle.rs +++ b/crates/bevy_ecs/src/bundle.rs @@ -165,6 +165,10 @@ pub unsafe trait Bundle: DynamicBundle + Send + Sync + 'static { } /// The parts from [`Bundle`] that don't require statically knowing the components of the bundle. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a dynamic component bundle", + label = "invalid bundle" +)] pub trait DynamicBundle { // SAFETY: // The `StorageType` argument passed into [`Bundle::get_components`] must be correct for the diff --git a/crates/bevy_ecs/src/change_detection.rs b/crates/bevy_ecs/src/change_detection.rs index d4cc1a73af4dd..430653ebaf3b9 100644 --- a/crates/bevy_ecs/src/change_detection.rs +++ b/crates/bevy_ecs/src/change_detection.rs @@ -43,6 +43,10 @@ pub const MAX_CHANGE_AGE: u32 = u32::MAX - (2 * CHECK_TICK_THRESHOLD - 1); /// } /// } /// ``` +#[diagnostic::on_unimplemented( + message = "`{Self}` does not support change detection", + label = "invalid change detecter" +)] pub trait DetectChanges { /// Returns `true` if this value was added after the system last ran. fn is_added(&self) -> bool; @@ -95,6 +99,10 @@ pub trait DetectChanges { /// } /// ``` /// +#[diagnostic::on_unimplemented( + message = "`{Self}` does not support mutable change detection", + label = "invalid change detecter" +)] pub trait DetectChangesMut: DetectChanges { /// The type contained within this smart pointer /// diff --git a/crates/bevy_ecs/src/component.rs b/crates/bevy_ecs/src/component.rs index 6b91c432f52bd..5eb2a478b7674 100644 --- a/crates/bevy_ecs/src/component.rs +++ b/crates/bevy_ecs/src/component.rs @@ -150,6 +150,11 @@ use std::{ /// /// [`SyncCell`]: bevy_utils::synccell::SyncCell /// [`Exclusive`]: https://doc.rust-lang.org/nightly/std/sync/struct.Exclusive.html +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a component", + label = "invalid component", + note = "consider annotating `{Self}` with `#[derive(Component)]`" +)] pub trait Component: Send + Sync + 'static { /// A constant indicating the storage type used for this component. const STORAGE_TYPE: StorageType; diff --git a/crates/bevy_ecs/src/entity/map_entities.rs b/crates/bevy_ecs/src/entity/map_entities.rs index 083b7a5075b2e..7b9ae1464ef71 100644 --- a/crates/bevy_ecs/src/entity/map_entities.rs +++ b/crates/bevy_ecs/src/entity/map_entities.rs @@ -37,7 +37,7 @@ use super::EntityHashMap; /// } /// } /// ``` -/// +#[diagnostic::on_unimplemented(message = "`{Self}` can not map entities")] pub trait MapEntities { /// Updates all [`Entity`] references stored inside using `entity_mapper`. /// @@ -71,6 +71,10 @@ pub trait MapEntities { /// } /// } /// ``` +#[diagnostic::on_unimplemented( + message = "`{Self}` is not an entity mapper", + label = "invalid entity mapper" +)] pub trait EntityMapper { /// Map an entity to another entity fn map_entity(&mut self, entity: Entity) -> Entity; diff --git a/crates/bevy_ecs/src/event.rs b/crates/bevy_ecs/src/event.rs index 5f5b7092f047e..5ac71831caaab 100644 --- a/crates/bevy_ecs/src/event.rs +++ b/crates/bevy_ecs/src/event.rs @@ -28,6 +28,11 @@ use std::{ /// You can conveniently access events using the [`EventReader`] and [`EventWriter`] system parameter. /// /// Events must be thread-safe. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not an event", + label = "invalid event", + note = "consider annotating `{Self}` with `#[derive(Event]`" +)] pub trait Event: Send + Sync + 'static {} /// An `EventId` uniquely identifies an event stored in a specific [`World`]. diff --git a/crates/bevy_ecs/src/intern.rs b/crates/bevy_ecs/src/intern.rs index 54ea4e32071bc..4b688e8bb04a8 100644 --- a/crates/bevy_ecs/src/intern.rs +++ b/crates/bevy_ecs/src/intern.rs @@ -91,6 +91,10 @@ impl From<&Interned> for Interned { /// A trait for internable values. /// /// This is used by [`Interner`] to create static references for values that are interned. +#[diagnostic::on_unimplemented( + message = "`{Self}` can not be interned", + label = "invalid internable" +)] pub trait Internable: Hash + Eq { /// Creates a static reference to `self`, possibly leaking memory. fn leak(&self) -> &'static Self; diff --git a/crates/bevy_ecs/src/label.rs b/crates/bevy_ecs/src/label.rs index 7585913b75441..890af769015cc 100644 --- a/crates/bevy_ecs/src/label.rs +++ b/crates/bevy_ecs/src/label.rs @@ -7,6 +7,7 @@ use std::{ /// An object safe version of [`Eq`]. This trait is automatically implemented /// for any `'static` type that implements `Eq`. +#[diagnostic::on_unimplemented(message = "`{Self}` does not implement dynamic `Eq`")] pub trait DynEq: Any { /// Casts the type to `dyn Any`. fn as_any(&self) -> &dyn Any; @@ -36,6 +37,7 @@ where /// An object safe version of [`Hash`]. This trait is automatically implemented /// for any `'static` type that implements `Hash`. +#[diagnostic::on_unimplemented(message = "`{Self}` does not implement dynamic `Hash`")] pub trait DynHash: DynEq { /// Casts the type to `dyn Any`. fn as_dyn_eq(&self) -> &dyn DynEq; @@ -110,6 +112,10 @@ macro_rules! define_label { ) => { $(#[$label_attr])* + #[diagnostic::on_unimplemented( + message = "`{Self}` is not a matching label", + label = "invalid label", + )] pub trait $label_trait_name: 'static + Send + Sync + ::std::fmt::Debug { $($trait_extra_methods)* diff --git a/crates/bevy_ecs/src/query/fetch.rs b/crates/bevy_ecs/src/query/fetch.rs index 85204fb7db56f..c9dc833dda648 100644 --- a/crates/bevy_ecs/src/query/fetch.rs +++ b/crates/bevy_ecs/src/query/fetch.rs @@ -268,6 +268,10 @@ use std::{cell::UnsafeCell, marker::PhantomData}; /// /// [`Query`]: crate::system::Query /// [`ReadOnly`]: Self::ReadOnly +#[diagnostic::on_unimplemented( + message = "`{Self}` is not valid `Query` data", + label = "invalid query data" +)] pub unsafe trait QueryData: WorldQuery { /// The read-only variant of this [`QueryData`], which satisfies the [`ReadOnlyQueryData`] trait. type ReadOnly: ReadOnlyQueryData::State>; diff --git a/crates/bevy_ecs/src/query/filter.rs b/crates/bevy_ecs/src/query/filter.rs index 646d1d0a088a5..a78e21d81d701 100644 --- a/crates/bevy_ecs/src/query/filter.rs +++ b/crates/bevy_ecs/src/query/filter.rs @@ -70,7 +70,10 @@ use std::{cell::UnsafeCell, marker::PhantomData}; /// [`matches_component_set`]: Self::matches_component_set /// [`Query`]: crate::system::Query /// [`State`]: Self::State - +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a valid `Query` filter", + label = "invalid query filter" +)] pub trait QueryFilter: WorldQuery { /// Returns true if (and only if) this Filter relies strictly on archetypes to limit which /// components are accessed by the Query. @@ -938,6 +941,10 @@ impl QueryFilter for Changed { /// /// [`Added`] and [`Changed`] works with entities, and therefore are not archetypal. As such /// they do not implement [`ArchetypeFilter`]. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not an archetypical filter", + label = "invalid filter" +)] pub trait ArchetypeFilter: QueryFilter {} impl ArchetypeFilter for With {} diff --git a/crates/bevy_ecs/src/reflect/entity_commands.rs b/crates/bevy_ecs/src/reflect/entity_commands.rs index 8545b346bd15a..92ae503b3de5b 100644 --- a/crates/bevy_ecs/src/reflect/entity_commands.rs +++ b/crates/bevy_ecs/src/reflect/entity_commands.rs @@ -8,6 +8,7 @@ use std::borrow::Cow; use std::marker::PhantomData; /// An extension trait for [`EntityCommands`] for reflection related functions +#[diagnostic::on_unimplemented(message = "`{Self}` is not an App", label = "invalid `App`")] pub trait ReflectCommandExt { /// Adds the given boxed reflect component to the entity using the reflection data in /// [`AppTypeRegistry`]. diff --git a/crates/bevy_ecs/src/schedule/condition.rs b/crates/bevy_ecs/src/schedule/condition.rs index 7d2f1ab6173ea..ac063b826011e 100644 --- a/crates/bevy_ecs/src/schedule/condition.rs +++ b/crates/bevy_ecs/src/schedule/condition.rs @@ -70,6 +70,10 @@ pub type BoxedCondition = Box>; /// # world.insert_resource(DidRun(false)); /// # app.run(&mut world); /// # assert!(world.resource::().0); +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a run condition", + label = "invalid run condition" +)] pub trait Condition: sealed::Condition { /// Returns a new run condition that only returns `true` /// if both this one and the passed `and_then` return `true`. diff --git a/crates/bevy_ecs/src/schedule/config.rs b/crates/bevy_ecs/src/schedule/config.rs index 3204b59e65d22..2fc37eb2894c0 100644 --- a/crates/bevy_ecs/src/schedule/config.rs +++ b/crates/bevy_ecs/src/schedule/config.rs @@ -288,6 +288,10 @@ impl NodeConfigs { /// ) /// ); /// ``` +#[diagnostic::on_unimplemented( + message = "`{Self}` does not describe a valid system configuration", + label = "invalid system configuration" +)] pub trait IntoSystemConfigs where Self: Sized, @@ -562,6 +566,10 @@ impl SystemSetConfig { pub type SystemSetConfigs = NodeConfigs; /// Types that can convert into a [`SystemSetConfigs`]. +#[diagnostic::on_unimplemented( + message = "`{Self}` does not describe a valid system set configuration", + label = "invalid system set configuration" +)] pub trait IntoSystemSetConfigs where Self: Sized, diff --git a/crates/bevy_ecs/src/schedule/set.rs b/crates/bevy_ecs/src/schedule/set.rs index 7096d5c2e21a8..a39efdb41b584 100644 --- a/crates/bevy_ecs/src/schedule/set.rs +++ b/crates/bevy_ecs/src/schedule/set.rs @@ -149,6 +149,10 @@ impl SystemSet for AnonymousSet { } /// Types that can be converted into a [`SystemSet`]. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a system set", + label = "invalid system set" +)] pub trait IntoSystemSet: Sized { /// The type of [`SystemSet`] this instance converts into. type Set: SystemSet; diff --git a/crates/bevy_ecs/src/storage/sparse_set.rs b/crates/bevy_ecs/src/storage/sparse_set.rs index dffdb71db961e..10ae63dfe6788 100644 --- a/crates/bevy_ecs/src/storage/sparse_set.rs +++ b/crates/bevy_ecs/src/storage/sparse_set.rs @@ -528,6 +528,10 @@ impl SparseSet { /// Ideally, the `usize` values should be very small (ie: incremented starting from /// zero), as the number of bits needed to represent a `SparseSetIndex` in a `FixedBitSet` /// is proportional to the **value** of those `usize`. +#[diagnostic::on_unimplemented( + message = "`{Self}` can not be used as a sparse set index", + label = "invalid index" +)] pub trait SparseSetIndex: Clone + PartialEq + Eq + Hash { /// Gets the sparse set index corresponding to this instance. fn sparse_set_index(&self) -> usize; diff --git a/crates/bevy_ecs/src/system/adapter_system.rs b/crates/bevy_ecs/src/system/adapter_system.rs index c44e19c24d709..794db43936506 100644 --- a/crates/bevy_ecs/src/system/adapter_system.rs +++ b/crates/bevy_ecs/src/system/adapter_system.rs @@ -39,6 +39,10 @@ use crate::{schedule::InternedSystemSet, world::unsafe_world_cell::UnsafeWorldCe /// # system.initialize(&mut world); /// # assert!(system.run((), &mut world)); /// ``` +#[diagnostic::on_unimplemented( + message = "`{Self}` can not adapt a system of type `{S}`", + label = "invalid system adapter" +)] pub trait Adapt: Send + Sync + 'static { /// The [input](System::In) type for an [`AdapterSystem`]. type In; diff --git a/crates/bevy_ecs/src/system/combinator.rs b/crates/bevy_ecs/src/system/combinator.rs index 8184cf76226fb..006708d75d658 100644 --- a/crates/bevy_ecs/src/system/combinator.rs +++ b/crates/bevy_ecs/src/system/combinator.rs @@ -83,6 +83,10 @@ use super::{ReadOnlySystem, System}; /// # assert!(world.resource::().0); /// # world.resource_mut::().0 = false; /// ``` +#[diagnostic::on_unimplemented( + message = "`{Self}` can not combine systems `{A}` and `{B}`", + label = "invalid system combination" +)] pub trait Combine { /// The [input](System::In) type for a [`CombinatorSystem`]. type In; diff --git a/crates/bevy_ecs/src/system/commands/mod.rs b/crates/bevy_ecs/src/system/commands/mod.rs index 9d5e58802c317..3ba85a57e2dae 100644 --- a/crates/bevy_ecs/src/system/commands/mod.rs +++ b/crates/bevy_ecs/src/system/commands/mod.rs @@ -675,6 +675,10 @@ impl<'w, 's> Commands<'w, 's> { /// assert_eq!(names, HashSet::from_iter(["Entity #0", "Entity #1"])); /// } /// ``` +#[diagnostic::on_unimplemented( + message = "`{Self}` is not an entity command", + label = "invalid command" +)] pub trait EntityCommand: Send + 'static { /// Executes this command for the given [`Entity`]. fn apply(self, id: Entity, world: &mut World); diff --git a/crates/bevy_ecs/src/system/exclusive_function_system.rs b/crates/bevy_ecs/src/system/exclusive_function_system.rs index d4351923adaf4..85f3af12097e3 100644 --- a/crates/bevy_ecs/src/system/exclusive_function_system.rs +++ b/crates/bevy_ecs/src/system/exclusive_function_system.rs @@ -161,6 +161,10 @@ where /// /// This trait can be useful for making your own systems which accept other systems, /// sometimes called higher order systems. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not an exclusive system", + label = "invalid system" +)] pub trait ExclusiveSystemParamFunction: Send + Sync + 'static { /// The input type to this system. See [`System::In`]. type In; @@ -168,7 +172,7 @@ pub trait ExclusiveSystemParamFunction: Send + Sync + 'static { /// The return type of this system. See [`System::Out`]. type Out; - /// The [`ExclusiveSystemParam`]/s defined by this system's `fn` parameters. + /// The [`ExclusiveSystemParam`]'s defined by this system's `fn` parameters. type Param: ExclusiveSystemParam; /// Executes this system once. See [`System::run`]. diff --git a/crates/bevy_ecs/src/system/exclusive_system_param.rs b/crates/bevy_ecs/src/system/exclusive_system_param.rs index 3c356c98175cf..93ad2e603a247 100644 --- a/crates/bevy_ecs/src/system/exclusive_system_param.rs +++ b/crates/bevy_ecs/src/system/exclusive_system_param.rs @@ -10,6 +10,10 @@ use std::marker::PhantomData; /// A parameter that can be used in an exclusive system (a system with an `&mut World` parameter). /// Any parameters implementing this trait must come after the `&mut World` parameter. +#[diagnostic::on_unimplemented( + message = "`{Self}` can not be used as a parameter for an exclusive system", + label = "invalid system parameter" +)] pub trait ExclusiveSystemParam: Sized { /// Used to store data which persists across invocations of a system. type State: Send + Sync + 'static; diff --git a/crates/bevy_ecs/src/system/function_system.rs b/crates/bevy_ecs/src/system/function_system.rs index ac96075017bdb..4e5c1f938eba0 100644 --- a/crates/bevy_ecs/src/system/function_system.rs +++ b/crates/bevy_ecs/src/system/function_system.rs @@ -626,6 +626,7 @@ where /// ``` /// [`PipeSystem`]: crate::system::PipeSystem /// [`ParamSet`]: crate::system::ParamSet +#[diagnostic::on_unimplemented(message = "`{Self}` is not a system", label = "invalid system")] pub trait SystemParamFunction: Send + Sync + 'static { /// The input type to this system. See [`System::In`]. type In; diff --git a/crates/bevy_ecs/src/system/mod.rs b/crates/bevy_ecs/src/system/mod.rs index 19785a7243c75..a6b06061939a5 100644 --- a/crates/bevy_ecs/src/system/mod.rs +++ b/crates/bevy_ecs/src/system/mod.rs @@ -147,6 +147,11 @@ use crate::world::World; // This trait has to be generic because we have potentially overlapping impls, in particular // because Rust thinks a type could impl multiple different `FnMut` combinations // even though none can currently +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a valid system", + label = "invalid system", + note = "expecting a system which consumes `{In}` and produces `{Out}`" +)] pub trait IntoSystem: Sized { /// The type of [`System`] that this instance converts into. type System: System; diff --git a/crates/bevy_ecs/src/system/system.rs b/crates/bevy_ecs/src/system/system.rs index ec1b08707c70e..ada3fa5dfd748 100644 --- a/crates/bevy_ecs/src/system/system.rs +++ b/crates/bevy_ecs/src/system/system.rs @@ -22,6 +22,7 @@ use super::IntoSystem; /// Systems are executed in parallel, in opportunistic order; data access is managed automatically. /// It's possible to specify explicit execution order between specific systems, /// see [`IntoSystemConfigs`](crate::schedule::IntoSystemConfigs). +#[diagnostic::on_unimplemented(message = "`{Self}` is not a system", label = "invalid system")] pub trait System: Send + Sync + 'static { /// The system's input. See [`In`](crate::system::In) for /// [`FunctionSystem`](crate::system::FunctionSystem)s. @@ -270,6 +271,10 @@ impl Debug for dyn System { /// /// # assert_eq!(count, 2); /// ``` +#[diagnostic::on_unimplemented( + message = "`{Self}` can not run systems", + label = "invalid system runner" +)] pub trait RunSystemOnce: Sized { /// Runs a system and applies its deferred parameters. fn run_system_once, Out, Marker>(self, system: T) -> Out { diff --git a/crates/bevy_ecs/src/system/system_param.rs b/crates/bevy_ecs/src/system/system_param.rs index d85f50ae2529e..8f77715c46de7 100644 --- a/crates/bevy_ecs/src/system/system_param.rs +++ b/crates/bevy_ecs/src/system/system_param.rs @@ -432,6 +432,11 @@ impl_param_set!(); /// ``` /// /// [`Exclusive`]: https://doc.rust-lang.org/nightly/std/sync/struct.Exclusive.html +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a resource", + label = "invalid Resource", + note = "consider annotating `{Self}` with `#[derive(Resource)]`" +)] pub trait Resource: Send + Sync + 'static {} // SAFETY: Res only reads a single World resource @@ -783,6 +788,10 @@ unsafe impl<'a, T: FromWorld + Send + 'static> SystemParam for Local<'a, T> { /// Types that implement `SystemBuffer` should take care to perform as many /// computations up-front as possible. Buffers cannot be applied in parallel, /// so you should try to minimize the time spent in [`SystemBuffer::apply`]. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a deferrable system parameter", + label = "invalid system parameter" +)] pub trait SystemBuffer: FromWorld + Send + 'static { /// Applies any deferred mutations to the [`World`]. fn apply(&mut self, system_meta: &SystemMeta, world: &mut World); diff --git a/crates/bevy_ecs/src/world/mod.rs b/crates/bevy_ecs/src/world/mod.rs index ea52da782287b..d002b11a68e47 100644 --- a/crates/bevy_ecs/src/world/mod.rs +++ b/crates/bevy_ecs/src/world/mod.rs @@ -73,6 +73,7 @@ pub use identifier::WorldId; /// commands.add(AddToCounter(42)); /// } /// ``` +#[diagnostic::on_unimplemented(message = "`{Self}` is not a command", label = "invalid command")] pub trait Command: Send + 'static { /// Applies this command, causing it to mutate the provided `world`. /// @@ -2606,6 +2607,7 @@ unsafe impl Sync for World {} /// using data from the supplied [`World`]. /// /// This can be helpful for complex initialization or context-aware defaults. +#[diagnostic::on_unimplemented(message = "`{Self}` can not be created from a World")] pub trait FromWorld { /// Creates `Self` using data from the given [`World`]. fn from_world(world: &mut World) -> Self; diff --git a/crates/bevy_gizmos/src/config.rs b/crates/bevy_gizmos/src/config.rs index 92f6962c19384..81bffe4f34b64 100644 --- a/crates/bevy_gizmos/src/config.rs +++ b/crates/bevy_gizmos/src/config.rs @@ -46,6 +46,10 @@ pub enum GizmoLineStyle { /// Here you can store additional configuration for you gizmo group not covered by [`GizmoConfig`] /// /// Make sure to derive [`Default`] + [`Reflect`] and register in the app using `app.init_gizmo_group::()` +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a gizmo configuration group", + label = "invalid configuration group" +)] pub trait GizmoConfigGroup: Reflect + TypePath + Default {} /// The default gizmo config group. diff --git a/crates/bevy_gizmos/src/lib.rs b/crates/bevy_gizmos/src/lib.rs index d523f0dd5403f..d75a55c09872c 100644 --- a/crates/bevy_gizmos/src/lib.rs +++ b/crates/bevy_gizmos/src/lib.rs @@ -188,6 +188,7 @@ impl Plugin for GizmoPlugin { } /// A extension trait adding `App::init_gizmo_group` and `App::insert_gizmo_config`. +#[diagnostic::on_unimplemented(message = "`{Self}` is not an App", label = "invalid `App`")] pub trait AppGizmoBuilder { /// Registers [`GizmoConfigGroup`] in the app enabling the use of [Gizmos<Config>](crate::gizmos::Gizmos). /// diff --git a/crates/bevy_gizmos/src/primitives/dim2.rs b/crates/bevy_gizmos/src/primitives/dim2.rs index 74028903b1df9..4777281c618eb 100644 --- a/crates/bevy_gizmos/src/primitives/dim2.rs +++ b/crates/bevy_gizmos/src/primitives/dim2.rs @@ -20,6 +20,10 @@ const HALF_MIN_LINE_LEN: f32 = 25.0; const INFINITE_LEN: f32 = 100_000.0; /// A trait for rendering 2D geometric primitives (`P`) with [`Gizmos`]. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a primitive 2D gizmo", + label = "invalid gizmo" +)] pub trait GizmoPrimitive2d { /// The output of `primitive_2d`. This is a builder to set non-default values. type Output<'a> diff --git a/crates/bevy_gizmos/src/primitives/dim3.rs b/crates/bevy_gizmos/src/primitives/dim3.rs index 8af28f396a675..02e09e358a918 100644 --- a/crates/bevy_gizmos/src/primitives/dim3.rs +++ b/crates/bevy_gizmos/src/primitives/dim3.rs @@ -17,6 +17,10 @@ const DEFAULT_NUMBER_SEGMENTS: usize = 5; const INFINITE_LEN: f32 = 10_000.0; /// A trait for rendering 3D geometric primitives (`P`) with [`Gizmos`]. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a primitive 3D gizmo", + label = "invalid gizmo" +)] pub trait GizmoPrimitive3d { /// The output of `primitive_3d`. This is a builder to set non-default values. type Output<'a> diff --git a/crates/bevy_hierarchy/src/child_builder.rs b/crates/bevy_hierarchy/src/child_builder.rs index 6c32979666e63..acc64c4528289 100644 --- a/crates/bevy_hierarchy/src/child_builder.rs +++ b/crates/bevy_hierarchy/src/child_builder.rs @@ -309,6 +309,10 @@ impl ChildBuilder<'_> { } /// Trait for removing, adding and replacing children and parents of an entity. +#[diagnostic::on_unimplemented( + message = "`{Self}` can not build child entities", + label = "invalid builder" +)] pub trait BuildChildren { /// Takes a closure which builds children for this entity using [`ChildBuilder`]. fn with_children(&mut self, f: impl FnOnce(&mut ChildBuilder)) -> &mut Self; @@ -516,6 +520,10 @@ impl<'w> WorldChildBuilder<'w> { } /// Trait that defines adding, changing and children and parents of an entity directly through the [`World`]. +#[diagnostic::on_unimplemented( + message = "`{Self}` can not build child entities", + label = "invalid builder" +)] pub trait BuildWorldChildren { /// Takes a closure which builds children for this entity using [`WorldChildBuilder`]. fn with_children(&mut self, spawn_children: impl FnOnce(&mut WorldChildBuilder)) -> &mut Self; diff --git a/crates/bevy_hierarchy/src/hierarchy.rs b/crates/bevy_hierarchy/src/hierarchy.rs index 26f26233a0fe5..60462d94cae4f 100644 --- a/crates/bevy_hierarchy/src/hierarchy.rs +++ b/crates/bevy_hierarchy/src/hierarchy.rs @@ -81,6 +81,10 @@ impl Command for DespawnChildrenRecursive { } /// Trait that holds functions for despawning recursively down the transform hierarchy +#[diagnostic::on_unimplemented( + message = "`{Self}` can not despawn child entities", + label = "invalid despawner" +)] pub trait DespawnRecursiveExt { /// Despawns the provided entity alongside all descendants. fn despawn_recursive(self); diff --git a/crates/bevy_hierarchy/src/query_extension.rs b/crates/bevy_hierarchy/src/query_extension.rs index d78dee681c30d..3b3cbc1aa2ac8 100644 --- a/crates/bevy_hierarchy/src/query_extension.rs +++ b/crates/bevy_hierarchy/src/query_extension.rs @@ -9,6 +9,7 @@ use bevy_ecs::{ use crate::{Children, Parent}; /// An extension trait for [`Query`] that adds hierarchy related methods. +#[diagnostic::on_unimplemented(message = "`{Self}` is not a Query", label = "invalid query")] pub trait HierarchyQueryExt<'w, 's, D: QueryData, F: QueryFilter> { /// Returns an [`Iterator`] of [`Entity`]s over all of `entity`s descendants. /// diff --git a/crates/bevy_math/src/bounding/bounded2d/mod.rs b/crates/bevy_math/src/bounding/bounded2d/mod.rs index b97da70e3d17a..d32364df75177 100644 --- a/crates/bevy_math/src/bounding/bounded2d/mod.rs +++ b/crates/bevy_math/src/bounding/bounded2d/mod.rs @@ -16,6 +16,7 @@ fn point_cloud_2d_center(points: &[Vec2]) -> Vec2 { } /// A trait with methods that return 2D bounded volumes for a shape +#[diagnostic::on_unimplemented(message = "`{Self}` is not bounded in 2D")] pub trait Bounded2d { /// Get an axis-aligned bounding box for the shape with the given translation and rotation. /// The rotation is in radians, counterclockwise, with 0 meaning no rotation. diff --git a/crates/bevy_math/src/bounding/bounded3d/mod.rs b/crates/bevy_math/src/bounding/bounded3d/mod.rs index 4c4ad16749e3d..7fcc4c414a2f4 100644 --- a/crates/bevy_math/src/bounding/bounded3d/mod.rs +++ b/crates/bevy_math/src/bounding/bounded3d/mod.rs @@ -20,6 +20,7 @@ fn point_cloud_3d_center(points: impl Iterator>) -> Vec3 } /// A trait with methods that return 3D bounded volumes for a shape +#[diagnostic::on_unimplemented(message = "`{Self}` is not bounded in 3D")] pub trait Bounded3d { /// Get an axis-aligned bounding box for the shape with the given translation and rotation fn aabb_3d(&self, translation: Vec3, rotation: Quat) -> Aabb3d; diff --git a/crates/bevy_math/src/bounding/mod.rs b/crates/bevy_math/src/bounding/mod.rs index 6de162d7291b7..c96d301283fd7 100644 --- a/crates/bevy_math/src/bounding/mod.rs +++ b/crates/bevy_math/src/bounding/mod.rs @@ -10,6 +10,10 @@ /// overlapping elements or finding intersections. /// /// This trait supports both 2D and 3D bounding shapes. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a bounding volume", + label = "invalid volume" +)] pub trait BoundingVolume: Sized { /// The position type used for the volume. This should be `Vec2` for 2D and `Vec3` for 3D. type Translation: Clone + Copy + PartialEq; @@ -101,6 +105,10 @@ pub trait BoundingVolume: Sized { /// - Raycasting /// - Testing for overlap /// - Checking if an object is within the view frustum of a camera +#[diagnostic::on_unimplemented( + message = "`{Self}` can not test for volume intersections", + label = "invalid volume" +)] pub trait IntersectsVolume { /// Check if a volume intersects with this intersection test fn intersects(&self, volume: &Volume) -> bool; diff --git a/crates/bevy_math/src/common_traits.rs b/crates/bevy_math/src/common_traits.rs index 6074f2526607d..a2bf190646c3e 100644 --- a/crates/bevy_math/src/common_traits.rs +++ b/crates/bevy_math/src/common_traits.rs @@ -21,6 +21,10 @@ use std::ops::{Add, Div, Mul, Neg, Sub}; /// /// Note that, because implementing types use floating point arithmetic, they are not required to actually /// implement `PartialEq` or `Eq`. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a vector space", + label = "invalid vector space" +)] pub trait VectorSpace: Mul + Div @@ -77,6 +81,10 @@ impl VectorSpace for f32 { /// /// Note that, because implementing types use floating point arithmetic, they are not required to actually /// implement `PartialEq` or `Eq`. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a normed vector space", + label = "invalid vector space" +)] pub trait NormedVectorSpace: VectorSpace { /// The size of this element. The return value should always be nonnegative. fn norm(self) -> f32; diff --git a/crates/bevy_math/src/cubic_splines.rs b/crates/bevy_math/src/cubic_splines.rs index a3343e55b65bb..5eb2dfe68550a 100644 --- a/crates/bevy_math/src/cubic_splines.rs +++ b/crates/bevy_math/src/cubic_splines.rs @@ -621,6 +621,10 @@ impl CubicGenerator

for LinearSpline

{ } /// Implement this on cubic splines that can generate a cubic curve from their spline parameters. +#[diagnostic::on_unimplemented( + message = "`{Self}` can not generate a cubic curve", + label = "invalid generator" +)] pub trait CubicGenerator { /// Build a [`CubicCurve`] by computing the interpolation coefficients for each curve segment. fn to_curve(&self) -> CubicCurve

; @@ -911,6 +915,10 @@ impl IntoIterator for CubicCurve

{ } /// Implement this on cubic splines that can generate a rational cubic curve from their spline parameters. +#[diagnostic::on_unimplemented( + message = "`{Self}` can not generate a rational curve", + label = "invalid generator" +)] pub trait RationalGenerator { /// Build a [`RationalCurve`] by computing the interpolation coefficients for each curve segment. fn to_curve(&self) -> RationalCurve

; diff --git a/crates/bevy_math/src/primitives/mod.rs b/crates/bevy_math/src/primitives/mod.rs index 460e635867ecb..d7b5a670647c9 100644 --- a/crates/bevy_math/src/primitives/mod.rs +++ b/crates/bevy_math/src/primitives/mod.rs @@ -10,9 +10,17 @@ pub use dim3::*; mod serde; /// A marker trait for 2D primitives +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a 2D primitive shape", + label = "invalid primitive" +)] pub trait Primitive2d {} /// A marker trait for 3D primitives +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a 3D primitive shape", + label = "invalid primitive" +)] pub trait Primitive3d {} /// The winding order for a set of points @@ -31,6 +39,10 @@ pub enum WindingOrder { } /// A trait for getting measurements of 2D shapes +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a measurable 2D shape", + label = "invalid shape" +)] pub trait Measured2d { /// Get the perimeter of the shape fn perimeter(&self) -> f32; @@ -40,6 +52,10 @@ pub trait Measured2d { } /// A trait for getting measurements of 3D shapes +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a measurable 3D shape", + label = "invalid shape" +)] pub trait Measured3d { /// Get the surface area of the shape fn area(&self) -> f32; diff --git a/crates/bevy_math/src/sampling/shape_sampling.rs b/crates/bevy_math/src/sampling/shape_sampling.rs index 3728034413bef..7c147a756f2d2 100644 --- a/crates/bevy_math/src/sampling/shape_sampling.rs +++ b/crates/bevy_math/src/sampling/shape_sampling.rs @@ -7,6 +7,7 @@ use rand::{ }; /// Exposes methods to uniformly sample a variety of primitive shapes. +#[diagnostic::on_unimplemented(message = "`{Self}` can not be sampled", label = "invalid shape")] pub trait ShapeSample { /// The type of vector returned by the sample methods, [`Vec2`] for 2D shapes and [`Vec3`] for 3D shapes. type Output; diff --git a/crates/bevy_math/src/sampling/standard.rs b/crates/bevy_math/src/sampling/standard.rs index 255d9a07c2d0a..7e1557b8d5e95 100644 --- a/crates/bevy_math/src/sampling/standard.rs +++ b/crates/bevy_math/src/sampling/standard.rs @@ -40,6 +40,9 @@ use rand::{ /// let mut rng = StdRng::from_entropy(); /// let random_dir = Dir3::from_rng(&mut rng); /// ``` +#[diagnostic::on_unimplemented( + message = "`{Self}` can not be generated from a random distribution" +)] pub trait FromRng where Self: Sized, diff --git a/crates/bevy_pbr/src/extended_material.rs b/crates/bevy_pbr/src/extended_material.rs index aa77b51c625ab..b8dc55b3609e1 100644 --- a/crates/bevy_pbr/src/extended_material.rs +++ b/crates/bevy_pbr/src/extended_material.rs @@ -27,6 +27,10 @@ pub struct MaterialExtensionKey { /// A subset of the `Material` trait for defining extensions to a base `Material`, such as the builtin `StandardMaterial`. /// A user type implementing the trait should be used as the `E` generic param in an `ExtendedMaterial` struct. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a valid material", + label = "invalid material" +)] pub trait MaterialExtension: Asset + AsBindGroup + Clone + Sized { /// Returns this material's vertex shader. If [`ShaderRef::Default`] is returned, the base material mesh vertex shader /// will be used. diff --git a/crates/bevy_pbr/src/light_probe/mod.rs b/crates/bevy_pbr/src/light_probe/mod.rs index 964ffbc7c2a46..0fece70102cbd 100644 --- a/crates/bevy_pbr/src/light_probe/mod.rs +++ b/crates/bevy_pbr/src/light_probe/mod.rs @@ -250,6 +250,10 @@ where /// Most light probe systems are written to be generic over the type of light /// probe. This allows much of the code to be shared and enables easy addition /// of more light probe types (e.g. real-time reflection planes) in the future. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a light probe", + label = "invalid light probe" +)] pub trait LightProbeComponent: Send + Sync + Component + Sized { /// Holds [`AssetId`]s of the texture or textures that this light probe /// references. diff --git a/crates/bevy_pbr/src/material.rs b/crates/bevy_pbr/src/material.rs index ede7b1672a9a0..4e27dc7122827 100644 --- a/crates/bevy_pbr/src/material.rs +++ b/crates/bevy_pbr/src/material.rs @@ -99,6 +99,10 @@ use self::{irradiance_volume::IrradianceVolume, prelude::EnvironmentMapLight}; /// @group(2) @binding(1) var color_texture: texture_2d; /// @group(2) @binding(2) var color_sampler: sampler; /// ``` +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a valid material", + label = "invalid material" +)] pub trait Material: Asset + AsBindGroup + Clone + Sized { /// Returns this material's vertex shader. If [`ShaderRef::Default`] is returned, the default mesh vertex shader /// will be used. diff --git a/crates/bevy_pbr/src/meshlet/persistent_buffer.rs b/crates/bevy_pbr/src/meshlet/persistent_buffer.rs index 60e163a87446a..602044db5d972 100644 --- a/crates/bevy_pbr/src/meshlet/persistent_buffer.rs +++ b/crates/bevy_pbr/src/meshlet/persistent_buffer.rs @@ -109,6 +109,10 @@ impl PersistentGpuBuffer { } /// A trait representing data that can be written to a [`PersistentGpuBuffer`]. +#[diagnostic::on_unimplemented( + message = "`{Self}` can not be written to a persistent GPU buffer", + label = "invalid bufferable" +)] pub trait PersistentGpuBufferable { /// Additional metadata associated with each item, made available during `write_bytes_le`. type Metadata; diff --git a/crates/bevy_ptr/src/lib.rs b/crates/bevy_ptr/src/lib.rs index de12026377ab6..f97a82bf8c976 100644 --- a/crates/bevy_ptr/src/lib.rs +++ b/crates/bevy_ptr/src/lib.rs @@ -22,6 +22,10 @@ pub struct Unaligned; /// Trait that is only implemented for [`Aligned`] and [`Unaligned`] to work around the lack of ability /// to have const generics of an enum. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not an alignment option", + label = "invalid alignment" +)] pub trait IsAligned: sealed::Sealed {} impl IsAligned for Aligned {} impl IsAligned for Unaligned {} @@ -544,6 +548,10 @@ mod private { } /// Extension trait for helper methods on [`UnsafeCell`] +#[diagnostic::on_unimplemented( + message = "`{Self}` is not an UnsafeCell", + label = "invalid `UnsafeCell`" +)] pub trait UnsafeCellDeref<'a, T>: private::SealedUnsafeCell { /// # Safety /// - The returned value must be unique and not alias any mutable or immutable references to the contents of the [`UnsafeCell`]. diff --git a/crates/bevy_reflect/compile_fail/tests/reflect_derive/generics_fail.rs b/crates/bevy_reflect/compile_fail/tests/reflect_derive/generics_fail.rs index ad7426299aa12..ba463bf4dd322 100644 --- a/crates/bevy_reflect/compile_fail/tests/reflect_derive/generics_fail.rs +++ b/crates/bevy_reflect/compile_fail/tests/reflect_derive/generics_fail.rs @@ -12,9 +12,9 @@ struct NoReflect(f32); fn main() { let mut foo: Box = Box::new(Foo:: { a: NoReflect(42.0) }); - //~^ ERROR: not satisfied + //~^ ERROR: `NoReflect` does not provide type registration information // foo doesn't implement Reflect because NoReflect doesn't implement Reflect foo.get_field::("a").unwrap(); - //~^ ERROR: not satisfied + //~^ ERROR: `NoReflect` can not be reflected } diff --git a/crates/bevy_reflect/compile_fail/tests/reflect_derive/generics_fail.stderr b/crates/bevy_reflect/compile_fail/tests/reflect_derive/generics_fail.stderr index c61aacaf72722..8c4890827de6c 100644 --- a/crates/bevy_reflect/compile_fail/tests/reflect_derive/generics_fail.stderr +++ b/crates/bevy_reflect/compile_fail/tests/reflect_derive/generics_fail.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `NoReflect: Reflect` is not satisfied +error[E0277]: `NoReflect` can not be reflected --> tests/reflect_derive/generics_fail.rs:18:21 | 18 | foo.get_field::("a").unwrap(); @@ -6,6 +6,7 @@ error[E0277]: the trait bound `NoReflect: Reflect` is not satisfied | | | required by a bound introduced by this call | + = note: Try using `#[derive(Reflect)]` = help: the following other types implement trait `Reflect`: bool char @@ -17,17 +18,19 @@ error[E0277]: the trait bound `NoReflect: Reflect` is not satisfied i128 and 74 others note: required by a bound in `bevy_reflect::GetField::get_field` - --> $BEVY_ROOT/crates/bevy_reflect/src/struct_trait.rs:242:21 + --> $BEVY_ROOT/crates/bevy_reflect/src/struct_trait.rs:244:21 | -242 | fn get_field(&self, name: &str) -> Option<&T>; +244 | fn get_field(&self, name: &str) -> Option<&T>; | ^^^^^^^ required by this bound in `GetField::get_field` -error[E0277]: the trait bound `NoReflect: GetTypeRegistration` is not satisfied +error[E0277]: `NoReflect` does not provide type registration information --> tests/reflect_derive/generics_fail.rs:14:36 | 14 | let mut foo: Box = Box::new(Foo:: { a: NoReflect(42.0) }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `GetTypeRegistration` is not implemented for `NoReflect`, which is required by `Foo: bevy_reflect::Struct` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid Type | + = help: the trait `GetTypeRegistration` is not implemented for `NoReflect`, which is required by `Foo: bevy_reflect::Struct` + = note: Try using `#[derive(Reflect)]` = help: the following other types implement trait `GetTypeRegistration`: bool char diff --git a/crates/bevy_reflect/src/array.rs b/crates/bevy_reflect/src/array.rs index f5f1158c20f11..e6107680c5810 100644 --- a/crates/bevy_reflect/src/array.rs +++ b/crates/bevy_reflect/src/array.rs @@ -44,6 +44,7 @@ use std::{ /// [`GetTypeRegistration`]: crate::GetTypeRegistration /// [limitation]: https://github.com/serde-rs/serde/issues/1937 /// [`Deserialize`]: ::serde::Deserialize +#[diagnostic::on_unimplemented(message = "`{Self}` is not an array", label = "invalid array")] pub trait Array: Reflect { /// Returns a reference to the element at `index`, or `None` if out of bounds. fn get(&self, index: usize) -> Option<&dyn Reflect>; diff --git a/crates/bevy_reflect/src/enums/enum_trait.rs b/crates/bevy_reflect/src/enums/enum_trait.rs index 66029923da25b..5cedcd773bc1e 100644 --- a/crates/bevy_reflect/src/enums/enum_trait.rs +++ b/crates/bevy_reflect/src/enums/enum_trait.rs @@ -87,6 +87,7 @@ use std::slice::Iter; /// [`None`]: Option::None /// [`Some`]: Option::Some /// [`Reflect`]: bevy_reflect_derive::Reflect +#[diagnostic::on_unimplemented(message = "`{Self}` is not an enum", label = "invalid enum")] pub trait Enum: Reflect { /// Returns a reference to the value of the field (in the current variant) with the given name. /// diff --git a/crates/bevy_reflect/src/from_reflect.rs b/crates/bevy_reflect/src/from_reflect.rs index 85de6c6bffd12..3d2ff662e408a 100644 --- a/crates/bevy_reflect/src/from_reflect.rs +++ b/crates/bevy_reflect/src/from_reflect.rs @@ -21,6 +21,7 @@ use crate::{FromType, Reflect}; /// [derive macro]: bevy_reflect_derive::FromReflect /// [`DynamicStruct`]: crate::DynamicStruct /// [crate-level documentation]: crate +#[diagnostic::on_unimplemented(message = "`{Self}` can not be created from a reflection")] pub trait FromReflect: Reflect + Sized { /// Constructs a concrete instance of `Self` from a reflected value. fn from_reflect(reflect: &dyn Reflect) -> Option; diff --git a/crates/bevy_reflect/src/list.rs b/crates/bevy_reflect/src/list.rs index 5b786ee76a991..b5211a109b25f 100644 --- a/crates/bevy_reflect/src/list.rs +++ b/crates/bevy_reflect/src/list.rs @@ -47,6 +47,7 @@ use crate::{ /// [list-like]: https://doc.rust-lang.org/book/ch08-01-vectors.html /// [reflection]: crate /// [type-erasing]: https://doc.rust-lang.org/book/ch17-02-trait-objects.html +#[diagnostic::on_unimplemented(message = "`{Self}` is not a list", label = "invalid list")] pub trait List: Reflect { /// Returns a reference to the element at `index`, or `None` if out of bounds. fn get(&self, index: usize) -> Option<&dyn Reflect>; diff --git a/crates/bevy_reflect/src/map.rs b/crates/bevy_reflect/src/map.rs index 5b182c68a973a..432ce351925de 100644 --- a/crates/bevy_reflect/src/map.rs +++ b/crates/bevy_reflect/src/map.rs @@ -40,6 +40,7 @@ use crate::{ /// /// [map-like]: https://doc.rust-lang.org/book/ch08-03-hash-maps.html /// [reflection]: crate +#[diagnostic::on_unimplemented(message = "`{Self}` is not a map", label = "invalid map")] pub trait Map: Reflect { /// Returns a reference to the value associated with the given key. /// diff --git a/crates/bevy_reflect/src/path/mod.rs b/crates/bevy_reflect/src/path/mod.rs index fdf1c5d9d5e07..2a002f8b54ece 100644 --- a/crates/bevy_reflect/src/path/mod.rs +++ b/crates/bevy_reflect/src/path/mod.rs @@ -44,6 +44,10 @@ impl<'a> From> for ReflectPathError<'a> { } /// Something that can be interpreted as a reflection path in [`GetPath`]. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a reflection path", + label = "invalid path" +)] pub trait ReflectPath<'a>: Sized { /// Gets a reference to the specified element on the given [`Reflect`] object. /// @@ -230,6 +234,11 @@ impl<'a> ReflectPath<'a> for &'a str { /// [`List`]: crate::List /// [`Array`]: crate::Array /// [`Enum`]: crate::Enum +#[diagnostic::on_unimplemented( + message = "`{Self}` does not provide a reflection path", + label = "invalid type", + note = "consider annotating `{Self}` with `#[derive(Reflect)]`" +)] pub trait GetPath: Reflect { /// Returns a reference to the value specified by `path`. /// diff --git a/crates/bevy_reflect/src/reflect.rs b/crates/bevy_reflect/src/reflect.rs index 43108e61a4278..8238048d0a5b0 100644 --- a/crates/bevy_reflect/src/reflect.rs +++ b/crates/bevy_reflect/src/reflect.rs @@ -179,6 +179,10 @@ impl std::fmt::Display for ReflectKind { /// [`bevy_reflect`]: crate /// [derive macro]: bevy_reflect_derive::Reflect /// [crate-level documentation]: crate +#[diagnostic::on_unimplemented( + message = "`{Self}` can not be reflected", + note = "consider annotating `{Self}` with `#[derive(Reflect)]`" +)] pub trait Reflect: DynamicTypePath + Any + Send + Sync { /// Returns the [`TypeInfo`] of the type _represented_ by this value. /// diff --git a/crates/bevy_reflect/src/struct_trait.rs b/crates/bevy_reflect/src/struct_trait.rs index 5d134034691d6..408536e47ca51 100644 --- a/crates/bevy_reflect/src/struct_trait.rs +++ b/crates/bevy_reflect/src/struct_trait.rs @@ -43,6 +43,7 @@ use std::{ /// [reflection]: crate /// [unit structs]: https://doc.rust-lang.org/book/ch05-01-defining-structs.html#unit-like-structs-without-any-fields +#[diagnostic::on_unimplemented(message = "`{Self}` is not a struct", label = "invalid struct")] pub trait Struct: Reflect { /// Returns a reference to the value of the field named `name` as a `&dyn /// Reflect`. @@ -236,6 +237,7 @@ impl<'a> ExactSizeIterator for FieldIter<'a> {} /// assert_eq!(foo.get_field::("bar"), Some(&"Hello".to_string())); /// # } /// ``` +#[diagnostic::on_unimplemented(message = "`{Self}` is not a struct", label = "invalid struct")] pub trait GetField { /// Returns a reference to the value of the field named `name`, downcast to /// `T`. diff --git a/crates/bevy_reflect/src/tuple.rs b/crates/bevy_reflect/src/tuple.rs index cf111edcdfb99..b044458deb17d 100644 --- a/crates/bevy_reflect/src/tuple.rs +++ b/crates/bevy_reflect/src/tuple.rs @@ -33,6 +33,7 @@ use std::slice::Iter; /// /// [tuple-like]: https://doc.rust-lang.org/book/ch03-02-data-types.html#the-tuple-type /// [reflection]: crate +#[diagnostic::on_unimplemented(message = "`{Self}` is not a tuple", label = "invalid tuple")] pub trait Tuple: Reflect { /// Returns a reference to the value of the field with index `index` as a /// `&dyn Reflect`. @@ -102,6 +103,7 @@ impl<'a> ExactSizeIterator for TupleFieldIter<'a> {} /// assert_eq!(foo.get_field::(1), Some(&42)); /// # } /// ``` +#[diagnostic::on_unimplemented(message = "`{Self}` is not a tuple", label = "invalid tuple")] pub trait GetTupleField { /// Returns a reference to the value of the field with index `index`, /// downcast to `T`. diff --git a/crates/bevy_reflect/src/tuple_struct.rs b/crates/bevy_reflect/src/tuple_struct.rs index 8aeb103984029..2185fa01b5f15 100644 --- a/crates/bevy_reflect/src/tuple_struct.rs +++ b/crates/bevy_reflect/src/tuple_struct.rs @@ -34,6 +34,10 @@ use std::slice::Iter; /// /// [tuple struct-like]: https://doc.rust-lang.org/book/ch05-01-defining-structs.html#using-tuple-structs-without-named-fields-to-create-different-types /// [reflection]: crate +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a tuple struct", + label = "invalid tuple struct" +)] pub trait TupleStruct: Reflect { /// Returns a reference to the value of the field with index `index` as a /// `&dyn Reflect`. @@ -185,6 +189,10 @@ impl<'a> ExactSizeIterator for TupleStructFieldIter<'a> {} /// assert_eq!(foo.get_field::(0), Some(&"Hello".to_string())); /// # } /// ``` +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a tuple struct", + label = "invalid tuple struct" +)] pub trait GetTupleStructField { /// Returns a reference to the value of the field with index `index`, /// downcast to `T`. diff --git a/crates/bevy_reflect/src/type_info.rs b/crates/bevy_reflect/src/type_info.rs index c64131a7b825f..82e2b89132074 100644 --- a/crates/bevy_reflect/src/type_info.rs +++ b/crates/bevy_reflect/src/type_info.rs @@ -70,6 +70,7 @@ use std::fmt::Debug; /// ``` /// /// [utility]: crate::utility +#[diagnostic::on_unimplemented(message = "`{Self}` can not be typed through reflection")] pub trait Typed: Reflect + TypePath { /// Returns the compile-time [info] for the underlying type. /// diff --git a/crates/bevy_reflect/src/type_path.rs b/crates/bevy_reflect/src/type_path.rs index d6e6a4ad44ef4..b7bd8f0c292e9 100644 --- a/crates/bevy_reflect/src/type_path.rs +++ b/crates/bevy_reflect/src/type_path.rs @@ -79,6 +79,11 @@ use std::fmt; /// [`crate_name`]: TypePath::crate_name /// [`module_path`]: TypePath::module_path /// [`type_ident`]: TypePath::type_ident +#[diagnostic::on_unimplemented( + message = "`{Self}` does not have a type path", + label = "invalid type", + note = "consider annotating `{Self}` with `#[derive(TypePath)]`" +)] pub trait TypePath: 'static { /// Returns the fully qualified path of the underlying type. /// @@ -129,6 +134,10 @@ pub trait TypePath: 'static { /// Since this is a supertrait of [`Reflect`] its methods can be called on a `dyn Reflect`. /// /// [`Reflect`]: crate::Reflect +#[diagnostic::on_unimplemented( + message = "`{Self}` can not be used as a dynamic type path", + label = "invalid type" +)] pub trait DynamicTypePath { /// See [`TypePath::type_path`]. fn reflect_type_path(&self) -> &str; diff --git a/crates/bevy_reflect/src/type_registry.rs b/crates/bevy_reflect/src/type_registry.rs index 6940a14542bde..5ebcd7efb45a5 100644 --- a/crates/bevy_reflect/src/type_registry.rs +++ b/crates/bevy_reflect/src/type_registry.rs @@ -56,6 +56,11 @@ impl Debug for TypeRegistryArc { /// See the [crate-level documentation] for more information on type registration. /// /// [crate-level documentation]: crate +#[diagnostic::on_unimplemented( + message = "`{Self}` does not provide type registration information", + label = "invalid type", + note = "consider annotating `{Self}` with `#[derive(Reflect)]`" +)] pub trait GetTypeRegistration: 'static { /// Returns the default [`TypeRegistration`] for this type. fn get_type_registration() -> TypeRegistration; diff --git a/crates/bevy_render/src/camera/projection.rs b/crates/bevy_render/src/camera/projection.rs index c8495ffbf39d1..3d0268e3a3a8c 100644 --- a/crates/bevy_render/src/camera/projection.rs +++ b/crates/bevy_render/src/camera/projection.rs @@ -74,6 +74,7 @@ pub struct CameraUpdateSystem; /// systems for your [`CameraProjection`] implementation. /// /// [`Camera`]: crate::camera::Camera +#[diagnostic::on_unimplemented(message = "`{Self}` is not a camera", label = "invalid camera")] pub trait CameraProjection { fn get_projection_matrix(&self) -> Mat4; fn update(&mut self, width: f32, height: f32); diff --git a/crates/bevy_render/src/extract_component.rs b/crates/bevy_render/src/extract_component.rs index 4b327cf6af3e8..9e7c668e15705 100644 --- a/crates/bevy_render/src/extract_component.rs +++ b/crates/bevy_render/src/extract_component.rs @@ -34,6 +34,10 @@ impl DynamicUniformIndex { /// /// Therefore the component is transferred from the "app world" into the "render world" /// in the [`ExtractSchedule`] step. +#[diagnostic::on_unimplemented( + message = "`{Self}` can not be extracted for rendering", + label = "invalid component" +)] pub trait ExtractComponent: Component { /// ECS [`ReadOnlyQueryData`] to fetch the components to extract. type QueryData: ReadOnlyQueryData; diff --git a/crates/bevy_render/src/extract_instances.rs b/crates/bevy_render/src/extract_instances.rs index 537ca5f11e439..b3b59ca1788c4 100644 --- a/crates/bevy_render/src/extract_instances.rs +++ b/crates/bevy_render/src/extract_instances.rs @@ -27,6 +27,10 @@ use crate::{prelude::ViewVisibility, Extract, ExtractSchedule, RenderApp}; /// This is essentially the same as /// [`ExtractComponent`](crate::extract_component::ExtractComponent), but /// higher-performance because it avoids the ECS overhead. +#[diagnostic::on_unimplemented( + message = "`{Self}` can not be extracted for rendering", + label = "invalid target" +)] pub trait ExtractInstance: Send + Sync + Sized + 'static { /// ECS [`ReadOnlyQueryData`] to fetch the components to extract. type QueryData: ReadOnlyQueryData; diff --git a/crates/bevy_render/src/extract_resource.rs b/crates/bevy_render/src/extract_resource.rs index 63a6c42dc4a20..dd75c4c961ffc 100644 --- a/crates/bevy_render/src/extract_resource.rs +++ b/crates/bevy_render/src/extract_resource.rs @@ -10,6 +10,10 @@ use crate::{Extract, ExtractSchedule, RenderApp}; /// /// Therefore the resource is transferred from the "main world" into the "render world" /// in the [`ExtractSchedule`] step. +#[diagnostic::on_unimplemented( + message = "`{Self}` can not be extracted for rendering", + label = "invalid resource" +)] pub trait ExtractResource: Resource { type Source: Resource; diff --git a/crates/bevy_render/src/mesh/primitives/mod.rs b/crates/bevy_render/src/mesh/primitives/mod.rs index a2bb01599b4ee..8632dcff72754 100644 --- a/crates/bevy_render/src/mesh/primitives/mod.rs +++ b/crates/bevy_render/src/mesh/primitives/mod.rs @@ -26,6 +26,10 @@ mod dim3; pub use dim3::*; /// A trait for shapes that can be turned into a [`Mesh`](super::Mesh). +#[diagnostic::on_unimplemented( + message = "`{Self}` can not be turned into a mesh", + label = "invalid meshable" +)] pub trait Meshable { /// The output of [`Self::mesh`]. This can either be a [`Mesh`](super::Mesh) /// or a builder used for creating a [`Mesh`](super::Mesh). diff --git a/crates/bevy_render/src/render_asset.rs b/crates/bevy_render/src/render_asset.rs index e3a6aab5fb637..9be674de343cd 100644 --- a/crates/bevy_render/src/render_asset.rs +++ b/crates/bevy_render/src/render_asset.rs @@ -27,6 +27,10 @@ pub enum PrepareAssetError { /// /// After that in the [`RenderSet::PrepareAssets`] step the extracted asset /// is transformed into its GPU-representation of type [`RenderAsset`]. +#[diagnostic::on_unimplemented( + message = "`{Self}` can not be extracted for rendering", + label = "invalid asset" +)] pub trait RenderAsset: Send + Sync + 'static + Sized { /// The representation of the asset in the "main world". type SourceAsset: Asset + Clone; diff --git a/crates/bevy_render/src/render_graph/app.rs b/crates/bevy_render/src/render_graph/app.rs index 80ffcdb2a1f8d..5e5961c046e1b 100644 --- a/crates/bevy_render/src/render_graph/app.rs +++ b/crates/bevy_render/src/render_graph/app.rs @@ -5,6 +5,7 @@ use bevy_utils::tracing::warn; use super::{IntoRenderNodeArray, Node, RenderGraph, RenderLabel, RenderSubGraph}; /// Adds common [`RenderGraph`] operations to [`SubApp`] (and [`App`]). +#[diagnostic::on_unimplemented(message = "`{Self}` is not an App", label = "invalid `App`")] pub trait RenderGraphApp { // Add a sub graph to the [`RenderGraph`] fn add_render_sub_graph(&mut self, sub_graph: impl RenderSubGraph) -> &mut Self; diff --git a/crates/bevy_render/src/render_graph/node.rs b/crates/bevy_render/src/render_graph/node.rs index 0558f7c078164..2108a20c6034e 100644 --- a/crates/bevy_render/src/render_graph/node.rs +++ b/crates/bevy_render/src/render_graph/node.rs @@ -60,6 +60,10 @@ all_tuples_with_size!(impl_render_label_tuples, 1, 32, T, l); /// A node can produce outputs used as dependencies by other nodes. /// Those inputs and outputs are called slots and are the default way of passing render data /// inside the graph. For more information see [`SlotType`](super::SlotType). +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a render graph node", + label = "invalid node" +)] pub trait Node: Downcast + Send + Sync + 'static { /// Specifies the required input slots for this node. /// They will then be available during the run method inside the [`RenderGraphContext`]. @@ -336,7 +340,11 @@ impl Node for RunGraphOnViewNode { /// This trait should be used instead of the [`Node`] trait when making a render node that runs on a view. /// -/// It is intended to be used with [`ViewNodeRunner`] +/// It is intended to be used with [`ViewNodeRunner`]' +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a render graph view node", + label = "invalid node" +)] pub trait ViewNode { /// The query that will be used on the view entity. /// It is guaranteed to run on the view entity, so there's no need for a filter diff --git a/crates/bevy_render/src/render_phase/draw.rs b/crates/bevy_render/src/render_phase/draw.rs index 980899b64bc44..b6a028d9d4f50 100644 --- a/crates/bevy_render/src/render_phase/draw.rs +++ b/crates/bevy_render/src/render_phase/draw.rs @@ -20,6 +20,10 @@ use std::{ /// /// This trait can either be implemented directly or implicitly composed out of multiple modular /// [`RenderCommand`]s. For more details and an example see the [`RenderCommand`] documentation. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a valid draw operation", + label = "invalid draw" +)] pub trait Draw: Send + Sync + 'static { /// Prepares the draw function to be used. This is called once and only once before the phase /// begins. There may be zero or more [`draw`](Draw::draw) calls following a call to this function. @@ -167,6 +171,10 @@ impl DrawFunctions

{ /// DrawMesh, /// ); /// ``` +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a render command", + label = "invalid command" +)] pub trait RenderCommand { /// Specifies the general ECS data (e.g. resources) required by [`RenderCommand::render`]. /// @@ -301,6 +309,7 @@ where /// Registers a [`RenderCommand`] as a [`Draw`] function. /// They are stored inside the [`DrawFunctions`] resource of the app. +#[diagnostic::on_unimplemented(message = "`{Self}` is not an App", label = "invalid `App`")] pub trait AddRenderCommand { /// Adds the [`RenderCommand`] for the specified render phase to the app. fn add_render_command + Send + Sync + 'static>( diff --git a/crates/bevy_render/src/render_phase/mod.rs b/crates/bevy_render/src/render_phase/mod.rs index a1125fa938e2c..174048bcb9d91 100644 --- a/crates/bevy_render/src/render_phase/mod.rs +++ b/crates/bevy_render/src/render_phase/mod.rs @@ -642,6 +642,7 @@ where /// and then sorted all at once. This is needed for transparent meshes, which /// have to be sorted back-to-front to render with the painter's algorithm. /// These types of phase items are generally slower than binned phase items. +#[diagnostic::on_unimplemented(message = "`{Self}` is not a phase item", label = "invalid item")] pub trait PhaseItem: Sized + Send + Sync + 'static { /// Whether or not this `PhaseItem` should be subjected to automatic batching. (Default: `true`) const AUTOMATIC_BATCHING: bool = true; @@ -808,6 +809,10 @@ impl PhaseItemExtraIndex { /// /// An example of a binned phase item is `Opaque3d`, for which the rendering /// order isn't critical. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a binned phase item", + label = "invalid item" +)] pub trait BinnedPhaseItem: PhaseItem { /// The key used for binning [`PhaseItem`]s into bins. Order the members of /// [`BinnedPhaseItem::BinKey`] by the order of binding for best @@ -836,6 +841,10 @@ pub trait BinnedPhaseItem: PhaseItem { /// /// An example of a sorted phase item is `Transparent3d`, which must be sorted /// back to front in order to correctly render with the painter's algorithm. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a sorted phase item", + label = "invalid item" +)] pub trait SortedPhaseItem: PhaseItem { /// The type used for ordering the items. The smallest values are drawn first. /// This order can be calculated using the [`ViewRangefinder3d`], @@ -867,6 +876,10 @@ pub trait SortedPhaseItem: PhaseItem { /// cached in the [`PipelineCache`]. /// /// You can use the [`SetItemPipeline`] render command to set the pipeline for this item. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a cached phase item", + label = "invalid item" +)] pub trait CachedRenderPipelinePhaseItem: PhaseItem { /// The id of the render pipeline, cached in the [`PipelineCache`], that will be used to draw /// this phase item. diff --git a/crates/bevy_render/src/render_resource/bind_group.rs b/crates/bevy_render/src/render_resource/bind_group.rs index ff61060ce796d..344a203578bc1 100644 --- a/crates/bevy_render/src/render_resource/bind_group.rs +++ b/crates/bevy_render/src/render_resource/bind_group.rs @@ -280,6 +280,10 @@ impl Deref for BindGroup { /// } /// } /// ``` +#[diagnostic::on_unimplemented( + message = "`{Self}` can not be used as a bind group", + label = "invalid bind group" +)] pub trait AsBindGroup { /// Data that will be stored alongside the "prepared" bind group. type Data: Send + Sync; diff --git a/crates/bevy_render/src/render_resource/gpu_array_buffer.rs b/crates/bevy_render/src/render_resource/gpu_array_buffer.rs index 9765cfc627adc..26a6fd4ec57f5 100644 --- a/crates/bevy_render/src/render_resource/gpu_array_buffer.rs +++ b/crates/bevy_render/src/render_resource/gpu_array_buffer.rs @@ -13,6 +13,10 @@ use std::marker::PhantomData; use wgpu::{BindingResource, BufferUsages}; /// Trait for types able to go in a [`GpuArrayBuffer`]. +#[diagnostic::on_unimplemented( + message = "`{Self}` can not be used in a GPU array buffer", + label = "invalid bufferable" +)] pub trait GpuArrayBufferable: ShaderType + ShaderSize + WriteInto + Clone {} impl GpuArrayBufferable for T {} diff --git a/crates/bevy_render/src/texture/image.rs b/crates/bevy_render/src/texture/image.rs index 4b0a46bd3a7bc..e1b568db40363 100644 --- a/crates/bevy_render/src/texture/image.rs +++ b/crates/bevy_render/src/texture/image.rs @@ -787,6 +787,10 @@ impl<'a> ImageType<'a> { } /// Used to calculate the volume of an item. +#[diagnostic::on_unimplemented( + message = "`{Self}` does not a definition for volume", + label = "invalid volume" +)] pub trait Volume { fn volume(&self) -> usize; } @@ -799,6 +803,10 @@ impl Volume for Extent3d { } /// Extends the wgpu [`TextureFormat`] with information about the pixel. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a `TextureFormat`", + label = "invalid `TextureFormat`" +)] pub trait TextureFormatPixelInfo { /// Returns the size of a pixel in bytes of the format. fn pixel_size(&self) -> usize; diff --git a/crates/bevy_sprite/src/mesh2d/material.rs b/crates/bevy_sprite/src/mesh2d/material.rs index d58083763aeaa..6e16845ad6624 100644 --- a/crates/bevy_sprite/src/mesh2d/material.rs +++ b/crates/bevy_sprite/src/mesh2d/material.rs @@ -102,6 +102,10 @@ use crate::{ /// @group(2) @binding(1) var color_texture: texture_2d; /// @group(2) @binding(2) var color_sampler: sampler; /// ``` +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a 2D material", + label = "invalid material" +)] pub trait Material2d: AsBindGroup + Asset + Clone + Sized { /// Returns this material's vertex shader. If [`ShaderRef::Default`] is returned, the default mesh vertex shader /// will be used. diff --git a/crates/bevy_state/src/state/computed_states.rs b/crates/bevy_state/src/state/computed_states.rs index fda0f99d8c821..0ca0b889598aa 100644 --- a/crates/bevy_state/src/state/computed_states.rs +++ b/crates/bevy_state/src/state/computed_states.rs @@ -68,6 +68,10 @@ use super::states::States; /// .init_state::() /// .add_computed_state::(); /// ``` +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a computed state", + label = "invalid state" +)] pub trait ComputedStates: 'static + Send + Sync + Clone + PartialEq + Eq + Hash + Debug { /// The set of states from which the [`Self`] is derived. /// diff --git a/crates/bevy_state/src/state/freely_mutable_state.rs b/crates/bevy_state/src/state/freely_mutable_state.rs index 1fc809f9e5d1f..adec59b50b66c 100644 --- a/crates/bevy_state/src/state/freely_mutable_state.rs +++ b/crates/bevy_state/src/state/freely_mutable_state.rs @@ -9,6 +9,11 @@ use super::transitions::*; /// /// While ordinary states are freely mutable (and implement this trait as part of their derive macro), /// computed states are not: instead, they can *only* change when the states that drive them do. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a mutable state", + label = "invalid state", + note = "consider annotating `{Self}` with `#[derive(States)]`" +)] pub trait FreelyMutableState: States { /// This function registers all the necessary systems to apply state changes and run transition schedules fn register_state(schedule: &mut Schedule) { diff --git a/crates/bevy_state/src/state/state_set.rs b/crates/bevy_state/src/state/state_set.rs index 067711829dbf0..73d566d953130 100644 --- a/crates/bevy_state/src/state/state_set.rs +++ b/crates/bevy_state/src/state/state_set.rs @@ -27,6 +27,10 @@ mod sealed { /// /// It is sealed, and auto implemented for all [`States`] types and /// tuples containing them. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a state set", + label = "invalid state set" +)] pub trait StateSet: sealed::StateSetSealed { /// The total [`DEPENDENCY_DEPTH`](`States::DEPENDENCY_DEPTH`) of all /// the states that are part of this [`StateSet`], added together. diff --git a/crates/bevy_state/src/state/states.rs b/crates/bevy_state/src/state/states.rs index 6f2be17cd5759..bcd627580c91d 100644 --- a/crates/bevy_state/src/state/states.rs +++ b/crates/bevy_state/src/state/states.rs @@ -54,6 +54,11 @@ use std::hash::Hash; /// app.add_systems(Update, handle_escape_pressed.run_if(in_state(GameState::MainMenu))); /// app.add_systems(OnEnter(GameState::SettingsMenu), open_settings_menu); /// ``` +#[diagnostic::on_unimplemented( + message = "`{Self}` can not be used as a state", + label = "invalid state", + note = "consider annotating `{Self}` with `#[derive(States)]`" +)] pub trait States: 'static + Send + Sync + Clone + PartialEq + Eq + Hash + Debug { /// How many other states this state depends on. /// Used to help order transitions and de-duplicate [`ComputedStates`](crate::state::ComputedStates), as well as prevent cyclical diff --git a/crates/bevy_state/src/state/sub_states.rs b/crates/bevy_state/src/state/sub_states.rs index 8046a059b9652..9aa05567a7ffa 100644 --- a/crates/bevy_state/src/state/sub_states.rs +++ b/crates/bevy_state/src/state/sub_states.rs @@ -143,6 +143,11 @@ pub use bevy_state_macros::SubStates; /// /// impl FreelyMutableState for GamePhase {} /// ``` +#[diagnostic::on_unimplemented( + message = "`{Self}` can not be used as a sub-state", + label = "invalid sub-state", + note = "consider annotating `{Self}` with `#[derive(SubStates)]`" +)] pub trait SubStates: States + FreelyMutableState { /// The set of states from which the [`Self`] is derived. /// diff --git a/crates/bevy_tasks/src/iter/mod.rs b/crates/bevy_tasks/src/iter/mod.rs index 6887fa05440a1..0624dd178b3d8 100644 --- a/crates/bevy_tasks/src/iter/mod.rs +++ b/crates/bevy_tasks/src/iter/mod.rs @@ -11,6 +11,10 @@ pub use adapters::*; /// run in parallel is inexpensive, *a [`ParallelIterator`] could take longer /// than a normal [`Iterator`]*. Therefore, you should profile your code before /// using [`ParallelIterator`]. +#[diagnostic::on_unimplemented( + message = "`{Self}` can not be iterated in parallel", + label = "invalid iterator" +)] pub trait ParallelIterator where BatchIter: Iterator + Send, diff --git a/crates/bevy_tasks/src/slice.rs b/crates/bevy_tasks/src/slice.rs index 93568fd15dad0..54ad85c4849ab 100644 --- a/crates/bevy_tasks/src/slice.rs +++ b/crates/bevy_tasks/src/slice.rs @@ -1,6 +1,7 @@ use super::TaskPool; /// Provides functions for mapping read-only slices across a provided [`TaskPool`]. +#[diagnostic::on_unimplemented(message = "`{Self}` can not be sliced in parallel")] pub trait ParallelSlice: AsRef<[T]> { /// Splits the slice in chunks of size `chunks_size` or less and maps the chunks /// in parallel across the provided `task_pool`. One task is spawned in the task pool @@ -101,6 +102,7 @@ pub trait ParallelSlice: AsRef<[T]> { impl ParallelSlice for S where S: AsRef<[T]> {} /// Provides functions for mapping mutable slices across a provided [`TaskPool`]. +#[diagnostic::on_unimplemented(message = "`{Self}` can not be mutably sliced in parallel")] pub trait ParallelSliceMut: AsMut<[T]> { /// Splits the slice in chunks of size `chunks_size` or less and maps the chunks /// in parallel across the provided `task_pool`. One task is spawned in the task pool diff --git a/crates/bevy_ui/src/measurement.rs b/crates/bevy_ui/src/measurement.rs index b482bd01aa759..70a606b5c14d5 100644 --- a/crates/bevy_ui/src/measurement.rs +++ b/crates/bevy_ui/src/measurement.rs @@ -18,6 +18,7 @@ impl std::fmt::Debug for ContentSize { /// A `Measure` is used to compute the size of a ui node /// when the size of that node is based on its content. +#[diagnostic::on_unimplemented(message = "`{Self}` can not be measured", label = "invalid UI node")] pub trait Measure: Send + Sync + 'static { /// Calculate the size of the node given the constraints. fn measure( diff --git a/crates/bevy_ui/src/ui_material.rs b/crates/bevy_ui/src/ui_material.rs index dfeb3ee4c19ce..99f9269a2032d 100644 --- a/crates/bevy_ui/src/ui_material.rs +++ b/crates/bevy_ui/src/ui_material.rs @@ -90,6 +90,10 @@ use bevy_render::render_resource::{AsBindGroup, RenderPipelineDescriptor, Shader /// /// } /// ``` +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a UI material", + label = "invalid material" +)] pub trait UiMaterial: AsBindGroup + Asset + Clone + Sized { /// Returns this materials vertex shader. If [`ShaderRef::Default`] is returned, the default UI /// vertex shader will be used. From 00df7646c186cf52af1d334cdca7e8ed9010d0d6 Mon Sep 17 00:00:00 2001 From: Zachary Harrold Date: Tue, 14 May 2024 11:04:21 +1000 Subject: [PATCH 2/7] Remove Redundant `on_unimplemented` Messages --- crates/bevy_animation/src/animatable.rs | 4 ---- crates/bevy_app/src/plugin.rs | 5 ---- crates/bevy_app/src/plugin_group.rs | 4 ---- crates/bevy_asset/src/direct_access_ext.rs | 1 - crates/bevy_asset/src/io/mod.rs | 24 ------------------- crates/bevy_asset/src/lib.rs | 5 ---- crates/bevy_asset/src/loader.rs | 12 ---------- crates/bevy_asset/src/meta.rs | 8 ------- crates/bevy_asset/src/processor/process.rs | 8 ------- crates/bevy_asset/src/saver.rs | 8 ------- crates/bevy_asset/src/transformer.rs | 4 ---- crates/bevy_audio/src/audio_source.rs | 5 ---- crates/bevy_audio/src/sinks.rs | 4 ---- crates/bevy_color/src/color_difference.rs | 4 ---- crates/bevy_color/src/color_ops.rs | 20 ---------------- crates/bevy_color/src/color_range.rs | 4 ---- crates/bevy_diagnostic/src/diagnostic.rs | 1 - crates/bevy_dynamic_plugin/src/loader.rs | 1 - crates/bevy_ecs/src/bundle.rs | 4 ---- crates/bevy_ecs/src/change_detection.rs | 8 ------- crates/bevy_ecs/src/entity/map_entities.rs | 5 ---- crates/bevy_ecs/src/intern.rs | 4 ---- crates/bevy_ecs/src/label.rs | 6 ----- .../bevy_ecs/src/reflect/entity_commands.rs | 1 - crates/bevy_ecs/src/schedule/condition.rs | 4 ---- crates/bevy_ecs/src/storage/sparse_set.rs | 4 ---- crates/bevy_ecs/src/system/commands/mod.rs | 4 ---- crates/bevy_ecs/src/system/system.rs | 4 ---- crates/bevy_ecs/src/system/system_param.rs | 4 ---- crates/bevy_ecs/src/world/mod.rs | 2 -- crates/bevy_gizmos/src/config.rs | 4 ---- crates/bevy_gizmos/src/lib.rs | 1 - crates/bevy_gizmos/src/primitives/dim2.rs | 4 ---- crates/bevy_gizmos/src/primitives/dim3.rs | 4 ---- crates/bevy_hierarchy/src/child_builder.rs | 8 ------- crates/bevy_hierarchy/src/hierarchy.rs | 4 ---- crates/bevy_hierarchy/src/query_extension.rs | 1 - .../bevy_math/src/bounding/bounded2d/mod.rs | 1 - .../bevy_math/src/bounding/bounded3d/mod.rs | 1 - crates/bevy_math/src/bounding/mod.rs | 8 ------- crates/bevy_math/src/common_traits.rs | 8 ------- crates/bevy_math/src/cubic_splines.rs | 8 ------- crates/bevy_math/src/primitives/mod.rs | 16 ------------- .../bevy_math/src/sampling/shape_sampling.rs | 1 - crates/bevy_math/src/sampling/standard.rs | 3 --- crates/bevy_pbr/src/extended_material.rs | 4 ---- crates/bevy_pbr/src/light_probe/mod.rs | 4 ---- crates/bevy_pbr/src/material.rs | 4 ---- .../bevy_pbr/src/meshlet/persistent_buffer.rs | 4 ---- crates/bevy_ptr/src/lib.rs | 8 ------- crates/bevy_reflect/src/array.rs | 1 - crates/bevy_reflect/src/enums/enum_trait.rs | 1 - crates/bevy_reflect/src/list.rs | 1 - crates/bevy_reflect/src/map.rs | 1 - crates/bevy_reflect/src/struct_trait.rs | 2 -- crates/bevy_reflect/src/tuple.rs | 2 -- crates/bevy_reflect/src/tuple_struct.rs | 8 ------- crates/bevy_render/src/camera/projection.rs | 1 - crates/bevy_render/src/extract_component.rs | 4 ---- crates/bevy_render/src/extract_instances.rs | 4 ---- crates/bevy_render/src/extract_resource.rs | 4 ---- crates/bevy_render/src/mesh/primitives/mod.rs | 4 ---- crates/bevy_render/src/render_asset.rs | 4 ---- crates/bevy_render/src/render_graph/app.rs | 1 - crates/bevy_render/src/render_graph/node.rs | 8 ------- crates/bevy_render/src/render_phase/draw.rs | 9 ------- crates/bevy_render/src/render_phase/mod.rs | 13 ---------- .../src/render_resource/bind_group.rs | 4 ---- .../src/render_resource/gpu_array_buffer.rs | 4 ---- crates/bevy_render/src/texture/image.rs | 8 ------- crates/bevy_sprite/src/mesh2d/material.rs | 4 ---- .../bevy_state/src/state/computed_states.rs | 4 ---- crates/bevy_state/src/state/state_set.rs | 4 ---- crates/bevy_tasks/src/iter/mod.rs | 4 ---- crates/bevy_tasks/src/slice.rs | 2 -- crates/bevy_ui/src/measurement.rs | 1 - crates/bevy_ui/src/ui_material.rs | 4 ---- 77 files changed, 375 deletions(-) diff --git a/crates/bevy_animation/src/animatable.rs b/crates/bevy_animation/src/animatable.rs index f35e8846d2e51..4e59ccc8b2875 100644 --- a/crates/bevy_animation/src/animatable.rs +++ b/crates/bevy_animation/src/animatable.rs @@ -16,10 +16,6 @@ pub struct BlendInput { } /// An animatable value type. -#[diagnostic::on_unimplemented( - message = "`{Self}` can not be animated", - label = "invalid animatable" -)] pub trait Animatable: Reflect + Sized + Send + Sync + 'static { /// Interpolates between `a` and `b` with a interpolation factor of `time`. /// diff --git a/crates/bevy_app/src/plugin.rs b/crates/bevy_app/src/plugin.rs index 7103a58dd8935..3c5ca1adf0dc7 100644 --- a/crates/bevy_app/src/plugin.rs +++ b/crates/bevy_app/src/plugin.rs @@ -55,7 +55,6 @@ use std::any::Any; /// } /// # fn damp_flickering() {} /// ``` -#[diagnostic::on_unimplemented(message = "`{Self}` is not a plugin", label = "invalid plugin")] pub trait Plugin: Downcast + Any + Send + Sync { /// Configures the [`App`] to which this plugin is added. fn build(&self, app: &mut App); @@ -131,10 +130,6 @@ pub type CreatePlugin = unsafe fn() -> *mut dyn Plugin; /// /// This is implemented for all types which implement [`Plugin`], /// [`PluginGroup`](super::PluginGroup), and tuples over [`Plugins`]. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a set of plugins", - label = "invalid plugin set" -)] pub trait Plugins: sealed::Plugins {} impl Plugins for T where T: sealed::Plugins {} diff --git a/crates/bevy_app/src/plugin_group.rs b/crates/bevy_app/src/plugin_group.rs index b0082a8d0f5b0..b41a78f067a1a 100644 --- a/crates/bevy_app/src/plugin_group.rs +++ b/crates/bevy_app/src/plugin_group.rs @@ -3,10 +3,6 @@ use bevy_utils::{tracing::debug, tracing::warn, TypeIdMap}; use std::any::TypeId; /// Combines multiple [`Plugin`]s into a single unit. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a plugin group", - label = "invalid plugin group" -)] pub trait PluginGroup: Sized { /// Configures the [`Plugin`]s that are to be added. fn build(self) -> PluginGroupBuilder; diff --git a/crates/bevy_asset/src/direct_access_ext.rs b/crates/bevy_asset/src/direct_access_ext.rs index 293ea05228ce6..bfa7fa17b29c0 100644 --- a/crates/bevy_asset/src/direct_access_ext.rs +++ b/crates/bevy_asset/src/direct_access_ext.rs @@ -5,7 +5,6 @@ use bevy_ecs::world::World; use crate::{meta::Settings, Asset, AssetPath, AssetServer, Assets, Handle}; -#[diagnostic::on_unimplemented(message = "`{Self}` is not a World", label = "invalid world")] pub trait DirectAssetAccessExt { /// Insert an asset similarly to [`Assets::add`]. fn add_asset(&mut self, asset: impl Into) -> Handle; diff --git a/crates/bevy_asset/src/io/mod.rs b/crates/bevy_asset/src/io/mod.rs index 4b15cb4c453ca..a249d7d06121b 100644 --- a/crates/bevy_asset/src/io/mod.rs +++ b/crates/bevy_asset/src/io/mod.rs @@ -72,10 +72,6 @@ impl From for AssetReaderError { } } -#[diagnostic::on_unimplemented( - message = "`{Self}` is not an asynchronous and seekable reader", - label = "invalid reader" -)] pub trait AsyncReadAndSeek: AsyncRead + AsyncSeek {} impl AsyncReadAndSeek for T {} @@ -87,10 +83,6 @@ pub type Reader<'a> = dyn AsyncReadAndSeek + Unpin + Send + Sync + 'a; /// `path`. This trait is not object safe, if needed use a dyn [`ErasedAssetReader`] instead. /// /// Also see [`AssetWriter`]. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not an asset reader", - label = "invalid asset reader" -)] pub trait AssetReader: Send + Sync + 'static { /// Returns a future to load the full file data at the provided path. fn read<'a>( @@ -129,10 +121,6 @@ pub trait AssetReader: Send + Sync + 'static { /// Equivalent to an [`AssetReader`] but using boxed futures, necessary eg. when using a `dyn AssetReader`, /// as [`AssetReader`] isn't currently object safe. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not an erasable asset reader", - label = "invalid asset reader" -)] pub trait ErasedAssetReader: Send + Sync + 'static { /// Returns a future to load the full file data at the provided path. fn read<'a>(&'a self, path: &'a Path) @@ -204,10 +192,6 @@ pub enum AssetWriterError { /// `path`. This trait is not object safe, if needed use a dyn [`ErasedAssetWriter`] instead. /// /// Also see [`AssetReader`]. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not an asset writer", - label = "invalid asset writer" -)] pub trait AssetWriter: Send + Sync + 'static { /// Writes the full asset bytes at the provided path. fn write<'a>( @@ -290,10 +274,6 @@ pub trait AssetWriter: Send + Sync + 'static { /// Equivalent to an [`AssetWriter`] but using boxed futures, necessary eg. when using a `dyn AssetWriter`, /// as [`AssetWriter`] isn't currently object safe. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not an erasable asset writer", - label = "invalid asset writer" -)] pub trait ErasedAssetWriter: Send + Sync + 'static { /// Writes the full asset bytes at the provided path. fn write<'a>(&'a self, path: &'a Path) -> BoxedFuture, AssetWriterError>>; @@ -449,10 +429,6 @@ pub enum AssetSourceEvent { /// A handle to an "asset watcher" process, that will listen for and emit [`AssetSourceEvent`] values for as long as /// [`AssetWatcher`] has not been dropped. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not an asset watcher", - label = "invalid asset watcher" -)] pub trait AssetWatcher: Send + Sync + 'static {} /// An [`AsyncRead`] implementation capable of reading a [`Vec`]. diff --git a/crates/bevy_asset/src/lib.rs b/crates/bevy_asset/src/lib.rs index db38ba0742dd8..248d6c7eb5531 100644 --- a/crates/bevy_asset/src/lib.rs +++ b/crates/bevy_asset/src/lib.rs @@ -230,10 +230,6 @@ impl Plugin for AssetPlugin { )] pub trait Asset: VisitAssetDependencies + TypePath + Send + Sync + 'static {} -#[diagnostic::on_unimplemented( - message = "`{Self}` can not visit dependencies", - label = "invalid asset" -)] pub trait VisitAssetDependencies { fn visit_dependencies(&self, visit: &mut impl FnMut(UntypedAssetId)); } @@ -283,7 +279,6 @@ impl VisitAssetDependencies for Vec { } /// Adds asset-related builder methods to [`App`]. -#[diagnostic::on_unimplemented(message = "`{Self}` is not an App", label = "invalid `App`")] pub trait AssetApp { /// Registers the given `loader` in the [`App`]'s [`AssetServer`]. fn register_asset_loader(&mut self, loader: L) -> &mut Self; diff --git a/crates/bevy_asset/src/loader.rs b/crates/bevy_asset/src/loader.rs index 333b4010522d0..8630ffea8f1e5 100644 --- a/crates/bevy_asset/src/loader.rs +++ b/crates/bevy_asset/src/loader.rs @@ -22,10 +22,6 @@ use thiserror::Error; /// Loads an [`Asset`] from a given byte [`Reader`]. This can accept [`AssetLoader::Settings`], which configure how the [`Asset`] /// should be loaded. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not an asset loader", - label = "invalid asset loader" -)] pub trait AssetLoader: Send + Sync + 'static { /// The top level [`Asset`] loaded by this [`AssetLoader`]. type Asset: crate::Asset; @@ -49,10 +45,6 @@ pub trait AssetLoader: Send + Sync + 'static { } /// Provides type-erased access to an [`AssetLoader`]. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not an erasable asset loader", - label = "invalid asset loader" -)] pub trait ErasedAssetLoader: Send + Sync + 'static { /// Asynchronously loads the asset(s) from the bytes provided by [`Reader`]. fn load<'a>( @@ -239,10 +231,6 @@ impl ErasedLoadedAsset { } /// A type erased container for an [`Asset`] value that is capable of inserting the [`Asset`] into a [`World`]'s [`Assets`] collection. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not an asset container", - label = "invalid container" -)] pub trait AssetContainer: Downcast + Any + Send + Sync + 'static { fn insert(self: Box, id: UntypedAssetId, world: &mut World); fn asset_type_name(&self) -> &'static str; diff --git a/crates/bevy_asset/src/meta.rs b/crates/bevy_asset/src/meta.rs index 7e8d51f039889..dcfdd957a408a 100644 --- a/crates/bevy_asset/src/meta.rs +++ b/crates/bevy_asset/src/meta.rs @@ -114,10 +114,6 @@ pub struct ProcessedInfoMinimal { /// A dynamic type-erased counterpart to [`AssetMeta`] that enables passing around and interacting with [`AssetMeta`] without knowing /// its type. -#[diagnostic::on_unimplemented( - message = "`{Self}` can not be used as an erased AssetMeta", - label = "invalid asset meta" -)] pub trait AssetMetaDyn: Downcast + Send + Sync { /// Returns a reference to the [`AssetLoader`] settings, if they exist. fn loader_settings(&self) -> Option<&dyn Settings>; @@ -164,10 +160,6 @@ impl_downcast!(AssetMetaDyn); /// Settings used by the asset system, such as by [`AssetLoader`], [`Process`], and [`AssetSaver`] /// /// [`AssetSaver`]: crate::saver::AssetSaver -#[diagnostic::on_unimplemented( - message = "`{Self}` can not be used as an asset setting", - label = "invalid settings" -)] pub trait Settings: Downcast + Send + Sync + 'static {} impl Settings for T where T: Send + Sync {} diff --git a/crates/bevy_asset/src/processor/process.rs b/crates/bevy_asset/src/processor/process.rs index 0cbe071dfffca..442c9451c868d 100644 --- a/crates/bevy_asset/src/processor/process.rs +++ b/crates/bevy_asset/src/processor/process.rs @@ -21,10 +21,6 @@ use thiserror::Error; /// /// This is a "low level", maximally flexible interface. Most use cases are better served by the [`LoadTransformAndSave`] implementation /// of [`Process`]. -#[diagnostic::on_unimplemented( - message = "`{Self}` can not process assets", - label = "invalid asset process" -)] pub trait Process: Send + Sync + Sized + 'static { /// The configuration / settings used to process the asset. This will be stored in the [`AssetMeta`] and is user-configurable per-asset. type Settings: Settings + Default + Serialize + for<'a> Deserialize<'a>; @@ -247,10 +243,6 @@ impl> Process /// A type-erased variant of [`Process`] that enables interacting with processor implementations without knowing /// their type. -#[diagnostic::on_unimplemented( - message = "`{Self}` can not be erased", - label = "invalid asset process" -)] pub trait ErasedProcessor: Send + Sync { /// Type-erased variant of [`Process::process`]. fn process<'a>( diff --git a/crates/bevy_asset/src/saver.rs b/crates/bevy_asset/src/saver.rs index 0ee2a87db9ab9..36408dd125f29 100644 --- a/crates/bevy_asset/src/saver.rs +++ b/crates/bevy_asset/src/saver.rs @@ -7,10 +7,6 @@ use std::{borrow::Borrow, hash::Hash, ops::Deref}; /// Saves an [`Asset`] of a given [`AssetSaver::Asset`] type. [`AssetSaver::OutputLoader`] will then be used to load the saved asset /// in the final deployed application. The saver should produce asset bytes in a format that [`AssetSaver::OutputLoader`] can read. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not an asset saver", - label = "invalid asset saver" -)] pub trait AssetSaver: Send + Sync + 'static { /// The top level [`Asset`] saved by this [`AssetSaver`]. type Asset: Asset; @@ -34,10 +30,6 @@ pub trait AssetSaver: Send + Sync + 'static { } /// A type-erased dynamic variant of [`AssetSaver`] that allows callers to save assets without knowing the actual type of the [`AssetSaver`]. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not an erasable asset saver", - label = "invalid asset saver" -)] pub trait ErasedAssetSaver: Send + Sync + 'static { /// Saves the given runtime [`ErasedLoadedAsset`] by writing it to a byte format using `writer`. The passed in `settings` can influence how the /// `asset` is saved. diff --git a/crates/bevy_asset/src/transformer.rs b/crates/bevy_asset/src/transformer.rs index 196fd7a8b576a..0ffddc4658a43 100644 --- a/crates/bevy_asset/src/transformer.rs +++ b/crates/bevy_asset/src/transformer.rs @@ -8,10 +8,6 @@ use std::{ }; /// Transforms an [`Asset`] of a given [`AssetTransformer::AssetInput`] type to an [`Asset`] of [`AssetTransformer::AssetOutput`] type. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not an asset transformer", - label = "invalid asset transformer" -)] pub trait AssetTransformer: Send + Sync + 'static { /// The [`Asset`] type which this [`AssetTransformer`] takes as and input. type AssetInput: Asset; diff --git a/crates/bevy_audio/src/audio_source.rs b/crates/bevy_audio/src/audio_source.rs index 11a78422d9e06..b501eaeea09af 100644 --- a/crates/bevy_audio/src/audio_source.rs +++ b/crates/bevy_audio/src/audio_source.rs @@ -80,10 +80,6 @@ impl AssetLoader for AudioLoader { /// Types that implement this trait usually contain raw sound data that can be converted into an iterator of samples. /// This trait is implemented for [`AudioSource`]. /// Check the example [`decodable`](https://github.com/bevyengine/bevy/blob/latest/examples/audio/decodable.rs) for how to implement this trait on a custom type. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a decodable audio source", - label = "invalid Source" -)] pub trait Decodable: Send + Sync + 'static { /// The type of the audio samples. /// Usually a [`u16`], [`i16`] or [`f32`], as those implement [`rodio::Sample`]. @@ -110,7 +106,6 @@ impl Decodable for AudioSource { /// A trait that allows adding a custom audio source to the object. /// This is implemented for [`App`][bevy_app::App] to allow registering custom [`Decodable`] types. -#[diagnostic::on_unimplemented(message = "`{Self}` is not an App", label = "invalid `App`")] pub trait AddAudioSource { /// Registers an audio source. /// The type must implement [`Decodable`], diff --git a/crates/bevy_audio/src/sinks.rs b/crates/bevy_audio/src/sinks.rs index 734dfa17605fd..68fa1e99c4543 100644 --- a/crates/bevy_audio/src/sinks.rs +++ b/crates/bevy_audio/src/sinks.rs @@ -4,10 +4,6 @@ use bevy_transform::prelude::Transform; use rodio::{Sink, SpatialSink}; /// Common interactions with an audio sink. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not an audio sink", - label = "invalid audio sink" -)] pub trait AudioSinkPlayback { /// Gets the volume of the sound. /// diff --git a/crates/bevy_color/src/color_difference.rs b/crates/bevy_color/src/color_difference.rs index 48a59a3bf7fb9..a2bdf10e14549 100644 --- a/crates/bevy_color/src/color_difference.rs +++ b/crates/bevy_color/src/color_difference.rs @@ -2,10 +2,6 @@ /// Calculate the distance between this and another color as if they were coordinates /// in a Euclidean space. Alpha is not considered in the distance calculation. -#[diagnostic::on_unimplemented( - message = "`{Self}` does not have a definition for distance", - label = "invalid color model" -)] pub trait EuclideanDistance: Sized { /// Distance from `self` to `other`. fn distance(&self, other: &Self) -> f32 { diff --git a/crates/bevy_color/src/color_ops.rs b/crates/bevy_color/src/color_ops.rs index ec9f4b9478988..e37592bdd4dba 100644 --- a/crates/bevy_color/src/color_ops.rs +++ b/crates/bevy_color/src/color_ops.rs @@ -3,10 +3,6 @@ use bevy_math::{Vec3, Vec4}; /// Methods for changing the luminance of a color. Note that these methods are not /// guaranteed to produce consistent results across color spaces, /// but will be within a given space. -#[diagnostic::on_unimplemented( - message = "`{Self}` does not have a definition of luminance", - label = "non-luminance color model" -)] pub trait Luminance: Sized { /// Return the luminance of this color (0.0 - 1.0). fn luminance(&self) -> f32; @@ -34,10 +30,6 @@ pub trait Luminance: Sized { } /// Linear interpolation of two colors within a given color space. -#[diagnostic::on_unimplemented( - message = "`{Self}` can not be mixed", - label = "unmixable color model" -)] pub trait Mix: Sized { /// Linearly interpolate between this and another color, by factor. /// Factor should be between 0.0 and 1.0. @@ -51,10 +43,6 @@ pub trait Mix: Sized { } /// Methods for manipulating alpha values. -#[diagnostic::on_unimplemented( - message = "`{Self}` does not have an alpha channel", - label = "opaque color model" -)] pub trait Alpha: Sized { /// Return a new version of this color with the given alpha value. fn with_alpha(&self, alpha: f32) -> Self; @@ -77,10 +65,6 @@ pub trait Alpha: Sized { } /// Trait for manipulating the hue of a color. -#[diagnostic::on_unimplemented( - message = "`{Self}` does not have a definition of hue", - label = "non-hue color model" -)] pub trait Hue: Sized { /// Return a new version of this color with the hue channel set to the given value. fn with_hue(&self, hue: f32) -> Self; @@ -99,10 +83,6 @@ pub trait Hue: Sized { } /// Trait with methods for converting colors to non-color types -#[diagnostic::on_unimplemented( - message = "`{Self}` cannot be decomposed into color components", - label = "invalid color model" -)] pub trait ColorToComponents { /// Convert to an f32 array fn to_f32_array(self) -> [f32; 4]; diff --git a/crates/bevy_color/src/color_range.rs b/crates/bevy_color/src/color_range.rs index 7c375831b6a16..16d6f04866670 100644 --- a/crates/bevy_color/src/color_range.rs +++ b/crates/bevy_color/src/color_range.rs @@ -7,10 +7,6 @@ use crate::Mix; /// implements [`Mix`]. /// /// This is useful for defining gradients or animated color transitions. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a valid color range", - label = "invalid color range" -)] pub trait ColorRange { /// Get the color value at the given interpolation factor, which should be between 0.0 (start) /// and 1.0 (end). diff --git a/crates/bevy_diagnostic/src/diagnostic.rs b/crates/bevy_diagnostic/src/diagnostic.rs index 3eed83a91f657..b45ee593cfab3 100644 --- a/crates/bevy_diagnostic/src/diagnostic.rs +++ b/crates/bevy_diagnostic/src/diagnostic.rs @@ -382,7 +382,6 @@ impl SystemBuffer for DiagnosticsBuffer { } /// Extend [`App`] with new `register_diagnostic` function. -#[diagnostic::on_unimplemented(message = "`{Self}` is not an App", label = "invalid `App`")] pub trait RegisterDiagnostic { /// Register a new [`Diagnostic`] with an [`App`]. /// diff --git a/crates/bevy_dynamic_plugin/src/loader.rs b/crates/bevy_dynamic_plugin/src/loader.rs index 892321e825746..8b6517b237244 100644 --- a/crates/bevy_dynamic_plugin/src/loader.rs +++ b/crates/bevy_dynamic_plugin/src/loader.rs @@ -51,7 +51,6 @@ pub unsafe fn dynamically_load_plugin>( } /// An extension trait for [`App`] that allows loading dynamic plugins. -#[diagnostic::on_unimplemented(message = "`{Self}` is not an App", label = "invalid `App`")] pub trait DynamicPluginExt { /// Dynamically links a plugin at the given path, registering the plugin. /// diff --git a/crates/bevy_ecs/src/bundle.rs b/crates/bevy_ecs/src/bundle.rs index eb1d4737dca28..7ba65e9ba42cd 100644 --- a/crates/bevy_ecs/src/bundle.rs +++ b/crates/bevy_ecs/src/bundle.rs @@ -165,10 +165,6 @@ pub unsafe trait Bundle: DynamicBundle + Send + Sync + 'static { } /// The parts from [`Bundle`] that don't require statically knowing the components of the bundle. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a dynamic component bundle", - label = "invalid bundle" -)] pub trait DynamicBundle { // SAFETY: // The `StorageType` argument passed into [`Bundle::get_components`] must be correct for the diff --git a/crates/bevy_ecs/src/change_detection.rs b/crates/bevy_ecs/src/change_detection.rs index 430653ebaf3b9..d4cc1a73af4dd 100644 --- a/crates/bevy_ecs/src/change_detection.rs +++ b/crates/bevy_ecs/src/change_detection.rs @@ -43,10 +43,6 @@ pub const MAX_CHANGE_AGE: u32 = u32::MAX - (2 * CHECK_TICK_THRESHOLD - 1); /// } /// } /// ``` -#[diagnostic::on_unimplemented( - message = "`{Self}` does not support change detection", - label = "invalid change detecter" -)] pub trait DetectChanges { /// Returns `true` if this value was added after the system last ran. fn is_added(&self) -> bool; @@ -99,10 +95,6 @@ pub trait DetectChanges { /// } /// ``` /// -#[diagnostic::on_unimplemented( - message = "`{Self}` does not support mutable change detection", - label = "invalid change detecter" -)] pub trait DetectChangesMut: DetectChanges { /// The type contained within this smart pointer /// diff --git a/crates/bevy_ecs/src/entity/map_entities.rs b/crates/bevy_ecs/src/entity/map_entities.rs index 7b9ae1464ef71..b8e638f940018 100644 --- a/crates/bevy_ecs/src/entity/map_entities.rs +++ b/crates/bevy_ecs/src/entity/map_entities.rs @@ -37,7 +37,6 @@ use super::EntityHashMap; /// } /// } /// ``` -#[diagnostic::on_unimplemented(message = "`{Self}` can not map entities")] pub trait MapEntities { /// Updates all [`Entity`] references stored inside using `entity_mapper`. /// @@ -71,10 +70,6 @@ pub trait MapEntities { /// } /// } /// ``` -#[diagnostic::on_unimplemented( - message = "`{Self}` is not an entity mapper", - label = "invalid entity mapper" -)] pub trait EntityMapper { /// Map an entity to another entity fn map_entity(&mut self, entity: Entity) -> Entity; diff --git a/crates/bevy_ecs/src/intern.rs b/crates/bevy_ecs/src/intern.rs index 4b688e8bb04a8..54ea4e32071bc 100644 --- a/crates/bevy_ecs/src/intern.rs +++ b/crates/bevy_ecs/src/intern.rs @@ -91,10 +91,6 @@ impl From<&Interned> for Interned { /// A trait for internable values. /// /// This is used by [`Interner`] to create static references for values that are interned. -#[diagnostic::on_unimplemented( - message = "`{Self}` can not be interned", - label = "invalid internable" -)] pub trait Internable: Hash + Eq { /// Creates a static reference to `self`, possibly leaking memory. fn leak(&self) -> &'static Self; diff --git a/crates/bevy_ecs/src/label.rs b/crates/bevy_ecs/src/label.rs index 890af769015cc..7585913b75441 100644 --- a/crates/bevy_ecs/src/label.rs +++ b/crates/bevy_ecs/src/label.rs @@ -7,7 +7,6 @@ use std::{ /// An object safe version of [`Eq`]. This trait is automatically implemented /// for any `'static` type that implements `Eq`. -#[diagnostic::on_unimplemented(message = "`{Self}` does not implement dynamic `Eq`")] pub trait DynEq: Any { /// Casts the type to `dyn Any`. fn as_any(&self) -> &dyn Any; @@ -37,7 +36,6 @@ where /// An object safe version of [`Hash`]. This trait is automatically implemented /// for any `'static` type that implements `Hash`. -#[diagnostic::on_unimplemented(message = "`{Self}` does not implement dynamic `Hash`")] pub trait DynHash: DynEq { /// Casts the type to `dyn Any`. fn as_dyn_eq(&self) -> &dyn DynEq; @@ -112,10 +110,6 @@ macro_rules! define_label { ) => { $(#[$label_attr])* - #[diagnostic::on_unimplemented( - message = "`{Self}` is not a matching label", - label = "invalid label", - )] pub trait $label_trait_name: 'static + Send + Sync + ::std::fmt::Debug { $($trait_extra_methods)* diff --git a/crates/bevy_ecs/src/reflect/entity_commands.rs b/crates/bevy_ecs/src/reflect/entity_commands.rs index 92ae503b3de5b..8545b346bd15a 100644 --- a/crates/bevy_ecs/src/reflect/entity_commands.rs +++ b/crates/bevy_ecs/src/reflect/entity_commands.rs @@ -8,7 +8,6 @@ use std::borrow::Cow; use std::marker::PhantomData; /// An extension trait for [`EntityCommands`] for reflection related functions -#[diagnostic::on_unimplemented(message = "`{Self}` is not an App", label = "invalid `App`")] pub trait ReflectCommandExt { /// Adds the given boxed reflect component to the entity using the reflection data in /// [`AppTypeRegistry`]. diff --git a/crates/bevy_ecs/src/schedule/condition.rs b/crates/bevy_ecs/src/schedule/condition.rs index ac063b826011e..7d2f1ab6173ea 100644 --- a/crates/bevy_ecs/src/schedule/condition.rs +++ b/crates/bevy_ecs/src/schedule/condition.rs @@ -70,10 +70,6 @@ pub type BoxedCondition = Box>; /// # world.insert_resource(DidRun(false)); /// # app.run(&mut world); /// # assert!(world.resource::().0); -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a run condition", - label = "invalid run condition" -)] pub trait Condition: sealed::Condition { /// Returns a new run condition that only returns `true` /// if both this one and the passed `and_then` return `true`. diff --git a/crates/bevy_ecs/src/storage/sparse_set.rs b/crates/bevy_ecs/src/storage/sparse_set.rs index 10ae63dfe6788..dffdb71db961e 100644 --- a/crates/bevy_ecs/src/storage/sparse_set.rs +++ b/crates/bevy_ecs/src/storage/sparse_set.rs @@ -528,10 +528,6 @@ impl SparseSet { /// Ideally, the `usize` values should be very small (ie: incremented starting from /// zero), as the number of bits needed to represent a `SparseSetIndex` in a `FixedBitSet` /// is proportional to the **value** of those `usize`. -#[diagnostic::on_unimplemented( - message = "`{Self}` can not be used as a sparse set index", - label = "invalid index" -)] pub trait SparseSetIndex: Clone + PartialEq + Eq + Hash { /// Gets the sparse set index corresponding to this instance. fn sparse_set_index(&self) -> usize; diff --git a/crates/bevy_ecs/src/system/commands/mod.rs b/crates/bevy_ecs/src/system/commands/mod.rs index 3ba85a57e2dae..9d5e58802c317 100644 --- a/crates/bevy_ecs/src/system/commands/mod.rs +++ b/crates/bevy_ecs/src/system/commands/mod.rs @@ -675,10 +675,6 @@ impl<'w, 's> Commands<'w, 's> { /// assert_eq!(names, HashSet::from_iter(["Entity #0", "Entity #1"])); /// } /// ``` -#[diagnostic::on_unimplemented( - message = "`{Self}` is not an entity command", - label = "invalid command" -)] pub trait EntityCommand: Send + 'static { /// Executes this command for the given [`Entity`]. fn apply(self, id: Entity, world: &mut World); diff --git a/crates/bevy_ecs/src/system/system.rs b/crates/bevy_ecs/src/system/system.rs index ada3fa5dfd748..f8321a5d93389 100644 --- a/crates/bevy_ecs/src/system/system.rs +++ b/crates/bevy_ecs/src/system/system.rs @@ -271,10 +271,6 @@ impl Debug for dyn System { /// /// # assert_eq!(count, 2); /// ``` -#[diagnostic::on_unimplemented( - message = "`{Self}` can not run systems", - label = "invalid system runner" -)] pub trait RunSystemOnce: Sized { /// Runs a system and applies its deferred parameters. fn run_system_once, Out, Marker>(self, system: T) -> Out { diff --git a/crates/bevy_ecs/src/system/system_param.rs b/crates/bevy_ecs/src/system/system_param.rs index 8f77715c46de7..de328ca45333d 100644 --- a/crates/bevy_ecs/src/system/system_param.rs +++ b/crates/bevy_ecs/src/system/system_param.rs @@ -788,10 +788,6 @@ unsafe impl<'a, T: FromWorld + Send + 'static> SystemParam for Local<'a, T> { /// Types that implement `SystemBuffer` should take care to perform as many /// computations up-front as possible. Buffers cannot be applied in parallel, /// so you should try to minimize the time spent in [`SystemBuffer::apply`]. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a deferrable system parameter", - label = "invalid system parameter" -)] pub trait SystemBuffer: FromWorld + Send + 'static { /// Applies any deferred mutations to the [`World`]. fn apply(&mut self, system_meta: &SystemMeta, world: &mut World); diff --git a/crates/bevy_ecs/src/world/mod.rs b/crates/bevy_ecs/src/world/mod.rs index d002b11a68e47..ea52da782287b 100644 --- a/crates/bevy_ecs/src/world/mod.rs +++ b/crates/bevy_ecs/src/world/mod.rs @@ -73,7 +73,6 @@ pub use identifier::WorldId; /// commands.add(AddToCounter(42)); /// } /// ``` -#[diagnostic::on_unimplemented(message = "`{Self}` is not a command", label = "invalid command")] pub trait Command: Send + 'static { /// Applies this command, causing it to mutate the provided `world`. /// @@ -2607,7 +2606,6 @@ unsafe impl Sync for World {} /// using data from the supplied [`World`]. /// /// This can be helpful for complex initialization or context-aware defaults. -#[diagnostic::on_unimplemented(message = "`{Self}` can not be created from a World")] pub trait FromWorld { /// Creates `Self` using data from the given [`World`]. fn from_world(world: &mut World) -> Self; diff --git a/crates/bevy_gizmos/src/config.rs b/crates/bevy_gizmos/src/config.rs index 81bffe4f34b64..92f6962c19384 100644 --- a/crates/bevy_gizmos/src/config.rs +++ b/crates/bevy_gizmos/src/config.rs @@ -46,10 +46,6 @@ pub enum GizmoLineStyle { /// Here you can store additional configuration for you gizmo group not covered by [`GizmoConfig`] /// /// Make sure to derive [`Default`] + [`Reflect`] and register in the app using `app.init_gizmo_group::()` -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a gizmo configuration group", - label = "invalid configuration group" -)] pub trait GizmoConfigGroup: Reflect + TypePath + Default {} /// The default gizmo config group. diff --git a/crates/bevy_gizmos/src/lib.rs b/crates/bevy_gizmos/src/lib.rs index d75a55c09872c..d523f0dd5403f 100644 --- a/crates/bevy_gizmos/src/lib.rs +++ b/crates/bevy_gizmos/src/lib.rs @@ -188,7 +188,6 @@ impl Plugin for GizmoPlugin { } /// A extension trait adding `App::init_gizmo_group` and `App::insert_gizmo_config`. -#[diagnostic::on_unimplemented(message = "`{Self}` is not an App", label = "invalid `App`")] pub trait AppGizmoBuilder { /// Registers [`GizmoConfigGroup`] in the app enabling the use of [Gizmos<Config>](crate::gizmos::Gizmos). /// diff --git a/crates/bevy_gizmos/src/primitives/dim2.rs b/crates/bevy_gizmos/src/primitives/dim2.rs index 4777281c618eb..74028903b1df9 100644 --- a/crates/bevy_gizmos/src/primitives/dim2.rs +++ b/crates/bevy_gizmos/src/primitives/dim2.rs @@ -20,10 +20,6 @@ const HALF_MIN_LINE_LEN: f32 = 25.0; const INFINITE_LEN: f32 = 100_000.0; /// A trait for rendering 2D geometric primitives (`P`) with [`Gizmos`]. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a primitive 2D gizmo", - label = "invalid gizmo" -)] pub trait GizmoPrimitive2d { /// The output of `primitive_2d`. This is a builder to set non-default values. type Output<'a> diff --git a/crates/bevy_gizmos/src/primitives/dim3.rs b/crates/bevy_gizmos/src/primitives/dim3.rs index 02e09e358a918..8af28f396a675 100644 --- a/crates/bevy_gizmos/src/primitives/dim3.rs +++ b/crates/bevy_gizmos/src/primitives/dim3.rs @@ -17,10 +17,6 @@ const DEFAULT_NUMBER_SEGMENTS: usize = 5; const INFINITE_LEN: f32 = 10_000.0; /// A trait for rendering 3D geometric primitives (`P`) with [`Gizmos`]. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a primitive 3D gizmo", - label = "invalid gizmo" -)] pub trait GizmoPrimitive3d { /// The output of `primitive_3d`. This is a builder to set non-default values. type Output<'a> diff --git a/crates/bevy_hierarchy/src/child_builder.rs b/crates/bevy_hierarchy/src/child_builder.rs index acc64c4528289..6c32979666e63 100644 --- a/crates/bevy_hierarchy/src/child_builder.rs +++ b/crates/bevy_hierarchy/src/child_builder.rs @@ -309,10 +309,6 @@ impl ChildBuilder<'_> { } /// Trait for removing, adding and replacing children and parents of an entity. -#[diagnostic::on_unimplemented( - message = "`{Self}` can not build child entities", - label = "invalid builder" -)] pub trait BuildChildren { /// Takes a closure which builds children for this entity using [`ChildBuilder`]. fn with_children(&mut self, f: impl FnOnce(&mut ChildBuilder)) -> &mut Self; @@ -520,10 +516,6 @@ impl<'w> WorldChildBuilder<'w> { } /// Trait that defines adding, changing and children and parents of an entity directly through the [`World`]. -#[diagnostic::on_unimplemented( - message = "`{Self}` can not build child entities", - label = "invalid builder" -)] pub trait BuildWorldChildren { /// Takes a closure which builds children for this entity using [`WorldChildBuilder`]. fn with_children(&mut self, spawn_children: impl FnOnce(&mut WorldChildBuilder)) -> &mut Self; diff --git a/crates/bevy_hierarchy/src/hierarchy.rs b/crates/bevy_hierarchy/src/hierarchy.rs index 60462d94cae4f..26f26233a0fe5 100644 --- a/crates/bevy_hierarchy/src/hierarchy.rs +++ b/crates/bevy_hierarchy/src/hierarchy.rs @@ -81,10 +81,6 @@ impl Command for DespawnChildrenRecursive { } /// Trait that holds functions for despawning recursively down the transform hierarchy -#[diagnostic::on_unimplemented( - message = "`{Self}` can not despawn child entities", - label = "invalid despawner" -)] pub trait DespawnRecursiveExt { /// Despawns the provided entity alongside all descendants. fn despawn_recursive(self); diff --git a/crates/bevy_hierarchy/src/query_extension.rs b/crates/bevy_hierarchy/src/query_extension.rs index 3b3cbc1aa2ac8..d78dee681c30d 100644 --- a/crates/bevy_hierarchy/src/query_extension.rs +++ b/crates/bevy_hierarchy/src/query_extension.rs @@ -9,7 +9,6 @@ use bevy_ecs::{ use crate::{Children, Parent}; /// An extension trait for [`Query`] that adds hierarchy related methods. -#[diagnostic::on_unimplemented(message = "`{Self}` is not a Query", label = "invalid query")] pub trait HierarchyQueryExt<'w, 's, D: QueryData, F: QueryFilter> { /// Returns an [`Iterator`] of [`Entity`]s over all of `entity`s descendants. /// diff --git a/crates/bevy_math/src/bounding/bounded2d/mod.rs b/crates/bevy_math/src/bounding/bounded2d/mod.rs index d32364df75177..b97da70e3d17a 100644 --- a/crates/bevy_math/src/bounding/bounded2d/mod.rs +++ b/crates/bevy_math/src/bounding/bounded2d/mod.rs @@ -16,7 +16,6 @@ fn point_cloud_2d_center(points: &[Vec2]) -> Vec2 { } /// A trait with methods that return 2D bounded volumes for a shape -#[diagnostic::on_unimplemented(message = "`{Self}` is not bounded in 2D")] pub trait Bounded2d { /// Get an axis-aligned bounding box for the shape with the given translation and rotation. /// The rotation is in radians, counterclockwise, with 0 meaning no rotation. diff --git a/crates/bevy_math/src/bounding/bounded3d/mod.rs b/crates/bevy_math/src/bounding/bounded3d/mod.rs index 7fcc4c414a2f4..4c4ad16749e3d 100644 --- a/crates/bevy_math/src/bounding/bounded3d/mod.rs +++ b/crates/bevy_math/src/bounding/bounded3d/mod.rs @@ -20,7 +20,6 @@ fn point_cloud_3d_center(points: impl Iterator>) -> Vec3 } /// A trait with methods that return 3D bounded volumes for a shape -#[diagnostic::on_unimplemented(message = "`{Self}` is not bounded in 3D")] pub trait Bounded3d { /// Get an axis-aligned bounding box for the shape with the given translation and rotation fn aabb_3d(&self, translation: Vec3, rotation: Quat) -> Aabb3d; diff --git a/crates/bevy_math/src/bounding/mod.rs b/crates/bevy_math/src/bounding/mod.rs index c96d301283fd7..6de162d7291b7 100644 --- a/crates/bevy_math/src/bounding/mod.rs +++ b/crates/bevy_math/src/bounding/mod.rs @@ -10,10 +10,6 @@ /// overlapping elements or finding intersections. /// /// This trait supports both 2D and 3D bounding shapes. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a bounding volume", - label = "invalid volume" -)] pub trait BoundingVolume: Sized { /// The position type used for the volume. This should be `Vec2` for 2D and `Vec3` for 3D. type Translation: Clone + Copy + PartialEq; @@ -105,10 +101,6 @@ pub trait BoundingVolume: Sized { /// - Raycasting /// - Testing for overlap /// - Checking if an object is within the view frustum of a camera -#[diagnostic::on_unimplemented( - message = "`{Self}` can not test for volume intersections", - label = "invalid volume" -)] pub trait IntersectsVolume { /// Check if a volume intersects with this intersection test fn intersects(&self, volume: &Volume) -> bool; diff --git a/crates/bevy_math/src/common_traits.rs b/crates/bevy_math/src/common_traits.rs index a2bf190646c3e..6074f2526607d 100644 --- a/crates/bevy_math/src/common_traits.rs +++ b/crates/bevy_math/src/common_traits.rs @@ -21,10 +21,6 @@ use std::ops::{Add, Div, Mul, Neg, Sub}; /// /// Note that, because implementing types use floating point arithmetic, they are not required to actually /// implement `PartialEq` or `Eq`. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a vector space", - label = "invalid vector space" -)] pub trait VectorSpace: Mul + Div @@ -81,10 +77,6 @@ impl VectorSpace for f32 { /// /// Note that, because implementing types use floating point arithmetic, they are not required to actually /// implement `PartialEq` or `Eq`. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a normed vector space", - label = "invalid vector space" -)] pub trait NormedVectorSpace: VectorSpace { /// The size of this element. The return value should always be nonnegative. fn norm(self) -> f32; diff --git a/crates/bevy_math/src/cubic_splines.rs b/crates/bevy_math/src/cubic_splines.rs index 5eb2dfe68550a..a3343e55b65bb 100644 --- a/crates/bevy_math/src/cubic_splines.rs +++ b/crates/bevy_math/src/cubic_splines.rs @@ -621,10 +621,6 @@ impl CubicGenerator

for LinearSpline

{ } /// Implement this on cubic splines that can generate a cubic curve from their spline parameters. -#[diagnostic::on_unimplemented( - message = "`{Self}` can not generate a cubic curve", - label = "invalid generator" -)] pub trait CubicGenerator { /// Build a [`CubicCurve`] by computing the interpolation coefficients for each curve segment. fn to_curve(&self) -> CubicCurve

; @@ -915,10 +911,6 @@ impl IntoIterator for CubicCurve

{ } /// Implement this on cubic splines that can generate a rational cubic curve from their spline parameters. -#[diagnostic::on_unimplemented( - message = "`{Self}` can not generate a rational curve", - label = "invalid generator" -)] pub trait RationalGenerator { /// Build a [`RationalCurve`] by computing the interpolation coefficients for each curve segment. fn to_curve(&self) -> RationalCurve

; diff --git a/crates/bevy_math/src/primitives/mod.rs b/crates/bevy_math/src/primitives/mod.rs index d7b5a670647c9..460e635867ecb 100644 --- a/crates/bevy_math/src/primitives/mod.rs +++ b/crates/bevy_math/src/primitives/mod.rs @@ -10,17 +10,9 @@ pub use dim3::*; mod serde; /// A marker trait for 2D primitives -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a 2D primitive shape", - label = "invalid primitive" -)] pub trait Primitive2d {} /// A marker trait for 3D primitives -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a 3D primitive shape", - label = "invalid primitive" -)] pub trait Primitive3d {} /// The winding order for a set of points @@ -39,10 +31,6 @@ pub enum WindingOrder { } /// A trait for getting measurements of 2D shapes -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a measurable 2D shape", - label = "invalid shape" -)] pub trait Measured2d { /// Get the perimeter of the shape fn perimeter(&self) -> f32; @@ -52,10 +40,6 @@ pub trait Measured2d { } /// A trait for getting measurements of 3D shapes -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a measurable 3D shape", - label = "invalid shape" -)] pub trait Measured3d { /// Get the surface area of the shape fn area(&self) -> f32; diff --git a/crates/bevy_math/src/sampling/shape_sampling.rs b/crates/bevy_math/src/sampling/shape_sampling.rs index 7c147a756f2d2..3728034413bef 100644 --- a/crates/bevy_math/src/sampling/shape_sampling.rs +++ b/crates/bevy_math/src/sampling/shape_sampling.rs @@ -7,7 +7,6 @@ use rand::{ }; /// Exposes methods to uniformly sample a variety of primitive shapes. -#[diagnostic::on_unimplemented(message = "`{Self}` can not be sampled", label = "invalid shape")] pub trait ShapeSample { /// The type of vector returned by the sample methods, [`Vec2`] for 2D shapes and [`Vec3`] for 3D shapes. type Output; diff --git a/crates/bevy_math/src/sampling/standard.rs b/crates/bevy_math/src/sampling/standard.rs index 7e1557b8d5e95..255d9a07c2d0a 100644 --- a/crates/bevy_math/src/sampling/standard.rs +++ b/crates/bevy_math/src/sampling/standard.rs @@ -40,9 +40,6 @@ use rand::{ /// let mut rng = StdRng::from_entropy(); /// let random_dir = Dir3::from_rng(&mut rng); /// ``` -#[diagnostic::on_unimplemented( - message = "`{Self}` can not be generated from a random distribution" -)] pub trait FromRng where Self: Sized, diff --git a/crates/bevy_pbr/src/extended_material.rs b/crates/bevy_pbr/src/extended_material.rs index b8dc55b3609e1..aa77b51c625ab 100644 --- a/crates/bevy_pbr/src/extended_material.rs +++ b/crates/bevy_pbr/src/extended_material.rs @@ -27,10 +27,6 @@ pub struct MaterialExtensionKey { /// A subset of the `Material` trait for defining extensions to a base `Material`, such as the builtin `StandardMaterial`. /// A user type implementing the trait should be used as the `E` generic param in an `ExtendedMaterial` struct. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a valid material", - label = "invalid material" -)] pub trait MaterialExtension: Asset + AsBindGroup + Clone + Sized { /// Returns this material's vertex shader. If [`ShaderRef::Default`] is returned, the base material mesh vertex shader /// will be used. diff --git a/crates/bevy_pbr/src/light_probe/mod.rs b/crates/bevy_pbr/src/light_probe/mod.rs index 0fece70102cbd..964ffbc7c2a46 100644 --- a/crates/bevy_pbr/src/light_probe/mod.rs +++ b/crates/bevy_pbr/src/light_probe/mod.rs @@ -250,10 +250,6 @@ where /// Most light probe systems are written to be generic over the type of light /// probe. This allows much of the code to be shared and enables easy addition /// of more light probe types (e.g. real-time reflection planes) in the future. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a light probe", - label = "invalid light probe" -)] pub trait LightProbeComponent: Send + Sync + Component + Sized { /// Holds [`AssetId`]s of the texture or textures that this light probe /// references. diff --git a/crates/bevy_pbr/src/material.rs b/crates/bevy_pbr/src/material.rs index 4e27dc7122827..ede7b1672a9a0 100644 --- a/crates/bevy_pbr/src/material.rs +++ b/crates/bevy_pbr/src/material.rs @@ -99,10 +99,6 @@ use self::{irradiance_volume::IrradianceVolume, prelude::EnvironmentMapLight}; /// @group(2) @binding(1) var color_texture: texture_2d; /// @group(2) @binding(2) var color_sampler: sampler; /// ``` -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a valid material", - label = "invalid material" -)] pub trait Material: Asset + AsBindGroup + Clone + Sized { /// Returns this material's vertex shader. If [`ShaderRef::Default`] is returned, the default mesh vertex shader /// will be used. diff --git a/crates/bevy_pbr/src/meshlet/persistent_buffer.rs b/crates/bevy_pbr/src/meshlet/persistent_buffer.rs index 602044db5d972..60e163a87446a 100644 --- a/crates/bevy_pbr/src/meshlet/persistent_buffer.rs +++ b/crates/bevy_pbr/src/meshlet/persistent_buffer.rs @@ -109,10 +109,6 @@ impl PersistentGpuBuffer { } /// A trait representing data that can be written to a [`PersistentGpuBuffer`]. -#[diagnostic::on_unimplemented( - message = "`{Self}` can not be written to a persistent GPU buffer", - label = "invalid bufferable" -)] pub trait PersistentGpuBufferable { /// Additional metadata associated with each item, made available during `write_bytes_le`. type Metadata; diff --git a/crates/bevy_ptr/src/lib.rs b/crates/bevy_ptr/src/lib.rs index f97a82bf8c976..de12026377ab6 100644 --- a/crates/bevy_ptr/src/lib.rs +++ b/crates/bevy_ptr/src/lib.rs @@ -22,10 +22,6 @@ pub struct Unaligned; /// Trait that is only implemented for [`Aligned`] and [`Unaligned`] to work around the lack of ability /// to have const generics of an enum. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not an alignment option", - label = "invalid alignment" -)] pub trait IsAligned: sealed::Sealed {} impl IsAligned for Aligned {} impl IsAligned for Unaligned {} @@ -548,10 +544,6 @@ mod private { } /// Extension trait for helper methods on [`UnsafeCell`] -#[diagnostic::on_unimplemented( - message = "`{Self}` is not an UnsafeCell", - label = "invalid `UnsafeCell`" -)] pub trait UnsafeCellDeref<'a, T>: private::SealedUnsafeCell { /// # Safety /// - The returned value must be unique and not alias any mutable or immutable references to the contents of the [`UnsafeCell`]. diff --git a/crates/bevy_reflect/src/array.rs b/crates/bevy_reflect/src/array.rs index e6107680c5810..f5f1158c20f11 100644 --- a/crates/bevy_reflect/src/array.rs +++ b/crates/bevy_reflect/src/array.rs @@ -44,7 +44,6 @@ use std::{ /// [`GetTypeRegistration`]: crate::GetTypeRegistration /// [limitation]: https://github.com/serde-rs/serde/issues/1937 /// [`Deserialize`]: ::serde::Deserialize -#[diagnostic::on_unimplemented(message = "`{Self}` is not an array", label = "invalid array")] pub trait Array: Reflect { /// Returns a reference to the element at `index`, or `None` if out of bounds. fn get(&self, index: usize) -> Option<&dyn Reflect>; diff --git a/crates/bevy_reflect/src/enums/enum_trait.rs b/crates/bevy_reflect/src/enums/enum_trait.rs index 5cedcd773bc1e..66029923da25b 100644 --- a/crates/bevy_reflect/src/enums/enum_trait.rs +++ b/crates/bevy_reflect/src/enums/enum_trait.rs @@ -87,7 +87,6 @@ use std::slice::Iter; /// [`None`]: Option::None /// [`Some`]: Option::Some /// [`Reflect`]: bevy_reflect_derive::Reflect -#[diagnostic::on_unimplemented(message = "`{Self}` is not an enum", label = "invalid enum")] pub trait Enum: Reflect { /// Returns a reference to the value of the field (in the current variant) with the given name. /// diff --git a/crates/bevy_reflect/src/list.rs b/crates/bevy_reflect/src/list.rs index b5211a109b25f..5b786ee76a991 100644 --- a/crates/bevy_reflect/src/list.rs +++ b/crates/bevy_reflect/src/list.rs @@ -47,7 +47,6 @@ use crate::{ /// [list-like]: https://doc.rust-lang.org/book/ch08-01-vectors.html /// [reflection]: crate /// [type-erasing]: https://doc.rust-lang.org/book/ch17-02-trait-objects.html -#[diagnostic::on_unimplemented(message = "`{Self}` is not a list", label = "invalid list")] pub trait List: Reflect { /// Returns a reference to the element at `index`, or `None` if out of bounds. fn get(&self, index: usize) -> Option<&dyn Reflect>; diff --git a/crates/bevy_reflect/src/map.rs b/crates/bevy_reflect/src/map.rs index 432ce351925de..5b182c68a973a 100644 --- a/crates/bevy_reflect/src/map.rs +++ b/crates/bevy_reflect/src/map.rs @@ -40,7 +40,6 @@ use crate::{ /// /// [map-like]: https://doc.rust-lang.org/book/ch08-03-hash-maps.html /// [reflection]: crate -#[diagnostic::on_unimplemented(message = "`{Self}` is not a map", label = "invalid map")] pub trait Map: Reflect { /// Returns a reference to the value associated with the given key. /// diff --git a/crates/bevy_reflect/src/struct_trait.rs b/crates/bevy_reflect/src/struct_trait.rs index 408536e47ca51..5d134034691d6 100644 --- a/crates/bevy_reflect/src/struct_trait.rs +++ b/crates/bevy_reflect/src/struct_trait.rs @@ -43,7 +43,6 @@ use std::{ /// [reflection]: crate /// [unit structs]: https://doc.rust-lang.org/book/ch05-01-defining-structs.html#unit-like-structs-without-any-fields -#[diagnostic::on_unimplemented(message = "`{Self}` is not a struct", label = "invalid struct")] pub trait Struct: Reflect { /// Returns a reference to the value of the field named `name` as a `&dyn /// Reflect`. @@ -237,7 +236,6 @@ impl<'a> ExactSizeIterator for FieldIter<'a> {} /// assert_eq!(foo.get_field::("bar"), Some(&"Hello".to_string())); /// # } /// ``` -#[diagnostic::on_unimplemented(message = "`{Self}` is not a struct", label = "invalid struct")] pub trait GetField { /// Returns a reference to the value of the field named `name`, downcast to /// `T`. diff --git a/crates/bevy_reflect/src/tuple.rs b/crates/bevy_reflect/src/tuple.rs index b044458deb17d..cf111edcdfb99 100644 --- a/crates/bevy_reflect/src/tuple.rs +++ b/crates/bevy_reflect/src/tuple.rs @@ -33,7 +33,6 @@ use std::slice::Iter; /// /// [tuple-like]: https://doc.rust-lang.org/book/ch03-02-data-types.html#the-tuple-type /// [reflection]: crate -#[diagnostic::on_unimplemented(message = "`{Self}` is not a tuple", label = "invalid tuple")] pub trait Tuple: Reflect { /// Returns a reference to the value of the field with index `index` as a /// `&dyn Reflect`. @@ -103,7 +102,6 @@ impl<'a> ExactSizeIterator for TupleFieldIter<'a> {} /// assert_eq!(foo.get_field::(1), Some(&42)); /// # } /// ``` -#[diagnostic::on_unimplemented(message = "`{Self}` is not a tuple", label = "invalid tuple")] pub trait GetTupleField { /// Returns a reference to the value of the field with index `index`, /// downcast to `T`. diff --git a/crates/bevy_reflect/src/tuple_struct.rs b/crates/bevy_reflect/src/tuple_struct.rs index 2185fa01b5f15..8aeb103984029 100644 --- a/crates/bevy_reflect/src/tuple_struct.rs +++ b/crates/bevy_reflect/src/tuple_struct.rs @@ -34,10 +34,6 @@ use std::slice::Iter; /// /// [tuple struct-like]: https://doc.rust-lang.org/book/ch05-01-defining-structs.html#using-tuple-structs-without-named-fields-to-create-different-types /// [reflection]: crate -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a tuple struct", - label = "invalid tuple struct" -)] pub trait TupleStruct: Reflect { /// Returns a reference to the value of the field with index `index` as a /// `&dyn Reflect`. @@ -189,10 +185,6 @@ impl<'a> ExactSizeIterator for TupleStructFieldIter<'a> {} /// assert_eq!(foo.get_field::(0), Some(&"Hello".to_string())); /// # } /// ``` -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a tuple struct", - label = "invalid tuple struct" -)] pub trait GetTupleStructField { /// Returns a reference to the value of the field with index `index`, /// downcast to `T`. diff --git a/crates/bevy_render/src/camera/projection.rs b/crates/bevy_render/src/camera/projection.rs index 3d0268e3a3a8c..c8495ffbf39d1 100644 --- a/crates/bevy_render/src/camera/projection.rs +++ b/crates/bevy_render/src/camera/projection.rs @@ -74,7 +74,6 @@ pub struct CameraUpdateSystem; /// systems for your [`CameraProjection`] implementation. /// /// [`Camera`]: crate::camera::Camera -#[diagnostic::on_unimplemented(message = "`{Self}` is not a camera", label = "invalid camera")] pub trait CameraProjection { fn get_projection_matrix(&self) -> Mat4; fn update(&mut self, width: f32, height: f32); diff --git a/crates/bevy_render/src/extract_component.rs b/crates/bevy_render/src/extract_component.rs index 9e7c668e15705..4b327cf6af3e8 100644 --- a/crates/bevy_render/src/extract_component.rs +++ b/crates/bevy_render/src/extract_component.rs @@ -34,10 +34,6 @@ impl DynamicUniformIndex { /// /// Therefore the component is transferred from the "app world" into the "render world" /// in the [`ExtractSchedule`] step. -#[diagnostic::on_unimplemented( - message = "`{Self}` can not be extracted for rendering", - label = "invalid component" -)] pub trait ExtractComponent: Component { /// ECS [`ReadOnlyQueryData`] to fetch the components to extract. type QueryData: ReadOnlyQueryData; diff --git a/crates/bevy_render/src/extract_instances.rs b/crates/bevy_render/src/extract_instances.rs index b3b59ca1788c4..537ca5f11e439 100644 --- a/crates/bevy_render/src/extract_instances.rs +++ b/crates/bevy_render/src/extract_instances.rs @@ -27,10 +27,6 @@ use crate::{prelude::ViewVisibility, Extract, ExtractSchedule, RenderApp}; /// This is essentially the same as /// [`ExtractComponent`](crate::extract_component::ExtractComponent), but /// higher-performance because it avoids the ECS overhead. -#[diagnostic::on_unimplemented( - message = "`{Self}` can not be extracted for rendering", - label = "invalid target" -)] pub trait ExtractInstance: Send + Sync + Sized + 'static { /// ECS [`ReadOnlyQueryData`] to fetch the components to extract. type QueryData: ReadOnlyQueryData; diff --git a/crates/bevy_render/src/extract_resource.rs b/crates/bevy_render/src/extract_resource.rs index dd75c4c961ffc..63a6c42dc4a20 100644 --- a/crates/bevy_render/src/extract_resource.rs +++ b/crates/bevy_render/src/extract_resource.rs @@ -10,10 +10,6 @@ use crate::{Extract, ExtractSchedule, RenderApp}; /// /// Therefore the resource is transferred from the "main world" into the "render world" /// in the [`ExtractSchedule`] step. -#[diagnostic::on_unimplemented( - message = "`{Self}` can not be extracted for rendering", - label = "invalid resource" -)] pub trait ExtractResource: Resource { type Source: Resource; diff --git a/crates/bevy_render/src/mesh/primitives/mod.rs b/crates/bevy_render/src/mesh/primitives/mod.rs index 8632dcff72754..a2bb01599b4ee 100644 --- a/crates/bevy_render/src/mesh/primitives/mod.rs +++ b/crates/bevy_render/src/mesh/primitives/mod.rs @@ -26,10 +26,6 @@ mod dim3; pub use dim3::*; /// A trait for shapes that can be turned into a [`Mesh`](super::Mesh). -#[diagnostic::on_unimplemented( - message = "`{Self}` can not be turned into a mesh", - label = "invalid meshable" -)] pub trait Meshable { /// The output of [`Self::mesh`]. This can either be a [`Mesh`](super::Mesh) /// or a builder used for creating a [`Mesh`](super::Mesh). diff --git a/crates/bevy_render/src/render_asset.rs b/crates/bevy_render/src/render_asset.rs index 9be674de343cd..e3a6aab5fb637 100644 --- a/crates/bevy_render/src/render_asset.rs +++ b/crates/bevy_render/src/render_asset.rs @@ -27,10 +27,6 @@ pub enum PrepareAssetError { /// /// After that in the [`RenderSet::PrepareAssets`] step the extracted asset /// is transformed into its GPU-representation of type [`RenderAsset`]. -#[diagnostic::on_unimplemented( - message = "`{Self}` can not be extracted for rendering", - label = "invalid asset" -)] pub trait RenderAsset: Send + Sync + 'static + Sized { /// The representation of the asset in the "main world". type SourceAsset: Asset + Clone; diff --git a/crates/bevy_render/src/render_graph/app.rs b/crates/bevy_render/src/render_graph/app.rs index 5e5961c046e1b..80ffcdb2a1f8d 100644 --- a/crates/bevy_render/src/render_graph/app.rs +++ b/crates/bevy_render/src/render_graph/app.rs @@ -5,7 +5,6 @@ use bevy_utils::tracing::warn; use super::{IntoRenderNodeArray, Node, RenderGraph, RenderLabel, RenderSubGraph}; /// Adds common [`RenderGraph`] operations to [`SubApp`] (and [`App`]). -#[diagnostic::on_unimplemented(message = "`{Self}` is not an App", label = "invalid `App`")] pub trait RenderGraphApp { // Add a sub graph to the [`RenderGraph`] fn add_render_sub_graph(&mut self, sub_graph: impl RenderSubGraph) -> &mut Self; diff --git a/crates/bevy_render/src/render_graph/node.rs b/crates/bevy_render/src/render_graph/node.rs index 2108a20c6034e..5bff05ca88fa1 100644 --- a/crates/bevy_render/src/render_graph/node.rs +++ b/crates/bevy_render/src/render_graph/node.rs @@ -60,10 +60,6 @@ all_tuples_with_size!(impl_render_label_tuples, 1, 32, T, l); /// A node can produce outputs used as dependencies by other nodes. /// Those inputs and outputs are called slots and are the default way of passing render data /// inside the graph. For more information see [`SlotType`](super::SlotType). -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a render graph node", - label = "invalid node" -)] pub trait Node: Downcast + Send + Sync + 'static { /// Specifies the required input slots for this node. /// They will then be available during the run method inside the [`RenderGraphContext`]. @@ -341,10 +337,6 @@ impl Node for RunGraphOnViewNode { /// This trait should be used instead of the [`Node`] trait when making a render node that runs on a view. /// /// It is intended to be used with [`ViewNodeRunner`]' -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a render graph view node", - label = "invalid node" -)] pub trait ViewNode { /// The query that will be used on the view entity. /// It is guaranteed to run on the view entity, so there's no need for a filter diff --git a/crates/bevy_render/src/render_phase/draw.rs b/crates/bevy_render/src/render_phase/draw.rs index b6a028d9d4f50..980899b64bc44 100644 --- a/crates/bevy_render/src/render_phase/draw.rs +++ b/crates/bevy_render/src/render_phase/draw.rs @@ -20,10 +20,6 @@ use std::{ /// /// This trait can either be implemented directly or implicitly composed out of multiple modular /// [`RenderCommand`]s. For more details and an example see the [`RenderCommand`] documentation. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a valid draw operation", - label = "invalid draw" -)] pub trait Draw: Send + Sync + 'static { /// Prepares the draw function to be used. This is called once and only once before the phase /// begins. There may be zero or more [`draw`](Draw::draw) calls following a call to this function. @@ -171,10 +167,6 @@ impl DrawFunctions

{ /// DrawMesh, /// ); /// ``` -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a render command", - label = "invalid command" -)] pub trait RenderCommand { /// Specifies the general ECS data (e.g. resources) required by [`RenderCommand::render`]. /// @@ -309,7 +301,6 @@ where /// Registers a [`RenderCommand`] as a [`Draw`] function. /// They are stored inside the [`DrawFunctions`] resource of the app. -#[diagnostic::on_unimplemented(message = "`{Self}` is not an App", label = "invalid `App`")] pub trait AddRenderCommand { /// Adds the [`RenderCommand`] for the specified render phase to the app. fn add_render_command + Send + Sync + 'static>( diff --git a/crates/bevy_render/src/render_phase/mod.rs b/crates/bevy_render/src/render_phase/mod.rs index 174048bcb9d91..a1125fa938e2c 100644 --- a/crates/bevy_render/src/render_phase/mod.rs +++ b/crates/bevy_render/src/render_phase/mod.rs @@ -642,7 +642,6 @@ where /// and then sorted all at once. This is needed for transparent meshes, which /// have to be sorted back-to-front to render with the painter's algorithm. /// These types of phase items are generally slower than binned phase items. -#[diagnostic::on_unimplemented(message = "`{Self}` is not a phase item", label = "invalid item")] pub trait PhaseItem: Sized + Send + Sync + 'static { /// Whether or not this `PhaseItem` should be subjected to automatic batching. (Default: `true`) const AUTOMATIC_BATCHING: bool = true; @@ -809,10 +808,6 @@ impl PhaseItemExtraIndex { /// /// An example of a binned phase item is `Opaque3d`, for which the rendering /// order isn't critical. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a binned phase item", - label = "invalid item" -)] pub trait BinnedPhaseItem: PhaseItem { /// The key used for binning [`PhaseItem`]s into bins. Order the members of /// [`BinnedPhaseItem::BinKey`] by the order of binding for best @@ -841,10 +836,6 @@ pub trait BinnedPhaseItem: PhaseItem { /// /// An example of a sorted phase item is `Transparent3d`, which must be sorted /// back to front in order to correctly render with the painter's algorithm. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a sorted phase item", - label = "invalid item" -)] pub trait SortedPhaseItem: PhaseItem { /// The type used for ordering the items. The smallest values are drawn first. /// This order can be calculated using the [`ViewRangefinder3d`], @@ -876,10 +867,6 @@ pub trait SortedPhaseItem: PhaseItem { /// cached in the [`PipelineCache`]. /// /// You can use the [`SetItemPipeline`] render command to set the pipeline for this item. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a cached phase item", - label = "invalid item" -)] pub trait CachedRenderPipelinePhaseItem: PhaseItem { /// The id of the render pipeline, cached in the [`PipelineCache`], that will be used to draw /// this phase item. diff --git a/crates/bevy_render/src/render_resource/bind_group.rs b/crates/bevy_render/src/render_resource/bind_group.rs index 344a203578bc1..ff61060ce796d 100644 --- a/crates/bevy_render/src/render_resource/bind_group.rs +++ b/crates/bevy_render/src/render_resource/bind_group.rs @@ -280,10 +280,6 @@ impl Deref for BindGroup { /// } /// } /// ``` -#[diagnostic::on_unimplemented( - message = "`{Self}` can not be used as a bind group", - label = "invalid bind group" -)] pub trait AsBindGroup { /// Data that will be stored alongside the "prepared" bind group. type Data: Send + Sync; diff --git a/crates/bevy_render/src/render_resource/gpu_array_buffer.rs b/crates/bevy_render/src/render_resource/gpu_array_buffer.rs index 26a6fd4ec57f5..9765cfc627adc 100644 --- a/crates/bevy_render/src/render_resource/gpu_array_buffer.rs +++ b/crates/bevy_render/src/render_resource/gpu_array_buffer.rs @@ -13,10 +13,6 @@ use std::marker::PhantomData; use wgpu::{BindingResource, BufferUsages}; /// Trait for types able to go in a [`GpuArrayBuffer`]. -#[diagnostic::on_unimplemented( - message = "`{Self}` can not be used in a GPU array buffer", - label = "invalid bufferable" -)] pub trait GpuArrayBufferable: ShaderType + ShaderSize + WriteInto + Clone {} impl GpuArrayBufferable for T {} diff --git a/crates/bevy_render/src/texture/image.rs b/crates/bevy_render/src/texture/image.rs index e1b568db40363..4b0a46bd3a7bc 100644 --- a/crates/bevy_render/src/texture/image.rs +++ b/crates/bevy_render/src/texture/image.rs @@ -787,10 +787,6 @@ impl<'a> ImageType<'a> { } /// Used to calculate the volume of an item. -#[diagnostic::on_unimplemented( - message = "`{Self}` does not a definition for volume", - label = "invalid volume" -)] pub trait Volume { fn volume(&self) -> usize; } @@ -803,10 +799,6 @@ impl Volume for Extent3d { } /// Extends the wgpu [`TextureFormat`] with information about the pixel. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a `TextureFormat`", - label = "invalid `TextureFormat`" -)] pub trait TextureFormatPixelInfo { /// Returns the size of a pixel in bytes of the format. fn pixel_size(&self) -> usize; diff --git a/crates/bevy_sprite/src/mesh2d/material.rs b/crates/bevy_sprite/src/mesh2d/material.rs index 6e16845ad6624..d58083763aeaa 100644 --- a/crates/bevy_sprite/src/mesh2d/material.rs +++ b/crates/bevy_sprite/src/mesh2d/material.rs @@ -102,10 +102,6 @@ use crate::{ /// @group(2) @binding(1) var color_texture: texture_2d; /// @group(2) @binding(2) var color_sampler: sampler; /// ``` -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a 2D material", - label = "invalid material" -)] pub trait Material2d: AsBindGroup + Asset + Clone + Sized { /// Returns this material's vertex shader. If [`ShaderRef::Default`] is returned, the default mesh vertex shader /// will be used. diff --git a/crates/bevy_state/src/state/computed_states.rs b/crates/bevy_state/src/state/computed_states.rs index 0ca0b889598aa..fda0f99d8c821 100644 --- a/crates/bevy_state/src/state/computed_states.rs +++ b/crates/bevy_state/src/state/computed_states.rs @@ -68,10 +68,6 @@ use super::states::States; /// .init_state::() /// .add_computed_state::(); /// ``` -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a computed state", - label = "invalid state" -)] pub trait ComputedStates: 'static + Send + Sync + Clone + PartialEq + Eq + Hash + Debug { /// The set of states from which the [`Self`] is derived. /// diff --git a/crates/bevy_state/src/state/state_set.rs b/crates/bevy_state/src/state/state_set.rs index 73d566d953130..067711829dbf0 100644 --- a/crates/bevy_state/src/state/state_set.rs +++ b/crates/bevy_state/src/state/state_set.rs @@ -27,10 +27,6 @@ mod sealed { /// /// It is sealed, and auto implemented for all [`States`] types and /// tuples containing them. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a state set", - label = "invalid state set" -)] pub trait StateSet: sealed::StateSetSealed { /// The total [`DEPENDENCY_DEPTH`](`States::DEPENDENCY_DEPTH`) of all /// the states that are part of this [`StateSet`], added together. diff --git a/crates/bevy_tasks/src/iter/mod.rs b/crates/bevy_tasks/src/iter/mod.rs index 0624dd178b3d8..6887fa05440a1 100644 --- a/crates/bevy_tasks/src/iter/mod.rs +++ b/crates/bevy_tasks/src/iter/mod.rs @@ -11,10 +11,6 @@ pub use adapters::*; /// run in parallel is inexpensive, *a [`ParallelIterator`] could take longer /// than a normal [`Iterator`]*. Therefore, you should profile your code before /// using [`ParallelIterator`]. -#[diagnostic::on_unimplemented( - message = "`{Self}` can not be iterated in parallel", - label = "invalid iterator" -)] pub trait ParallelIterator where BatchIter: Iterator + Send, diff --git a/crates/bevy_tasks/src/slice.rs b/crates/bevy_tasks/src/slice.rs index 54ad85c4849ab..93568fd15dad0 100644 --- a/crates/bevy_tasks/src/slice.rs +++ b/crates/bevy_tasks/src/slice.rs @@ -1,7 +1,6 @@ use super::TaskPool; /// Provides functions for mapping read-only slices across a provided [`TaskPool`]. -#[diagnostic::on_unimplemented(message = "`{Self}` can not be sliced in parallel")] pub trait ParallelSlice: AsRef<[T]> { /// Splits the slice in chunks of size `chunks_size` or less and maps the chunks /// in parallel across the provided `task_pool`. One task is spawned in the task pool @@ -102,7 +101,6 @@ pub trait ParallelSlice: AsRef<[T]> { impl ParallelSlice for S where S: AsRef<[T]> {} /// Provides functions for mapping mutable slices across a provided [`TaskPool`]. -#[diagnostic::on_unimplemented(message = "`{Self}` can not be mutably sliced in parallel")] pub trait ParallelSliceMut: AsMut<[T]> { /// Splits the slice in chunks of size `chunks_size` or less and maps the chunks /// in parallel across the provided `task_pool`. One task is spawned in the task pool diff --git a/crates/bevy_ui/src/measurement.rs b/crates/bevy_ui/src/measurement.rs index 70a606b5c14d5..b482bd01aa759 100644 --- a/crates/bevy_ui/src/measurement.rs +++ b/crates/bevy_ui/src/measurement.rs @@ -18,7 +18,6 @@ impl std::fmt::Debug for ContentSize { /// A `Measure` is used to compute the size of a ui node /// when the size of that node is based on its content. -#[diagnostic::on_unimplemented(message = "`{Self}` can not be measured", label = "invalid UI node")] pub trait Measure: Send + Sync + 'static { /// Calculate the size of the node given the constraints. fn measure( diff --git a/crates/bevy_ui/src/ui_material.rs b/crates/bevy_ui/src/ui_material.rs index 99f9269a2032d..dfeb3ee4c19ce 100644 --- a/crates/bevy_ui/src/ui_material.rs +++ b/crates/bevy_ui/src/ui_material.rs @@ -90,10 +90,6 @@ use bevy_render::render_resource::{AsBindGroup, RenderPipelineDescriptor, Shader /// /// } /// ``` -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a UI material", - label = "invalid material" -)] pub trait UiMaterial: AsBindGroup + Asset + Clone + Sized { /// Returns this materials vertex shader. If [`ShaderRef::Default`] is returned, the default UI /// vertex shader will be used. From a3a9df93d43d4e1058f471d8d5718a6f9d692c89 Mon Sep 17 00:00:00 2001 From: Zac Harrold Date: Tue, 14 May 2024 11:23:15 +1000 Subject: [PATCH 3/7] Update `Reflect` related `on_unimplemented` messages Removed redundant messages and provided hints towards `derive` macros where appropriate. --- crates/bevy_reflect/src/from_reflect.rs | 5 ++++- crates/bevy_reflect/src/path/mod.rs | 4 ---- crates/bevy_reflect/src/type_info.rs | 5 ++++- crates/bevy_reflect/src/type_path.rs | 5 +++-- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/crates/bevy_reflect/src/from_reflect.rs b/crates/bevy_reflect/src/from_reflect.rs index 3d2ff662e408a..805bcf05e4320 100644 --- a/crates/bevy_reflect/src/from_reflect.rs +++ b/crates/bevy_reflect/src/from_reflect.rs @@ -21,7 +21,10 @@ use crate::{FromType, Reflect}; /// [derive macro]: bevy_reflect_derive::FromReflect /// [`DynamicStruct`]: crate::DynamicStruct /// [crate-level documentation]: crate -#[diagnostic::on_unimplemented(message = "`{Self}` can not be created from a reflection")] +#[diagnostic::on_unimplemented( + message = "`{Self}` can not be created from a reflection", + note = "consider annotating `{Self}` with `#[derive(FromReflect)]`" +)] pub trait FromReflect: Reflect + Sized { /// Constructs a concrete instance of `Self` from a reflected value. fn from_reflect(reflect: &dyn Reflect) -> Option; diff --git a/crates/bevy_reflect/src/path/mod.rs b/crates/bevy_reflect/src/path/mod.rs index 2a002f8b54ece..468840eda6576 100644 --- a/crates/bevy_reflect/src/path/mod.rs +++ b/crates/bevy_reflect/src/path/mod.rs @@ -44,10 +44,6 @@ impl<'a> From> for ReflectPathError<'a> { } /// Something that can be interpreted as a reflection path in [`GetPath`]. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a reflection path", - label = "invalid path" -)] pub trait ReflectPath<'a>: Sized { /// Gets a reference to the specified element on the given [`Reflect`] object. /// diff --git a/crates/bevy_reflect/src/type_info.rs b/crates/bevy_reflect/src/type_info.rs index 82e2b89132074..aef223cd43deb 100644 --- a/crates/bevy_reflect/src/type_info.rs +++ b/crates/bevy_reflect/src/type_info.rs @@ -70,7 +70,10 @@ use std::fmt::Debug; /// ``` /// /// [utility]: crate::utility -#[diagnostic::on_unimplemented(message = "`{Self}` can not be typed through reflection")] +#[diagnostic::on_unimplemented( + message = "`{Self}` can not be typed through reflection", + note = "consider annotating `{Self}` with `#[derive(Reflect)]`" +)] pub trait Typed: Reflect + TypePath { /// Returns the compile-time [info] for the underlying type. /// diff --git a/crates/bevy_reflect/src/type_path.rs b/crates/bevy_reflect/src/type_path.rs index b7bd8f0c292e9..1ea8a7b9eaa8a 100644 --- a/crates/bevy_reflect/src/type_path.rs +++ b/crates/bevy_reflect/src/type_path.rs @@ -82,7 +82,7 @@ use std::fmt; #[diagnostic::on_unimplemented( message = "`{Self}` does not have a type path", label = "invalid type", - note = "consider annotating `{Self}` with `#[derive(TypePath)]`" + note = "consider annotating `{Self}` with `#[derive(Reflect)]` or `#[derive(TypePath)]`" )] pub trait TypePath: 'static { /// Returns the fully qualified path of the underlying type. @@ -136,7 +136,8 @@ pub trait TypePath: 'static { /// [`Reflect`]: crate::Reflect #[diagnostic::on_unimplemented( message = "`{Self}` can not be used as a dynamic type path", - label = "invalid type" + label = "invalid type", + note = "consider annotating `{Self}` with `#[derive(Reflect)]` or `#[derive(TypePath)]`" )] pub trait DynamicTypePath { /// See [`TypePath::type_path`]. From ec8780aadd0244a288a952f1589610d32875e52e Mon Sep 17 00:00:00 2001 From: Zac Harrold Date: Wed, 15 May 2024 09:16:12 +1000 Subject: [PATCH 4/7] Updated `on_unimplemented` Messages --- crates/bevy_asset/src/lib.rs | 4 ++-- crates/bevy_ecs/src/bundle.rs | 5 +++++ crates/bevy_ecs/src/component.rs | 4 ++-- crates/bevy_ecs/src/event.rs | 4 ++-- crates/bevy_ecs/src/query/fetch.rs | 2 +- crates/bevy_ecs/src/query/filter.rs | 4 ++-- crates/bevy_ecs/src/system/mod.rs | 5 ++--- crates/bevy_ecs/src/system/system_param.rs | 4 ++-- crates/bevy_reflect/src/path/mod.rs | 1 - crates/bevy_reflect/src/type_path.rs | 2 -- crates/bevy_reflect/src/type_registry.rs | 1 - crates/bevy_state/src/state/freely_mutable_state.rs | 4 ++-- 12 files changed, 20 insertions(+), 20 deletions(-) diff --git a/crates/bevy_asset/src/lib.rs b/crates/bevy_asset/src/lib.rs index 248d6c7eb5531..f6fd2ae42be3b 100644 --- a/crates/bevy_asset/src/lib.rs +++ b/crates/bevy_asset/src/lib.rs @@ -224,8 +224,8 @@ impl Plugin for AssetPlugin { } #[diagnostic::on_unimplemented( - message = "`{Self}` is not an asset", - label = "invalid asset", + message = "`{Self}` is not an `Asset`", + label = "invalid `Asset`", note = "consider annotating `{Self}` with `#[derive(Asset)]`" )] pub trait Asset: VisitAssetDependencies + TypePath + Send + Sync + 'static {} diff --git a/crates/bevy_ecs/src/bundle.rs b/crates/bevy_ecs/src/bundle.rs index 7ba65e9ba42cd..718a9356440f8 100644 --- a/crates/bevy_ecs/src/bundle.rs +++ b/crates/bevy_ecs/src/bundle.rs @@ -141,6 +141,11 @@ use std::ptr::NonNull; // bundle, in the _exact_ order that [`DynamicBundle::get_components`] is called. // - [`Bundle::from_components`] must call `func` exactly once for each [`ComponentId`] returned by // [`Bundle::component_ids`]. +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a `Bundle`", + label = "invalid `Bundle`", + note = "consider annotating `{Self}` with `#[derive(Component)]` or `#[derive(Bundle)]`" +)] pub unsafe trait Bundle: DynamicBundle + Send + Sync + 'static { /// Gets this [`Bundle`]'s component ids, in the order of this bundle's [`Component`]s #[doc(hidden)] diff --git a/crates/bevy_ecs/src/component.rs b/crates/bevy_ecs/src/component.rs index 5eb2a478b7674..7f30eebdc9180 100644 --- a/crates/bevy_ecs/src/component.rs +++ b/crates/bevy_ecs/src/component.rs @@ -151,8 +151,8 @@ use std::{ /// [`SyncCell`]: bevy_utils::synccell::SyncCell /// [`Exclusive`]: https://doc.rust-lang.org/nightly/std/sync/struct.Exclusive.html #[diagnostic::on_unimplemented( - message = "`{Self}` is not a component", - label = "invalid component", + message = "`{Self}` is not a `Component`", + label = "invalid `Component`", note = "consider annotating `{Self}` with `#[derive(Component)]`" )] pub trait Component: Send + Sync + 'static { diff --git a/crates/bevy_ecs/src/event.rs b/crates/bevy_ecs/src/event.rs index 5ac71831caaab..871dd3af21e62 100644 --- a/crates/bevy_ecs/src/event.rs +++ b/crates/bevy_ecs/src/event.rs @@ -29,8 +29,8 @@ use std::{ /// /// Events must be thread-safe. #[diagnostic::on_unimplemented( - message = "`{Self}` is not an event", - label = "invalid event", + message = "`{Self}` is not an `Event`", + label = "invalid `Event`", note = "consider annotating `{Self}` with `#[derive(Event]`" )] pub trait Event: Send + Sync + 'static {} diff --git a/crates/bevy_ecs/src/query/fetch.rs b/crates/bevy_ecs/src/query/fetch.rs index c9dc833dda648..94ff3cae70e82 100644 --- a/crates/bevy_ecs/src/query/fetch.rs +++ b/crates/bevy_ecs/src/query/fetch.rs @@ -270,7 +270,7 @@ use std::{cell::UnsafeCell, marker::PhantomData}; /// [`ReadOnly`]: Self::ReadOnly #[diagnostic::on_unimplemented( message = "`{Self}` is not valid `Query` data", - label = "invalid query data" + label = "invalid `Query` data" )] pub unsafe trait QueryData: WorldQuery { /// The read-only variant of this [`QueryData`], which satisfies the [`ReadOnlyQueryData`] trait. diff --git a/crates/bevy_ecs/src/query/filter.rs b/crates/bevy_ecs/src/query/filter.rs index a78e21d81d701..22b01c450144d 100644 --- a/crates/bevy_ecs/src/query/filter.rs +++ b/crates/bevy_ecs/src/query/filter.rs @@ -72,7 +72,7 @@ use std::{cell::UnsafeCell, marker::PhantomData}; /// [`State`]: Self::State #[diagnostic::on_unimplemented( message = "`{Self}` is not a valid `Query` filter", - label = "invalid query filter" + label = "invalid `Query` filter" )] pub trait QueryFilter: WorldQuery { /// Returns true if (and only if) this Filter relies strictly on archetypes to limit which @@ -943,7 +943,7 @@ impl QueryFilter for Changed { /// they do not implement [`ArchetypeFilter`]. #[diagnostic::on_unimplemented( message = "`{Self}` is not an archetypical filter", - label = "invalid filter" + label = "invalid `Query` filter" )] pub trait ArchetypeFilter: QueryFilter {} diff --git a/crates/bevy_ecs/src/system/mod.rs b/crates/bevy_ecs/src/system/mod.rs index a6b06061939a5..c1fb76ed26c98 100644 --- a/crates/bevy_ecs/src/system/mod.rs +++ b/crates/bevy_ecs/src/system/mod.rs @@ -148,9 +148,8 @@ use crate::world::World; // because Rust thinks a type could impl multiple different `FnMut` combinations // even though none can currently #[diagnostic::on_unimplemented( - message = "`{Self}` is not a valid system", - label = "invalid system", - note = "expecting a system which consumes `{In}` and produces `{Out}`" + message = "`{Self}` is not a valid system with input `{In}` and output `{Out}`", + label = "invalid system" )] pub trait IntoSystem: Sized { /// The type of [`System`] that this instance converts into. diff --git a/crates/bevy_ecs/src/system/system_param.rs b/crates/bevy_ecs/src/system/system_param.rs index de328ca45333d..0390e9981e5e1 100644 --- a/crates/bevy_ecs/src/system/system_param.rs +++ b/crates/bevy_ecs/src/system/system_param.rs @@ -433,8 +433,8 @@ impl_param_set!(); /// /// [`Exclusive`]: https://doc.rust-lang.org/nightly/std/sync/struct.Exclusive.html #[diagnostic::on_unimplemented( - message = "`{Self}` is not a resource", - label = "invalid Resource", + message = "`{Self}` is not a `Resource`", + label = "invalid `Resource`", note = "consider annotating `{Self}` with `#[derive(Resource)]`" )] pub trait Resource: Send + Sync + 'static {} diff --git a/crates/bevy_reflect/src/path/mod.rs b/crates/bevy_reflect/src/path/mod.rs index 468840eda6576..6a38faad59595 100644 --- a/crates/bevy_reflect/src/path/mod.rs +++ b/crates/bevy_reflect/src/path/mod.rs @@ -232,7 +232,6 @@ impl<'a> ReflectPath<'a> for &'a str { /// [`Enum`]: crate::Enum #[diagnostic::on_unimplemented( message = "`{Self}` does not provide a reflection path", - label = "invalid type", note = "consider annotating `{Self}` with `#[derive(Reflect)]`" )] pub trait GetPath: Reflect { diff --git a/crates/bevy_reflect/src/type_path.rs b/crates/bevy_reflect/src/type_path.rs index 1ea8a7b9eaa8a..dd2e18cc12486 100644 --- a/crates/bevy_reflect/src/type_path.rs +++ b/crates/bevy_reflect/src/type_path.rs @@ -81,7 +81,6 @@ use std::fmt; /// [`type_ident`]: TypePath::type_ident #[diagnostic::on_unimplemented( message = "`{Self}` does not have a type path", - label = "invalid type", note = "consider annotating `{Self}` with `#[derive(Reflect)]` or `#[derive(TypePath)]`" )] pub trait TypePath: 'static { @@ -136,7 +135,6 @@ pub trait TypePath: 'static { /// [`Reflect`]: crate::Reflect #[diagnostic::on_unimplemented( message = "`{Self}` can not be used as a dynamic type path", - label = "invalid type", note = "consider annotating `{Self}` with `#[derive(Reflect)]` or `#[derive(TypePath)]`" )] pub trait DynamicTypePath { diff --git a/crates/bevy_reflect/src/type_registry.rs b/crates/bevy_reflect/src/type_registry.rs index 5ebcd7efb45a5..5db83589d320e 100644 --- a/crates/bevy_reflect/src/type_registry.rs +++ b/crates/bevy_reflect/src/type_registry.rs @@ -58,7 +58,6 @@ impl Debug for TypeRegistryArc { /// [crate-level documentation]: crate #[diagnostic::on_unimplemented( message = "`{Self}` does not provide type registration information", - label = "invalid type", note = "consider annotating `{Self}` with `#[derive(Reflect)]`" )] pub trait GetTypeRegistration: 'static { diff --git a/crates/bevy_state/src/state/freely_mutable_state.rs b/crates/bevy_state/src/state/freely_mutable_state.rs index adec59b50b66c..3a2393b1e860d 100644 --- a/crates/bevy_state/src/state/freely_mutable_state.rs +++ b/crates/bevy_state/src/state/freely_mutable_state.rs @@ -10,8 +10,8 @@ use super::transitions::*; /// While ordinary states are freely mutable (and implement this trait as part of their derive macro), /// computed states are not: instead, they can *only* change when the states that drive them do. #[diagnostic::on_unimplemented( - message = "`{Self}` is not a mutable state", - label = "invalid state", + message = "`{Self}` is not a `FreelyMutableState`", + label = "invalid `FreelyMutableState`", note = "consider annotating `{Self}` with `#[derive(States)]`" )] pub trait FreelyMutableState: States { From 188d5384aee368b7601c85be1124256621ed929b Mon Sep 17 00:00:00 2001 From: Zac Harrold Date: Wed, 15 May 2024 16:49:58 +1000 Subject: [PATCH 5/7] Updated wording based on feedback Co-Authored-By: Jamie Ridding --- crates/bevy_reflect/src/from_reflect.rs | 2 +- crates/bevy_reflect/src/type_info.rs | 2 +- crates/bevy_state/src/state/freely_mutable_state.rs | 6 +----- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/crates/bevy_reflect/src/from_reflect.rs b/crates/bevy_reflect/src/from_reflect.rs index 805bcf05e4320..aacb7d9d2516f 100644 --- a/crates/bevy_reflect/src/from_reflect.rs +++ b/crates/bevy_reflect/src/from_reflect.rs @@ -22,7 +22,7 @@ use crate::{FromType, Reflect}; /// [`DynamicStruct`]: crate::DynamicStruct /// [crate-level documentation]: crate #[diagnostic::on_unimplemented( - message = "`{Self}` can not be created from a reflection", + message = "`{Self}` can not be created through reflection", note = "consider annotating `{Self}` with `#[derive(FromReflect)]`" )] pub trait FromReflect: Reflect + Sized { diff --git a/crates/bevy_reflect/src/type_info.rs b/crates/bevy_reflect/src/type_info.rs index aef223cd43deb..1f68dbb7d0fa0 100644 --- a/crates/bevy_reflect/src/type_info.rs +++ b/crates/bevy_reflect/src/type_info.rs @@ -71,7 +71,7 @@ use std::fmt::Debug; /// /// [utility]: crate::utility #[diagnostic::on_unimplemented( - message = "`{Self}` can not be typed through reflection", + message = "`{Self}` can not provide type information through reflection", note = "consider annotating `{Self}` with `#[derive(Reflect)]`" )] pub trait Typed: Reflect + TypePath { diff --git a/crates/bevy_state/src/state/freely_mutable_state.rs b/crates/bevy_state/src/state/freely_mutable_state.rs index 3a2393b1e860d..88b5d901b5148 100644 --- a/crates/bevy_state/src/state/freely_mutable_state.rs +++ b/crates/bevy_state/src/state/freely_mutable_state.rs @@ -9,11 +9,7 @@ use super::transitions::*; /// /// While ordinary states are freely mutable (and implement this trait as part of their derive macro), /// computed states are not: instead, they can *only* change when the states that drive them do. -#[diagnostic::on_unimplemented( - message = "`{Self}` is not a `FreelyMutableState`", - label = "invalid `FreelyMutableState`", - note = "consider annotating `{Self}` with `#[derive(States)]`" -)] +#[diagnostic::on_unimplemented(note = "consider annotating `{Self}` with `#[derive(States)]`")] pub trait FreelyMutableState: States { /// This function registers all the necessary systems to apply state changes and run transition schedules fn register_state(schedule: &mut Schedule) { From 2541e458f57a7ae6c2b9826b588e9c42c0e0d5bd Mon Sep 17 00:00:00 2001 From: Zac Harrold Date: Thu, 16 May 2024 09:37:32 +1000 Subject: [PATCH 6/7] Updated Wording Based on Feedback Co-Authored-By: Alice Cecile Co-Authored-By: Jamie Ridding --- crates/bevy_ecs/src/query/fetch.rs | 2 +- crates/bevy_ecs/src/query/filter.rs | 8 +++++--- crates/bevy_ecs/src/system/combinator.rs | 3 ++- crates/bevy_ecs/src/system/function_system.rs | 5 ++++- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/crates/bevy_ecs/src/query/fetch.rs b/crates/bevy_ecs/src/query/fetch.rs index dfb41a664b077..2ebf95cdea787 100644 --- a/crates/bevy_ecs/src/query/fetch.rs +++ b/crates/bevy_ecs/src/query/fetch.rs @@ -269,7 +269,7 @@ use std::{cell::UnsafeCell, marker::PhantomData}; /// [`Query`]: crate::system::Query /// [`ReadOnly`]: Self::ReadOnly #[diagnostic::on_unimplemented( - message = "`{Self}` is not valid `Query` data", + message = "`{Self}` is not valid to request as data in a `Query`", label = "invalid `Query` data" )] pub unsafe trait QueryData: WorldQuery { diff --git a/crates/bevy_ecs/src/query/filter.rs b/crates/bevy_ecs/src/query/filter.rs index 22b01c450144d..583ce4947e70c 100644 --- a/crates/bevy_ecs/src/query/filter.rs +++ b/crates/bevy_ecs/src/query/filter.rs @@ -72,7 +72,8 @@ use std::{cell::UnsafeCell, marker::PhantomData}; /// [`State`]: Self::State #[diagnostic::on_unimplemented( message = "`{Self}` is not a valid `Query` filter", - label = "invalid `Query` filter" + label = "invalid `Query` filter", + note = "a `QueryFilter` typically uses a combination of `With` and `Without` statements" )] pub trait QueryFilter: WorldQuery { /// Returns true if (and only if) this Filter relies strictly on archetypes to limit which @@ -942,8 +943,9 @@ impl QueryFilter for Changed { /// [`Added`] and [`Changed`] works with entities, and therefore are not archetypal. As such /// they do not implement [`ArchetypeFilter`]. #[diagnostic::on_unimplemented( - message = "`{Self}` is not an archetypical filter", - label = "invalid `Query` filter" + message = "`{Self}` is not a valid `Query` filter based on archetype information", + label = "invalid `Query` filter", + note = "an `ArchetypeFilter` typically uses a combination of `With` and `Without` statements" )] pub trait ArchetypeFilter: QueryFilter {} diff --git a/crates/bevy_ecs/src/system/combinator.rs b/crates/bevy_ecs/src/system/combinator.rs index 006708d75d658..dca72127dc9a5 100644 --- a/crates/bevy_ecs/src/system/combinator.rs +++ b/crates/bevy_ecs/src/system/combinator.rs @@ -85,7 +85,8 @@ use super::{ReadOnlySystem, System}; /// ``` #[diagnostic::on_unimplemented( message = "`{Self}` can not combine systems `{A}` and `{B}`", - label = "invalid system combination" + label = "invalid system combination", + note = "the inputs and outputs of `{A}` and `{B}` are not compatible with this combiner" )] pub trait Combine { /// The [input](System::In) type for a [`CombinatorSystem`]. diff --git a/crates/bevy_ecs/src/system/function_system.rs b/crates/bevy_ecs/src/system/function_system.rs index 4e5c1f938eba0..c97e684e64337 100644 --- a/crates/bevy_ecs/src/system/function_system.rs +++ b/crates/bevy_ecs/src/system/function_system.rs @@ -626,7 +626,10 @@ where /// ``` /// [`PipeSystem`]: crate::system::PipeSystem /// [`ParamSet`]: crate::system::ParamSet -#[diagnostic::on_unimplemented(message = "`{Self}` is not a system", label = "invalid system")] +#[diagnostic::on_unimplemented( + message = "`{Self}` is not a valid system", + label = "invalid system" +)] pub trait SystemParamFunction: Send + Sync + 'static { /// The input type to this system. See [`System::In`]. type In; From a91c739ce02e8cbdb2adcc4eccdd095335819d54 Mon Sep 17 00:00:00 2001 From: Zachary Harrold Date: Fri, 17 May 2024 08:14:01 +1000 Subject: [PATCH 7/7] Update crates/bevy_render/src/render_graph/node.rs Co-authored-by: BD103 <59022059+BD103@users.noreply.github.com> --- crates/bevy_render/src/render_graph/node.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_render/src/render_graph/node.rs b/crates/bevy_render/src/render_graph/node.rs index 5bff05ca88fa1..0558f7c078164 100644 --- a/crates/bevy_render/src/render_graph/node.rs +++ b/crates/bevy_render/src/render_graph/node.rs @@ -336,7 +336,7 @@ impl Node for RunGraphOnViewNode { /// This trait should be used instead of the [`Node`] trait when making a render node that runs on a view. /// -/// It is intended to be used with [`ViewNodeRunner`]' +/// It is intended to be used with [`ViewNodeRunner`] pub trait ViewNode { /// The query that will be used on the view entity. /// It is guaranteed to run on the view entity, so there's no need for a filter