From bf765e61b54543498dc8cf4ffb612ae5cb885118 Mon Sep 17 00:00:00 2001 From: Zachary Harrold Date: Fri, 6 Dec 2024 08:15:21 +1100 Subject: [PATCH] Add `no_std` support to `bevy_reflect` (#16256) # Objective - Contributes to #15460 ## Solution - Added `std` feature (enabled by default) ## Testing - CI - `cargo check -p bevy_reflect --no-default-features --target "x86_64-unknown-none"` - UEFI demo application runs with this branch of `bevy_reflect`, allowing `derive(Reflect)` ## Notes - The [`spin`](https://crates.io/crates/spin) crate has been included to provide `RwLock` and `Once` (as an alternative to `OnceLock`) when the `std` feature is not enabled. Another alternative may be more desirable, please provide feedback if you have a strong opinion here! - Certain items (`Box`, `String`, `ToString`) provided by `alloc` have been added to `__macro_exports` as a way to avoid `alloc` vs `std` namespacing. I'm personally quite annoyed that we can't rely on `alloc` as a crate name in `std` environments within macros. I'd love an alternative to my approach here, but I suspect it's the least-bad option. - I would've liked to have an `alloc` feature (for allocation-free `bevy_reflect`), unfortunately, `erased_serde` unconditionally requires access to `Box`. Maybe one day we could design around this, but for now it just means `bevy_reflect` requires `alloc`. --------- Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com> Co-authored-by: Alice Cecile --- crates/bevy_reflect/Cargo.toml | 50 ++++++++++++++----- crates/bevy_reflect/derive/src/derive_data.rs | 9 +++- crates/bevy_reflect/derive/src/generics.rs | 4 +- .../bevy_reflect/derive/src/impls/common.rs | 20 ++++---- crates/bevy_reflect/derive/src/impls/enums.rs | 8 +-- .../bevy_reflect/derive/src/impls/opaque.rs | 8 +-- .../bevy_reflect/derive/src/impls/structs.rs | 8 +-- .../derive/src/impls/tuple_structs.rs | 8 +-- crates/bevy_reflect/derive/src/impls/typed.rs | 39 +++++++++------ .../bevy_reflect/derive/src/serialization.rs | 15 +++--- crates/bevy_reflect/derive/src/string_expr.rs | 4 +- .../derive/src/trait_reflection.rs | 8 +-- crates/bevy_reflect/src/array.rs | 1 + crates/bevy_reflect/src/attributes.rs | 5 +- crates/bevy_reflect/src/enums/dynamic_enum.rs | 1 + crates/bevy_reflect/src/enums/enum_trait.rs | 2 +- crates/bevy_reflect/src/enums/variants.rs | 4 +- crates/bevy_reflect/src/from_reflect.rs | 1 + crates/bevy_reflect/src/func/args/arg.rs | 4 ++ crates/bevy_reflect/src/func/args/error.rs | 3 ++ crates/bevy_reflect/src/func/args/from_arg.rs | 3 ++ crates/bevy_reflect/src/func/args/info.rs | 3 ++ crates/bevy_reflect/src/func/args/list.rs | 5 +- .../bevy_reflect/src/func/args/ownership.rs | 3 ++ .../bevy_reflect/src/func/dynamic_function.rs | 9 ++-- .../src/func/dynamic_function_mut.rs | 9 ++-- crates/bevy_reflect/src/func/error.rs | 3 ++ crates/bevy_reflect/src/func/function.rs | 5 +- crates/bevy_reflect/src/func/info.rs | 9 ++-- crates/bevy_reflect/src/func/into_function.rs | 3 ++ .../src/func/into_function_mut.rs | 3 ++ crates/bevy_reflect/src/func/macros.rs | 3 ++ crates/bevy_reflect/src/func/reflect_fn.rs | 3 ++ .../bevy_reflect/src/func/reflect_fn_mut.rs | 3 ++ crates/bevy_reflect/src/func/registry.rs | 9 ++-- crates/bevy_reflect/src/func/return_type.rs | 4 ++ crates/bevy_reflect/src/generics.rs | 3 +- crates/bevy_reflect/src/impls/glam.rs | 3 ++ crates/bevy_reflect/src/impls/smallvec.rs | 5 +- crates/bevy_reflect/src/impls/std.rs | 44 ++++++++++++---- crates/bevy_reflect/src/kind.rs | 1 + crates/bevy_reflect/src/lib.rs | 14 ++++++ crates/bevy_reflect/src/list.rs | 1 + crates/bevy_reflect/src/map.rs | 3 +- crates/bevy_reflect/src/path/mod.rs | 1 + crates/bevy_reflect/src/reflect.rs | 7 +-- crates/bevy_reflect/src/remote.rs | 2 +- crates/bevy_reflect/src/serde/de/arrays.rs | 1 + .../src/serde/de/deserialize_with_registry.rs | 1 + .../bevy_reflect/src/serde/de/deserializer.rs | 3 +- crates/bevy_reflect/src/serde/de/helpers.rs | 4 ++ crates/bevy_reflect/src/serde/de/processor.rs | 1 + .../bevy_reflect/src/serde/de/struct_utils.rs | 1 + .../bevy_reflect/src/serde/de/tuple_utils.rs | 1 + .../src/serde/ser/serializable.rs | 1 + .../src/serde/ser/serialize_with_registry.rs | 1 + crates/bevy_reflect/src/serde/type_data.rs | 5 +- crates/bevy_reflect/src/set.rs | 3 +- crates/bevy_reflect/src/std_traits.rs | 1 + crates/bevy_reflect/src/struct_trait.rs | 2 +- crates/bevy_reflect/src/tuple.rs | 7 ++- crates/bevy_reflect/src/tuple_struct.rs | 2 +- crates/bevy_reflect/src/type_info.rs | 6 +-- crates/bevy_reflect/src/type_info_stack.rs | 3 ++ crates/bevy_reflect/src/type_path.rs | 4 +- crates/bevy_reflect/src/type_registry.rs | 40 ++++++++++----- crates/bevy_reflect/src/utility.rs | 41 ++++++++++----- tools/ci/src/commands/compile_check_no_std.rs | 16 ++++++ 68 files changed, 364 insertions(+), 143 deletions(-) diff --git a/crates/bevy_reflect/Cargo.toml b/crates/bevy_reflect/Cargo.toml index 3fe4e07a5d..25f23db352 100644 --- a/crates/bevy_reflect/Cargo.toml +++ b/crates/bevy_reflect/Cargo.toml @@ -10,14 +10,24 @@ keywords = ["bevy"] rust-version = "1.81.0" [features] -default = ["smallvec", "debug", "alloc"] +default = ["std", "smallvec", "debug"] +std = [ + "bevy_utils/std", + "erased-serde/std", + "downcast-rs/std", + "serde/std", + "spin/std", + "glam?/std", + "smol_str?/std", + "uuid?/std", +] # When enabled, provides Bevy-related reflection implementations bevy = ["smallvec", "smol_str"] glam = ["dep:glam"] -petgraph = ["dep:petgraph"] +petgraph = ["dep:petgraph", "std"] smallvec = ["dep:smallvec"] uuid = ["dep:uuid"] -wgpu-types = ["dep:wgpu-types"] +wgpu-types = ["dep:wgpu-types", "std"] # Enables features useful for debugging reflection debug = ["debug_stack"] # When enabled, keeps track of the current serialization/deserialization context for better error messages @@ -26,31 +36,45 @@ debug_stack = [] documentation = ["bevy_reflect_derive/documentation"] # Enables function reflection functions = ["bevy_reflect_derive/functions"] -alloc = [] [dependencies] # bevy bevy_reflect_derive = { path = "derive", version = "0.15.0-dev" } -bevy_utils = { path = "../bevy_utils", version = "0.15.0-dev" } +bevy_utils = { path = "../bevy_utils", version = "0.15.0-dev", default-features = false, features = [ + "alloc", +] } bevy_ptr = { path = "../bevy_ptr", version = "0.15.0-dev" } # other -erased-serde = "0.4" -disqualified = "1.0" -downcast-rs = "1.2" +erased-serde = { version = "0.4", default-features = false, features = [ + "alloc", +] } +disqualified = { version = "1.0", default-features = false } +downcast-rs = { version = "1.2", default-features = false } derive_more = { version = "1", default-features = false, features = [ "error", "from", "display", ] } -serde = "1" -smallvec = { version = "1.11", optional = true } +serde = { version = "1", default-features = false, features = ["alloc"] } +spin = { version = "0.9.8", default-features = false, features = [ + "once", + "rwlock", +] } assert_type_match = "0.1.1" -glam = { version = "0.29", features = ["serde"], optional = true } +smallvec = { version = "1.11", default-features = false, optional = true } +glam = { version = "0.29", default-features = false, features = [ + "serde", +], optional = true } petgraph = { version = "0.6", features = ["serde-1"], optional = true } -smol_str = { version = "0.2.0", features = ["serde"], optional = true } -uuid = { version = "1.0", optional = true, features = ["v4", "serde"] } +smol_str = { version = "0.2.0", default-features = false, features = [ + "serde", +], optional = true } +uuid = { version = "1.0", default-features = false, optional = true, features = [ + "v4", + "serde", +] } variadics_please = "1.0" wgpu-types = { version = "23", features = ["serde"], optional = true } diff --git a/crates/bevy_reflect/derive/src/derive_data.rs b/crates/bevy_reflect/derive/src/derive_data.rs index 3d7363dec1..e739c91ebb 100644 --- a/crates/bevy_reflect/derive/src/derive_data.rs +++ b/crates/bevy_reflect/derive/src/derive_data.rs @@ -280,9 +280,11 @@ impl<'a> ReflectDerive<'a> { match &input.data { Data::Struct(data) => { let fields = Self::collect_struct_fields(&data.fields)?; + let serialization_data = + SerializationDataDef::new(&fields, &meta.bevy_reflect_path)?; let reflect_struct = ReflectStruct { meta, - serialization_data: SerializationDataDef::new(&fields)?, + serialization_data, fields, }; @@ -1034,6 +1036,7 @@ impl<'a> ReflectTypePath<'a> { fn reduce_generics( generics: &Generics, mut ty_generic_fn: impl FnMut(&TypeParam) -> StringExpr, + bevy_reflect_path: &Path, ) -> StringExpr { let mut params = generics.params.iter().filter_map(|param| match param { GenericParam::Type(type_param) => Some(ty_generic_fn(type_param)), @@ -1042,7 +1045,7 @@ impl<'a> ReflectTypePath<'a> { let ty = &const_param.ty; Some(StringExpr::Owned(quote! { - <#ty as ::std::string::ToString>::to_string(&#ident) + <#ty as #bevy_reflect_path::__macro_exports::alloc_utils::ToString>::to_string(&#ident) })) } GenericParam::Lifetime(_) => None, @@ -1074,6 +1077,7 @@ impl<'a> ReflectTypePath<'a> { <#ident as #bevy_reflect_path::TypePath>::type_path() }) }, + bevy_reflect_path, ); StringExpr::from_iter([ @@ -1111,6 +1115,7 @@ impl<'a> ReflectTypePath<'a> { <#ident as #bevy_reflect_path::TypePath>::short_type_path() }) }, + bevy_reflect_path, ); StringExpr::from_iter([ diff --git a/crates/bevy_reflect/derive/src/generics.rs b/crates/bevy_reflect/derive/src/generics.rs index bf79b75348..88b9c3f70b 100644 --- a/crates/bevy_reflect/derive/src/generics.rs +++ b/crates/bevy_reflect/derive/src/generics.rs @@ -32,7 +32,7 @@ pub(crate) fn generate_generics(meta: &ReflectMeta) -> Option { Some(quote! { #bevy_reflect_path::GenericInfo::Type( #bevy_reflect_path::TypeParamInfo::new::<#ident>( - ::std::borrow::Cow::Borrowed(#name), + #bevy_reflect_path::__macro_exports::alloc_utils::Cow::Borrowed(#name), ) #with_default ) @@ -53,7 +53,7 @@ pub(crate) fn generate_generics(meta: &ReflectMeta) -> Option { )] #bevy_reflect_path::GenericInfo::Const( #bevy_reflect_path::ConstParamInfo::new::<#ty>( - ::std::borrow::Cow::Borrowed(#name), + #bevy_reflect_path::__macro_exports::alloc_utils::Cow::Borrowed(#name), ) #with_default ) diff --git a/crates/bevy_reflect/derive/src/impls/common.rs b/crates/bevy_reflect/derive/src/impls/common.rs index 12f324c330..e8fdadb03e 100644 --- a/crates/bevy_reflect/derive/src/impls/common.rs +++ b/crates/bevy_reflect/derive/src/impls/common.rs @@ -1,4 +1,4 @@ -use bevy_macro_utils::fq_std::{FQAny, FQBox, FQOption, FQResult}; +use bevy_macro_utils::fq_std::{FQAny, FQOption, FQResult}; use quote::quote; @@ -17,8 +17,8 @@ pub fn impl_full_reflect( let any_impls = if meta.is_remote_wrapper() { quote! { #[inline] - fn into_any(self: #FQBox) -> #FQBox { - #FQBox::new(self.0) + fn into_any(self: #bevy_reflect_path::__macro_exports::alloc_utils::Box) -> #bevy_reflect_path::__macro_exports::alloc_utils::Box { + #bevy_reflect_path::__macro_exports::alloc_utils::Box::new(self.0) } #[inline] @@ -34,7 +34,7 @@ pub fn impl_full_reflect( } else { quote! { #[inline] - fn into_any(self: #FQBox) -> #FQBox { + fn into_any(self: #bevy_reflect_path::__macro_exports::alloc_utils::Box) -> #bevy_reflect_path::__macro_exports::alloc_utils::Box { self } @@ -55,7 +55,7 @@ pub fn impl_full_reflect( #any_impls #[inline] - fn into_reflect(self: #FQBox) -> #FQBox { + fn into_reflect(self: #bevy_reflect_path::__macro_exports::alloc_utils::Box) -> #bevy_reflect_path::__macro_exports::alloc_utils::Box { self } @@ -72,8 +72,8 @@ pub fn impl_full_reflect( #[inline] fn set( &mut self, - value: #FQBox - ) -> #FQResult<(), #FQBox> { + value: #bevy_reflect_path::__macro_exports::alloc_utils::Box + ) -> #FQResult<(), #bevy_reflect_path::__macro_exports::alloc_utils::Box> { *self = ::take(value)?; #FQResult::Ok(()) } @@ -119,8 +119,8 @@ pub fn common_partial_reflect_methods( quote! { #[inline] fn try_into_reflect( - self: #FQBox - ) -> #FQResult<#FQBox, #FQBox> { + self: #bevy_reflect_path::__macro_exports::alloc_utils::Box + ) -> #FQResult<#bevy_reflect_path::__macro_exports::alloc_utils::Box, #bevy_reflect_path::__macro_exports::alloc_utils::Box> { #FQResult::Ok(self) } @@ -135,7 +135,7 @@ pub fn common_partial_reflect_methods( } #[inline] - fn into_partial_reflect(self: #FQBox) -> #FQBox { + fn into_partial_reflect(self: #bevy_reflect_path::__macro_exports::alloc_utils::Box) -> #bevy_reflect_path::__macro_exports::alloc_utils::Box { self } diff --git a/crates/bevy_reflect/derive/src/impls/enums.rs b/crates/bevy_reflect/derive/src/impls/enums.rs index c4791ca32b..235a7cff1c 100644 --- a/crates/bevy_reflect/derive/src/impls/enums.rs +++ b/crates/bevy_reflect/derive/src/impls/enums.rs @@ -3,7 +3,7 @@ use crate::{ enum_utility::{EnumVariantOutputData, TryApplyVariantBuilder, VariantBuilder}, impls::{common_partial_reflect_methods, impl_full_reflect, impl_type_path, impl_typed}, }; -use bevy_macro_utils::fq_std::{FQBox, FQOption, FQResult}; +use bevy_macro_utils::fq_std::{FQOption, FQResult}; use proc_macro2::{Ident, Span}; use quote::quote; use syn::{Fields, Path}; @@ -186,8 +186,8 @@ pub(crate) fn impl_enum(reflect_enum: &ReflectEnum) -> proc_macro2::TokenStream } #[inline] - fn clone_value(&self) -> #FQBox { - #FQBox::new(#bevy_reflect_path::Enum::clone_dynamic(self)) + fn clone_value(&self) -> #bevy_reflect_path::__macro_exports::alloc_utils::Box { + #bevy_reflect_path::__macro_exports::alloc_utils::Box::new(#bevy_reflect_path::Enum::clone_dynamic(self)) } #[inline] @@ -256,7 +256,7 @@ pub(crate) fn impl_enum(reflect_enum: &ReflectEnum) -> proc_macro2::TokenStream #bevy_reflect_path::ReflectMut::Enum(self) } - fn reflect_owned(self: #FQBox) -> #bevy_reflect_path::ReflectOwned { + fn reflect_owned(self: #bevy_reflect_path::__macro_exports::alloc_utils::Box) -> #bevy_reflect_path::ReflectOwned { #bevy_reflect_path::ReflectOwned::Enum(self) } diff --git a/crates/bevy_reflect/derive/src/impls/opaque.rs b/crates/bevy_reflect/derive/src/impls/opaque.rs index eb8fb9f4e0..bdee656a96 100644 --- a/crates/bevy_reflect/derive/src/impls/opaque.rs +++ b/crates/bevy_reflect/derive/src/impls/opaque.rs @@ -3,7 +3,7 @@ use crate::{ where_clause_options::WhereClauseOptions, ReflectMeta, }; -use bevy_macro_utils::fq_std::{FQBox, FQClone, FQOption, FQResult}; +use bevy_macro_utils::fq_std::{FQClone, FQOption, FQResult}; use quote::quote; /// Implements `GetTypeRegistration` and `Reflect` for the given type data. @@ -77,8 +77,8 @@ pub(crate) fn impl_opaque(meta: &ReflectMeta) -> proc_macro2::TokenStream { } #[inline] - fn clone_value(&self) -> #FQBox { - #FQBox::new(#FQClone::clone(self)) + fn clone_value(&self) -> #bevy_reflect_path::__macro_exports::alloc_utils::Box { + #bevy_reflect_path::__macro_exports::alloc_utils::Box::new(#FQClone::clone(self)) } #[inline] @@ -112,7 +112,7 @@ pub(crate) fn impl_opaque(meta: &ReflectMeta) -> proc_macro2::TokenStream { } #[inline] - fn reflect_owned(self: #FQBox) -> #bevy_reflect_path::ReflectOwned { + fn reflect_owned(self: #bevy_reflect_path::__macro_exports::alloc_utils::Box) -> #bevy_reflect_path::ReflectOwned { #bevy_reflect_path::ReflectOwned::Opaque(self) } diff --git a/crates/bevy_reflect/derive/src/impls/structs.rs b/crates/bevy_reflect/derive/src/impls/structs.rs index fa1b454cfc..c1db19ca9c 100644 --- a/crates/bevy_reflect/derive/src/impls/structs.rs +++ b/crates/bevy_reflect/derive/src/impls/structs.rs @@ -3,7 +3,7 @@ use crate::{ struct_utility::FieldAccessors, ReflectStruct, }; -use bevy_macro_utils::fq_std::{FQBox, FQDefault, FQOption, FQResult}; +use bevy_macro_utils::fq_std::{FQDefault, FQOption, FQResult}; use quote::{quote, ToTokens}; /// Implements `Struct`, `GetTypeRegistration`, and `Reflect` for the given derive data. @@ -134,8 +134,8 @@ pub(crate) fn impl_struct(reflect_struct: &ReflectStruct) -> proc_macro2::TokenS } #[inline] - fn clone_value(&self) -> #FQBox { - #FQBox::new(#bevy_reflect_path::Struct::clone_dynamic(self)) + fn clone_value(&self) -> #bevy_reflect_path::__macro_exports::alloc_utils::Box { + #bevy_reflect_path::__macro_exports::alloc_utils::Box::new(#bevy_reflect_path::Struct::clone_dynamic(self)) } #[inline] @@ -174,7 +174,7 @@ pub(crate) fn impl_struct(reflect_struct: &ReflectStruct) -> proc_macro2::TokenS #bevy_reflect_path::ReflectMut::Struct(self) } #[inline] - fn reflect_owned(self: #FQBox) -> #bevy_reflect_path::ReflectOwned { + fn reflect_owned(self: #bevy_reflect_path::__macro_exports::alloc_utils::Box) -> #bevy_reflect_path::ReflectOwned { #bevy_reflect_path::ReflectOwned::Struct(self) } diff --git a/crates/bevy_reflect/derive/src/impls/tuple_structs.rs b/crates/bevy_reflect/derive/src/impls/tuple_structs.rs index f0f3cc8f2b..a0037c64ca 100644 --- a/crates/bevy_reflect/derive/src/impls/tuple_structs.rs +++ b/crates/bevy_reflect/derive/src/impls/tuple_structs.rs @@ -3,7 +3,7 @@ use crate::{ struct_utility::FieldAccessors, ReflectStruct, }; -use bevy_macro_utils::fq_std::{FQBox, FQDefault, FQOption, FQResult}; +use bevy_macro_utils::fq_std::{FQDefault, FQOption, FQResult}; use quote::{quote, ToTokens}; /// Implements `TupleStruct`, `GetTypeRegistration`, and `Reflect` for the given derive data. @@ -100,8 +100,8 @@ pub(crate) fn impl_tuple_struct(reflect_struct: &ReflectStruct) -> proc_macro2:: #FQOption::Some(::type_info()) } #[inline] - fn clone_value(&self) -> #FQBox { - #FQBox::new(#bevy_reflect_path::TupleStruct::clone_dynamic(self)) + fn clone_value(&self) -> #bevy_reflect_path::__macro_exports::alloc_utils::Box { + #bevy_reflect_path::__macro_exports::alloc_utils::Box::new(#bevy_reflect_path::TupleStruct::clone_dynamic(self)) } #[inline] @@ -139,7 +139,7 @@ pub(crate) fn impl_tuple_struct(reflect_struct: &ReflectStruct) -> proc_macro2:: #bevy_reflect_path::ReflectMut::TupleStruct(self) } #[inline] - fn reflect_owned(self: #FQBox) -> #bevy_reflect_path::ReflectOwned { + fn reflect_owned(self: #bevy_reflect_path::__macro_exports::alloc_utils::Box) -> #bevy_reflect_path::ReflectOwned { #bevy_reflect_path::ReflectOwned::TupleStruct(self) } diff --git a/crates/bevy_reflect/derive/src/impls/typed.rs b/crates/bevy_reflect/derive/src/impls/typed.rs index b158973a7b..da8254d149 100644 --- a/crates/bevy_reflect/derive/src/impls/typed.rs +++ b/crates/bevy_reflect/derive/src/impls/typed.rs @@ -106,27 +106,34 @@ pub(crate) fn impl_type_path(meta: &ReflectMeta) -> TokenStream { quote! { #primitive_assert - impl #impl_generics #bevy_reflect_path::TypePath for #type_path #ty_generics #where_reflect_clause { - fn type_path() -> &'static str { - #long_type_path - } + // To ensure alloc is available, but also prevent its name from clashing, we place the implementation inside an anonymous constant + const _: () = { + extern crate alloc; - fn short_type_path() -> &'static str { - #short_type_path - } + use alloc::string::ToString; - fn type_ident() -> Option<&'static str> { - #type_ident - } + impl #impl_generics #bevy_reflect_path::TypePath for #type_path #ty_generics #where_reflect_clause { + fn type_path() -> &'static str { + #long_type_path + } - fn crate_name() -> Option<&'static str> { - #crate_name - } + fn short_type_path() -> &'static str { + #short_type_path + } - fn module_path() -> Option<&'static str> { - #module_path + fn type_ident() -> Option<&'static str> { + #type_ident + } + + fn crate_name() -> Option<&'static str> { + #crate_name + } + + fn module_path() -> Option<&'static str> { + #module_path + } } - } + }; } } diff --git a/crates/bevy_reflect/derive/src/serialization.rs b/crates/bevy_reflect/derive/src/serialization.rs index a1ea937894..3cfe0adc74 100644 --- a/crates/bevy_reflect/derive/src/serialization.rs +++ b/crates/bevy_reflect/derive/src/serialization.rs @@ -2,7 +2,7 @@ use crate::{ derive_data::StructField, field_attributes::{DefaultBehavior, ReflectIgnoreBehavior}, }; -use bevy_macro_utils::fq_std::{FQBox, FQDefault}; +use bevy_macro_utils::fq_std::FQDefault; use quote::quote; use std::collections::HashMap; use syn::{spanned::Spanned, Path}; @@ -20,7 +20,10 @@ impl SerializationDataDef { /// /// Returns `Ok(Some(data))` if there are any fields needing to be skipped during serialization. /// Otherwise, returns `Ok(None)`. - pub fn new(fields: &[StructField<'_>]) -> Result, syn::Error> { + pub fn new( + fields: &[StructField<'_>], + bevy_reflect_path: &Path, + ) -> Result, syn::Error> { let mut skipped = HashMap::default(); for field in fields { @@ -33,7 +36,7 @@ impl SerializationDataDef { "internal error: field is missing a reflection index", ) })?, - SkippedFieldDef::new(field)?, + SkippedFieldDef::new(field, bevy_reflect_path)?, ); } _ => continue, @@ -75,15 +78,15 @@ pub(crate) struct SkippedFieldDef { } impl SkippedFieldDef { - pub fn new(field: &StructField<'_>) -> Result { + pub fn new(field: &StructField<'_>, bevy_reflect_path: &Path) -> Result { let ty = &field.data.ty; let default_fn = match &field.attrs.default { DefaultBehavior::Func(func) => quote! { - || { #FQBox::new(#func()) } + || { #bevy_reflect_path::__macro_exports::alloc_utils::Box::new(#func()) } }, _ => quote! { - || { #FQBox::new(<#ty as #FQDefault>::default()) } + || { #bevy_reflect_path::__macro_exports::alloc_utils::Box::new(<#ty as #FQDefault>::default()) } }, }; diff --git a/crates/bevy_reflect/derive/src/string_expr.rs b/crates/bevy_reflect/derive/src/string_expr.rs index 1284736fc9..cc48a90b91 100644 --- a/crates/bevy_reflect/derive/src/string_expr.rs +++ b/crates/bevy_reflect/derive/src/string_expr.rs @@ -44,9 +44,11 @@ impl StringExpr { /// /// [already owned]: StringExpr::Owned pub fn into_owned(self) -> TokenStream { + let bevy_reflect_path = crate::meta::get_bevy_reflect_path(); + match self { Self::Const(tokens) | Self::Borrowed(tokens) => quote! { - ::std::string::ToString::to_string(#tokens) + #bevy_reflect_path::__macro_exports::alloc_utils::ToString::to_string(#tokens) }, Self::Owned(owned) => owned, } diff --git a/crates/bevy_reflect/derive/src/trait_reflection.rs b/crates/bevy_reflect/derive/src/trait_reflection.rs index 6516c5ab7e..e2c8a4d3d5 100644 --- a/crates/bevy_reflect/derive/src/trait_reflection.rs +++ b/crates/bevy_reflect/derive/src/trait_reflection.rs @@ -1,5 +1,5 @@ use bevy_macro_utils::{ - fq_std::{FQBox, FQClone, FQOption, FQResult}, + fq_std::{FQClone, FQOption, FQResult}, BevyManifest, }; use proc_macro::TokenStream; @@ -57,7 +57,7 @@ pub(crate) fn reflect_trait(_args: &TokenStream, input: TokenStream) -> TokenStr #trait_vis struct #reflect_trait_ident { get_func: fn(&dyn #bevy_reflect_path::Reflect) -> #FQOption<&dyn #trait_ident>, get_mut_func: fn(&mut dyn #bevy_reflect_path::Reflect) -> #FQOption<&mut dyn #trait_ident>, - get_boxed_func: fn(#FQBox) -> #FQResult<#FQBox, #FQBox>, + get_boxed_func: fn(#bevy_reflect_path::__macro_exports::alloc_utils::Box) -> #FQResult<#bevy_reflect_path::__macro_exports::alloc_utils::Box, #bevy_reflect_path::__macro_exports::alloc_utils::Box>, } impl #reflect_trait_ident { @@ -72,7 +72,7 @@ pub(crate) fn reflect_trait(_args: &TokenStream, input: TokenStream) -> TokenStr } #[doc = #get_box_doc] - pub fn get_boxed(&self, reflect_value: #FQBox) -> #FQResult<#FQBox, #FQBox> { + pub fn get_boxed(&self, reflect_value: #bevy_reflect_path::__macro_exports::alloc_utils::Box) -> #FQResult<#bevy_reflect_path::__macro_exports::alloc_utils::Box, #bevy_reflect_path::__macro_exports::alloc_utils::Box> { (self.get_boxed_func)(reflect_value) } } @@ -87,7 +87,7 @@ pub(crate) fn reflect_trait(_args: &TokenStream, input: TokenStream) -> TokenStr ::downcast_mut::(reflect_value).map(|value| value as &mut dyn #trait_ident) }, get_boxed_func: |reflect_value| { - ::downcast::(reflect_value).map(|value| value as #FQBox) + ::downcast::(reflect_value).map(|value| value as #bevy_reflect_path::__macro_exports::alloc_utils::Box) } } } diff --git a/crates/bevy_reflect/src/array.rs b/crates/bevy_reflect/src/array.rs index 481b29648b..0753c0e345 100644 --- a/crates/bevy_reflect/src/array.rs +++ b/crates/bevy_reflect/src/array.rs @@ -4,6 +4,7 @@ use crate::{ Generics, MaybeTyped, PartialReflect, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, Type, TypeInfo, TypePath, }; +use alloc::{boxed::Box, vec::Vec}; use bevy_reflect_derive::impl_type_path; use core::{ any::Any, diff --git a/crates/bevy_reflect/src/attributes.rs b/crates/bevy_reflect/src/attributes.rs index 029f61ed1b..0e751fa57a 100644 --- a/crates/bevy_reflect/src/attributes.rs +++ b/crates/bevy_reflect/src/attributes.rs @@ -1,4 +1,5 @@ use crate::Reflect; +use alloc::boxed::Box; use bevy_utils::TypeIdMap; use core::{ any::TypeId, @@ -16,7 +17,7 @@ use core::{ /// /// ``` /// # use bevy_reflect::{Reflect, Typed, TypeInfo}; -/// use std::ops::RangeInclusive; +/// use core::ops::RangeInclusive; /// #[derive(Reflect)] /// struct Slider { /// #[reflect(@RangeInclusive::::new(0.0, 1.0))] @@ -152,7 +153,7 @@ macro_rules! impl_custom_attribute_methods { } #[allow(rustdoc::redundant_explicit_links)] - /// Gets a custom attribute by its [`TypeId`](std::any::TypeId). + /// Gets a custom attribute by its [`TypeId`](core::any::TypeId). /// /// This is the dynamic equivalent of [`get_attribute`](Self::get_attribute). pub fn get_attribute_by_id(&$self, id: ::core::any::TypeId) -> Option<&dyn $crate::Reflect> { diff --git a/crates/bevy_reflect/src/enums/dynamic_enum.rs b/crates/bevy_reflect/src/enums/dynamic_enum.rs index d114b6d86e..9162ab3610 100644 --- a/crates/bevy_reflect/src/enums/dynamic_enum.rs +++ b/crates/bevy_reflect/src/enums/dynamic_enum.rs @@ -6,6 +6,7 @@ use crate::{ Struct, Tuple, TypeInfo, VariantFieldIter, VariantType, }; +use alloc::{boxed::Box, string::String}; use core::fmt::Formatter; use derive_more::derive::From; diff --git a/crates/bevy_reflect/src/enums/enum_trait.rs b/crates/bevy_reflect/src/enums/enum_trait.rs index d2325439c3..696f389f6e 100644 --- a/crates/bevy_reflect/src/enums/enum_trait.rs +++ b/crates/bevy_reflect/src/enums/enum_trait.rs @@ -4,7 +4,7 @@ use crate::{ type_info::impl_type_methods, DynamicEnum, Generics, PartialReflect, Type, TypePath, VariantInfo, VariantType, }; -use alloc::sync::Arc; +use alloc::{boxed::Box, format, string::String, sync::Arc}; use bevy_utils::HashMap; use core::slice::Iter; diff --git a/crates/bevy_reflect/src/enums/variants.rs b/crates/bevy_reflect/src/enums/variants.rs index 0830914794..c29c67770e 100644 --- a/crates/bevy_reflect/src/enums/variants.rs +++ b/crates/bevy_reflect/src/enums/variants.rs @@ -2,10 +2,10 @@ use crate::{ attributes::{impl_custom_attribute_methods, CustomAttributes}, NamedField, UnnamedField, }; +use alloc::boxed::Box; +use alloc::sync::Arc; use bevy_utils::HashMap; use core::slice::Iter; - -use alloc::sync::Arc; use derive_more::derive::{Display, Error}; /// Describes the form of an enum variant. diff --git a/crates/bevy_reflect/src/from_reflect.rs b/crates/bevy_reflect/src/from_reflect.rs index 7a8c3b289d..71a0dd5715 100644 --- a/crates/bevy_reflect/src/from_reflect.rs +++ b/crates/bevy_reflect/src/from_reflect.rs @@ -1,4 +1,5 @@ use crate::{FromType, PartialReflect, Reflect}; +use alloc::boxed::Box; /// A trait that enables types to be dynamically constructed from reflected data. /// diff --git a/crates/bevy_reflect/src/func/args/arg.rs b/crates/bevy_reflect/src/func/args/arg.rs index a61ff7c184..d614f073f2 100644 --- a/crates/bevy_reflect/src/func/args/arg.rs +++ b/crates/bevy_reflect/src/func/args/arg.rs @@ -2,8 +2,12 @@ use crate::{ func::args::{ArgError, FromArg, Ownership}, PartialReflect, Reflect, TypePath, }; +use alloc::boxed::Box; use core::ops::Deref; +#[cfg(not(feature = "std"))] +use alloc::{format, vec}; + /// Represents an argument that can be passed to a [`DynamicFunction`] or [`DynamicFunctionMut`]. /// /// [`DynamicFunction`]: crate::func::DynamicFunction diff --git a/crates/bevy_reflect/src/func/args/error.rs b/crates/bevy_reflect/src/func/args/error.rs index 65b7ea603e..4e1c6f001f 100644 --- a/crates/bevy_reflect/src/func/args/error.rs +++ b/crates/bevy_reflect/src/func/args/error.rs @@ -4,6 +4,9 @@ use derive_more::derive::{Display, Error}; use crate::func::args::Ownership; +#[cfg(not(feature = "std"))] +use alloc::{boxed::Box, format, vec}; + /// An error that occurs when converting an [argument]. /// /// [argument]: crate::func::args::Arg diff --git a/crates/bevy_reflect/src/func/args/from_arg.rs b/crates/bevy_reflect/src/func/args/from_arg.rs index 88d04aefe7..ddb1e014eb 100644 --- a/crates/bevy_reflect/src/func/args/from_arg.rs +++ b/crates/bevy_reflect/src/func/args/from_arg.rs @@ -1,5 +1,8 @@ use crate::func::args::{Arg, ArgError}; +#[cfg(not(feature = "std"))] +use alloc::{boxed::Box, format, vec}; + /// A trait for types that can be created from an [`Arg`]. /// /// This trait exists so that types can be automatically converted into an [`Arg`] diff --git a/crates/bevy_reflect/src/func/args/info.rs b/crates/bevy_reflect/src/func/args/info.rs index b1a81f3059..3919771f34 100644 --- a/crates/bevy_reflect/src/func/args/info.rs +++ b/crates/bevy_reflect/src/func/args/info.rs @@ -6,6 +6,9 @@ use crate::{ Type, TypePath, }; +#[cfg(not(feature = "std"))] +use alloc::{boxed::Box, format, vec}; + /// Type information for an [`Arg`] used in a [`DynamicFunction`] or [`DynamicFunctionMut`]. /// /// [`Arg`]: crate::func::args::Arg diff --git a/crates/bevy_reflect/src/func/args/list.rs b/crates/bevy_reflect/src/func/args/list.rs index ea35cdb2ad..6ed7eace98 100644 --- a/crates/bevy_reflect/src/func/args/list.rs +++ b/crates/bevy_reflect/src/func/args/list.rs @@ -5,7 +5,10 @@ use crate::{ }, PartialReflect, Reflect, TypePath, }; -use alloc::collections::VecDeque; +use alloc::{boxed::Box, collections::VecDeque}; + +#[cfg(not(feature = "std"))] +use alloc::{boxed::Box, format, vec}; /// A list of arguments that can be passed to a [`DynamicFunction`] or [`DynamicFunctionMut`]. /// diff --git a/crates/bevy_reflect/src/func/args/ownership.rs b/crates/bevy_reflect/src/func/args/ownership.rs index b9395c742f..448efed9f6 100644 --- a/crates/bevy_reflect/src/func/args/ownership.rs +++ b/crates/bevy_reflect/src/func/args/ownership.rs @@ -1,5 +1,8 @@ use core::fmt::{Display, Formatter}; +#[cfg(not(feature = "std"))] +use alloc::{boxed::Box, format, vec}; + /// A trait for getting the ownership of a type. /// /// This trait exists so that [`TypedFunction`] can automatically generate diff --git a/crates/bevy_reflect/src/func/dynamic_function.rs b/crates/bevy_reflect/src/func/dynamic_function.rs index e6cfd9bea7..36a2f22a80 100644 --- a/crates/bevy_reflect/src/func/dynamic_function.rs +++ b/crates/bevy_reflect/src/func/dynamic_function.rs @@ -9,10 +9,13 @@ use crate::{ ApplyError, MaybeTyped, PartialReflect, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypePath, }; -use alloc::{borrow::Cow, sync::Arc}; +use alloc::{borrow::Cow, boxed::Box, sync::Arc}; use bevy_reflect_derive::impl_type_path; use core::fmt::{Debug, Formatter}; +#[cfg(not(feature = "std"))] +use alloc::{boxed::Box, format, vec}; + /// A dynamic representation of a function. /// /// This type can be used to represent any callable that satisfies [`Fn`] @@ -79,7 +82,7 @@ impl<'env> DynamicFunction<'env> { /// Set the name of the function. /// /// For [`DynamicFunctions`] created using [`IntoFunction`], - /// the default name will always be the full path to the function as returned by [`std::any::type_name`], + /// the default name will always be the full path to the function as returned by [`core::any::type_name`], /// unless the function is a closure, anonymous function, or function pointer, /// in which case the name will be `None`. /// @@ -134,7 +137,7 @@ impl<'env> DynamicFunction<'env> { /// The [name] of the function. /// /// For [`DynamicFunctions`] created using [`IntoFunction`], - /// the default name will always be the full path to the function as returned by [`std::any::type_name`], + /// the default name will always be the full path to the function as returned by [`core::any::type_name`], /// unless the function is a closure, anonymous function, or function pointer, /// in which case the name will be `None`. /// diff --git a/crates/bevy_reflect/src/func/dynamic_function_mut.rs b/crates/bevy_reflect/src/func/dynamic_function_mut.rs index e17f6bc67f..46341ee553 100644 --- a/crates/bevy_reflect/src/func/dynamic_function_mut.rs +++ b/crates/bevy_reflect/src/func/dynamic_function_mut.rs @@ -1,6 +1,9 @@ -use alloc::borrow::Cow; +use alloc::{borrow::Cow, boxed::Box}; use core::fmt::{Debug, Formatter}; +#[cfg(not(feature = "std"))] +use alloc::{boxed::Box, format, vec}; + use crate::func::{ args::ArgList, info::FunctionInfo, DynamicFunction, FunctionError, FunctionResult, IntoFunctionMut, @@ -90,7 +93,7 @@ impl<'env> DynamicFunctionMut<'env> { /// Set the name of the function. /// /// For [`DynamicFunctionMuts`] created using [`IntoFunctionMut`], - /// the default name will always be the full path to the function as returned by [`std::any::type_name`], + /// the default name will always be the full path to the function as returned by [`core::any::type_name`], /// unless the function is a closure, anonymous function, or function pointer, /// in which case the name will be `None`. /// @@ -195,7 +198,7 @@ impl<'env> DynamicFunctionMut<'env> { /// The [name] of the function. /// /// For [`DynamicFunctionMuts`] created using [`IntoFunctionMut`], - /// the default name will always be the full path to the function as returned by [`std::any::type_name`], + /// the default name will always be the full path to the function as returned by [`core::any::type_name`], /// unless the function is a closure, anonymous function, or function pointer, /// in which case the name will be `None`. /// diff --git a/crates/bevy_reflect/src/func/error.rs b/crates/bevy_reflect/src/func/error.rs index 520fb78860..ff65a91bd3 100644 --- a/crates/bevy_reflect/src/func/error.rs +++ b/crates/bevy_reflect/src/func/error.rs @@ -2,6 +2,9 @@ use crate::func::{args::ArgError, Return}; use alloc::borrow::Cow; use derive_more::derive::{Display, Error, From}; +#[cfg(not(feature = "std"))] +use alloc::{boxed::Box, format, vec}; + /// An error that occurs when calling a [`DynamicFunction`] or [`DynamicFunctionMut`]. /// /// [`DynamicFunction`]: crate::func::DynamicFunction diff --git a/crates/bevy_reflect/src/func/function.rs b/crates/bevy_reflect/src/func/function.rs index 3e157a2a81..face9f6466 100644 --- a/crates/bevy_reflect/src/func/function.rs +++ b/crates/bevy_reflect/src/func/function.rs @@ -5,6 +5,9 @@ use crate::{ use alloc::borrow::Cow; use core::fmt::Debug; +#[cfg(not(feature = "std"))] +use alloc::{boxed::Box, format, vec}; + /// A trait used to power [function-like] operations via [reflection]. /// /// This trait allows types to be called like regular functions @@ -36,7 +39,7 @@ pub trait Function: PartialReflect + Debug { /// The name of the function, if any. /// /// For [`DynamicFunctions`] created using [`IntoFunction`], - /// the default name will always be the full path to the function as returned by [`std::any::type_name`], + /// the default name will always be the full path to the function as returned by [`core::any::type_name`], /// unless the function is a closure, anonymous function, or function pointer, /// in which case the name will be `None`. /// diff --git a/crates/bevy_reflect/src/func/info.rs b/crates/bevy_reflect/src/func/info.rs index bc68469829..d8325c582d 100644 --- a/crates/bevy_reflect/src/func/info.rs +++ b/crates/bevy_reflect/src/func/info.rs @@ -1,4 +1,7 @@ -use alloc::borrow::Cow; +use alloc::{borrow::Cow, vec}; + +#[cfg(not(feature = "std"))] +use alloc::{boxed::Box, format, vec}; use variadics_please::all_tuples; @@ -109,7 +112,7 @@ impl FunctionInfo { /// The name of the function. /// /// For [`DynamicFunctions`] created using [`IntoFunction`] or [`DynamicFunctionMuts`] created using [`IntoFunctionMut`], - /// the default name will always be the full path to the function as returned by [`std::any::type_name`], + /// the default name will always be the full path to the function as returned by [`core::any::type_name`], /// unless the function is a closure, anonymous function, or function pointer, /// in which case the name will be `None`. /// @@ -351,7 +354,7 @@ all_tuples!(impl_typed_function, 0, 15, Arg, arg); /// | Anonymous function | `foo::bar::{{closure}}` | `None` | /// | Function pointer | `fn() -> String` | `None` | /// -/// [`type_name`]: std::any::type_name +/// [`type_name`]: core::any::type_name fn create_info() -> FunctionInfo { let name = core::any::type_name::(); diff --git a/crates/bevy_reflect/src/func/into_function.rs b/crates/bevy_reflect/src/func/into_function.rs index 3b52605aa3..78a92b05f5 100644 --- a/crates/bevy_reflect/src/func/into_function.rs +++ b/crates/bevy_reflect/src/func/into_function.rs @@ -1,5 +1,8 @@ use crate::func::{DynamicFunction, ReflectFn, TypedFunction}; +#[cfg(not(feature = "std"))] +use alloc::{boxed::Box, format, vec}; + /// A trait for types that can be converted into a [`DynamicFunction`]. /// /// This trait is automatically implemented for any type that implements diff --git a/crates/bevy_reflect/src/func/into_function_mut.rs b/crates/bevy_reflect/src/func/into_function_mut.rs index b4671047a6..a33b840bfc 100644 --- a/crates/bevy_reflect/src/func/into_function_mut.rs +++ b/crates/bevy_reflect/src/func/into_function_mut.rs @@ -1,5 +1,8 @@ use crate::func::{DynamicFunctionMut, ReflectFnMut, TypedFunction}; +#[cfg(not(feature = "std"))] +use alloc::{boxed::Box, format, vec}; + /// A trait for types that can be converted into a [`DynamicFunctionMut`]. /// /// This trait is automatically implemented for any type that implements diff --git a/crates/bevy_reflect/src/func/macros.rs b/crates/bevy_reflect/src/func/macros.rs index 3fb93a2230..410aaba456 100644 --- a/crates/bevy_reflect/src/func/macros.rs +++ b/crates/bevy_reflect/src/func/macros.rs @@ -1,3 +1,6 @@ +#[cfg(not(feature = "std"))] +use alloc::{boxed::Box, format, vec}; + /// Helper macro to implement the necessary traits for function reflection. /// /// This macro calls the following macros: diff --git a/crates/bevy_reflect/src/func/reflect_fn.rs b/crates/bevy_reflect/src/func/reflect_fn.rs index a2b2051717..486fa452aa 100644 --- a/crates/bevy_reflect/src/func/reflect_fn.rs +++ b/crates/bevy_reflect/src/func/reflect_fn.rs @@ -1,5 +1,8 @@ use variadics_please::all_tuples; +#[cfg(not(feature = "std"))] +use alloc::{boxed::Box, format, vec}; + use crate::{ func::{ args::FromArg, macros::count_tokens, ArgList, FunctionError, FunctionResult, IntoReturn, diff --git a/crates/bevy_reflect/src/func/reflect_fn_mut.rs b/crates/bevy_reflect/src/func/reflect_fn_mut.rs index 91ff07d75a..6a8b9a6d73 100644 --- a/crates/bevy_reflect/src/func/reflect_fn_mut.rs +++ b/crates/bevy_reflect/src/func/reflect_fn_mut.rs @@ -1,5 +1,8 @@ use variadics_please::all_tuples; +#[cfg(not(feature = "std"))] +use alloc::{boxed::Box, format, vec}; + use crate::{ func::{ args::FromArg, macros::count_tokens, ArgList, FunctionError, FunctionResult, IntoReturn, diff --git a/crates/bevy_reflect/src/func/registry.rs b/crates/bevy_reflect/src/func/registry.rs index 59fb9e7f8b..82d1f1542a 100644 --- a/crates/bevy_reflect/src/func/registry.rs +++ b/crates/bevy_reflect/src/func/registry.rs @@ -2,6 +2,9 @@ use alloc::{borrow::Cow, sync::Arc}; use core::fmt::Debug; use std::sync::{PoisonError, RwLock, RwLockReadGuard, RwLockWriteGuard}; +#[cfg(not(feature = "std"))] +use alloc::{boxed::Box, format, vec}; + use bevy_utils::HashMap; use crate::func::{ @@ -167,13 +170,13 @@ impl FunctionRegistry { /// a + b /// })? /// // Registering an existing function with its type name - /// .register_with_name(std::any::type_name_of_val(&mul), mul)? + /// .register_with_name(core::any::type_name_of_val(&mul), mul)? /// // Registering an existing function with a custom name /// .register_with_name("my_crate::mul", mul)?; /// /// // Be careful not to register anonymous functions with their type name. /// // This code works but registers the function with a non-unique name like `foo::bar::{{closure}}` - /// registry.register_with_name(std::any::type_name_of_val(&div), div)?; + /// registry.register_with_name(core::any::type_name_of_val(&div), div)?; /// # Ok(()) /// # } /// ``` @@ -195,7 +198,7 @@ impl FunctionRegistry { /// [name]: DynamicFunction::name /// [`register`]: Self::register /// [`overwrite_registration_with_name`]: Self::overwrite_registration_with_name - /// [type name]: std::any::type_name + /// [type name]: core::any::type_name pub fn register_with_name( &mut self, name: impl Into>, diff --git a/crates/bevy_reflect/src/func/return_type.rs b/crates/bevy_reflect/src/func/return_type.rs index 124ce4d735..3d1153912c 100644 --- a/crates/bevy_reflect/src/func/return_type.rs +++ b/crates/bevy_reflect/src/func/return_type.rs @@ -1,4 +1,8 @@ use crate::PartialReflect; +use alloc::boxed::Box; + +#[cfg(not(feature = "std"))] +use alloc::{format, vec}; /// The return type of a [`DynamicFunction`] or [`DynamicFunctionMut`]. /// diff --git a/crates/bevy_reflect/src/generics.rs b/crates/bevy_reflect/src/generics.rs index f24c4493de..fa91fc35c5 100644 --- a/crates/bevy_reflect/src/generics.rs +++ b/crates/bevy_reflect/src/generics.rs @@ -1,7 +1,6 @@ use crate::type_info::impl_type_methods; use crate::{Reflect, Type, TypePath}; -use alloc::borrow::Cow; -use alloc::sync::Arc; +use alloc::{borrow::Cow, boxed::Box, sync::Arc}; use core::ops::Deref; use derive_more::derive::From; diff --git a/crates/bevy_reflect/src/impls/glam.rs b/crates/bevy_reflect/src/impls/glam.rs index 0b3b81dc80..ba1fa00549 100644 --- a/crates/bevy_reflect/src/impls/glam.rs +++ b/crates/bevy_reflect/src/impls/glam.rs @@ -4,6 +4,9 @@ use assert_type_match::assert_type_match; use bevy_reflect_derive::{impl_reflect, impl_reflect_opaque}; use glam::*; +#[cfg(not(feature = "std"))] +use alloc::format; + /// Reflects the given foreign type as an enum and asserts that the variants/fields match up. macro_rules! reflect_enum { ($(#[$meta:meta])* enum $ident:ident { $($ty:tt)* } ) => { diff --git a/crates/bevy_reflect/src/impls/smallvec.rs b/crates/bevy_reflect/src/impls/smallvec.rs index b10ea1493b..793ca2001c 100644 --- a/crates/bevy_reflect/src/impls/smallvec.rs +++ b/crates/bevy_reflect/src/impls/smallvec.rs @@ -1,7 +1,10 @@ +use alloc::boxed::Box; use bevy_reflect_derive::impl_type_path; +use core::any::Any; use smallvec::{Array as SmallArray, SmallVec}; -use core::any::Any; +#[cfg(not(feature = "std"))] +use alloc::{format, vec}; use crate::{ self as bevy_reflect, utility::GenericTypeInfoCell, ApplyError, FromReflect, FromType, diff --git a/crates/bevy_reflect/src/impls/std.rs b/crates/bevy_reflect/src/impls/std.rs index 27b1d58d05..baeb2999e3 100644 --- a/crates/bevy_reflect/src/impls/std.rs +++ b/crates/bevy_reflect/src/impls/std.rs @@ -13,13 +13,15 @@ use crate::{ ReflectFromReflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, ReflectSerialize, Set, SetInfo, TypeInfo, TypeParamInfo, TypePath, TypeRegistration, TypeRegistry, Typed, }; -use alloc::{borrow::Cow, collections::VecDeque}; +use alloc::{borrow::Cow, borrow::ToOwned, boxed::Box, collections::VecDeque, format, vec::Vec}; use bevy_reflect_derive::{impl_reflect, impl_reflect_opaque}; use core::{ any::Any, fmt, hash::{BuildHasher, Hash, Hasher}, }; + +#[cfg(feature = "std")] use std::path::Path; impl_reflect_opaque!(bool( @@ -89,6 +91,7 @@ impl_reflect_opaque!(::alloc::string::String( Deserialize, Default )); +#[cfg(feature = "std")] impl_reflect_opaque!(::std::path::PathBuf( Debug, Hash, @@ -114,6 +117,7 @@ impl_reflect_opaque!(::bevy_utils::Duration( Deserialize, Default )); +#[cfg(any(target_arch = "wasm32", feature = "std"))] impl_reflect_opaque!(::bevy_utils::Instant(Debug, Hash, PartialEq)); impl_reflect_opaque!(::core::num::NonZeroI128( Debug, @@ -205,7 +209,7 @@ impl_reflect_opaque!(::alloc::sync::Arc); // `Serialize` and `Deserialize` only for platforms supported by serde: // https://github.com/serde-rs/serde/blob/3ffb86fc70efd3d329519e2dddfa306cc04f167c/serde/src/de/impls.rs#L1732 -#[cfg(any(unix, windows))] +#[cfg(all(any(unix, windows), feature = "std"))] impl_reflect_opaque!(::std::ffi::OsString( Debug, Hash, @@ -213,7 +217,7 @@ impl_reflect_opaque!(::std::ffi::OsString( Serialize, Deserialize )); -#[cfg(not(any(unix, windows)))] +#[cfg(all(not(any(unix, windows)), feature = "std"))] impl_reflect_opaque!(::std::ffi::OsString(Debug, Hash, PartialEq)); impl_reflect_opaque!(::alloc::collections::BinaryHeap); @@ -235,8 +239,14 @@ macro_rules! impl_reflect_for_atomic { registration.insert::(FromType::::from_type()); registration.insert::(FromType::::from_type()); registration.insert::(FromType::::from_type()); - registration.insert::(FromType::::from_type()); - registration.insert::(FromType::::from_type()); + + // Serde only supports atomic types when the "std" feature is enabled + #[cfg(feature = "std")] + { + registration.insert::(FromType::::from_type()); + registration.insert::(FromType::::from_type()); + } + registration } } @@ -820,10 +830,13 @@ macro_rules! impl_reflect_for_hashmap { }; } +#[cfg(feature = "std")] impl_reflect_for_hashmap!(::std::collections::HashMap); +#[cfg(feature = "std")] impl_type_path!(::std::collections::hash_map::RandomState); +#[cfg(feature = "std")] impl_type_path!(::std::collections::HashMap); -#[cfg(feature = "functions")] +#[cfg(all(feature = "functions", feature = "std"))] crate::func::macros::impl_function_traits!(::std::collections::HashMap; < K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash, @@ -1049,9 +1062,11 @@ macro_rules! impl_reflect_for_hashset { impl_type_path!(::bevy_utils::NoOpHash); impl_type_path!(::bevy_utils::FixedState); +#[cfg(feature = "std")] impl_reflect_for_hashset!(::std::collections::HashSet); +#[cfg(feature = "std")] impl_type_path!(::std::collections::HashSet); -#[cfg(feature = "functions")] +#[cfg(all(feature = "functions", feature = "std"))] crate::func::macros::impl_function_traits!(::std::collections::HashSet; < V: Hash + Eq + FromReflect + TypePath + GetTypeRegistration, @@ -1970,6 +1985,7 @@ impl FromReflect for &'static str { #[cfg(feature = "functions")] crate::func::macros::impl_function_traits!(&'static str); +#[cfg(feature = "std")] impl PartialReflect for &'static Path { fn get_represented_type_info(&self) -> Option<&'static TypeInfo> { Some(::type_info()) @@ -2048,6 +2064,7 @@ impl PartialReflect for &'static Path { } } +#[cfg(feature = "std")] impl Reflect for &'static Path { fn into_any(self: Box) -> Box { self @@ -2079,6 +2096,7 @@ impl Reflect for &'static Path { } } +#[cfg(feature = "std")] impl Typed for &'static Path { fn type_info() -> &'static TypeInfo { static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new(); @@ -2086,6 +2104,7 @@ impl Typed for &'static Path { } } +#[cfg(feature = "std")] impl GetTypeRegistration for &'static Path { fn get_type_registration() -> TypeRegistration { let mut registration = TypeRegistration::of::(); @@ -2094,15 +2113,17 @@ impl GetTypeRegistration for &'static Path { } } +#[cfg(feature = "std")] impl FromReflect for &'static Path { fn from_reflect(reflect: &dyn PartialReflect) -> Option { reflect.try_downcast_ref::().copied() } } -#[cfg(feature = "functions")] +#[cfg(all(feature = "functions", feature = "std"))] crate::func::macros::impl_function_traits!(&'static Path); +#[cfg(feature = "std")] impl PartialReflect for Cow<'static, Path> { fn get_represented_type_info(&self) -> Option<&'static TypeInfo> { Some(::type_info()) @@ -2185,6 +2206,7 @@ impl PartialReflect for Cow<'static, Path> { } } +#[cfg(feature = "std")] impl Reflect for Cow<'static, Path> { fn into_any(self: Box) -> Box { self @@ -2216,6 +2238,7 @@ impl Reflect for Cow<'static, Path> { } } +#[cfg(feature = "std")] impl Typed for Cow<'static, Path> { fn type_info() -> &'static TypeInfo { static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new(); @@ -2223,15 +2246,18 @@ impl Typed for Cow<'static, Path> { } } +#[cfg(feature = "std")] impl_type_path!(::std::path::Path); impl_type_path!(::alloc::borrow::Cow<'a: 'static, T: ToOwned + ?Sized>); +#[cfg(feature = "std")] impl FromReflect for Cow<'static, Path> { fn from_reflect(reflect: &dyn PartialReflect) -> Option { Some(reflect.try_downcast_ref::()?.clone()) } } +#[cfg(feature = "std")] impl GetTypeRegistration for Cow<'static, Path> { fn get_type_registration() -> TypeRegistration { let mut registration = TypeRegistration::of::(); @@ -2243,7 +2269,7 @@ impl GetTypeRegistration for Cow<'static, Path> { } } -#[cfg(feature = "functions")] +#[cfg(all(feature = "functions", feature = "std"))] crate::func::macros::impl_function_traits!(Cow<'static, Path>); #[cfg(test)] diff --git a/crates/bevy_reflect/src/kind.rs b/crates/bevy_reflect/src/kind.rs index 2e3928162a..66de3291ea 100644 --- a/crates/bevy_reflect/src/kind.rs +++ b/crates/bevy_reflect/src/kind.rs @@ -1,3 +1,4 @@ +use alloc::boxed::Box; use derive_more::derive::{Display, Error}; #[cfg(feature = "functions")] diff --git a/crates/bevy_reflect/src/lib.rs b/crates/bevy_reflect/src/lib.rs index a5b278aeee..07a3c43c12 100644 --- a/crates/bevy_reflect/src/lib.rs +++ b/crates/bevy_reflect/src/lib.rs @@ -553,6 +553,8 @@ //! [`ArgList`]: crate::func::ArgList //! [derive `Reflect`]: derive@crate::Reflect +#![cfg_attr(not(feature = "std"), no_std)] + extern crate alloc; mod array; @@ -651,6 +653,18 @@ pub mod __macro_exports { DynamicTupleStruct, GetTypeRegistration, TypeRegistry, }; + /// Re-exports of items from the [`alloc`] crate. + /// + /// This is required because in `std` environments (e.g., the `std` feature is enabled) + /// the `alloc` crate may not have been included, making its namespace unreliable. + pub mod alloc_utils { + pub use ::alloc::{ + borrow::{Cow, ToOwned}, + boxed::Box, + string::ToString, + }; + } + /// A wrapper trait around [`GetTypeRegistration`]. /// /// This trait is used by the derive macro to recursively register all type dependencies. diff --git a/crates/bevy_reflect/src/list.rs b/crates/bevy_reflect/src/list.rs index 49a479154f..58fca368b8 100644 --- a/crates/bevy_reflect/src/list.rs +++ b/crates/bevy_reflect/src/list.rs @@ -1,3 +1,4 @@ +use alloc::{boxed::Box, vec::Vec}; use core::{ any::Any, fmt::{Debug, Formatter}, diff --git a/crates/bevy_reflect/src/map.rs b/crates/bevy_reflect/src/map.rs index 03a4a325ef..bafcaf528f 100644 --- a/crates/bevy_reflect/src/map.rs +++ b/crates/bevy_reflect/src/map.rs @@ -9,6 +9,7 @@ use crate::{ PartialReflect, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, Type, TypeInfo, TypePath, }; +use alloc::{boxed::Box, format, vec::Vec}; /// A trait used to power [map-like] operations via [reflection]. /// @@ -42,7 +43,7 @@ use crate::{ /// ``` /// /// [`HashMap`]: std::collections::HashMap -/// [`BTreeMap`]: std::collections::BTreeMap +/// [`BTreeMap`]: alloc::collections::BTreeMap /// [map-like]: https://doc.rust-lang.org/book/ch08-03-hash-maps.html /// [reflection]: crate pub trait Map: PartialReflect { diff --git a/crates/bevy_reflect/src/path/mod.rs b/crates/bevy_reflect/src/path/mod.rs index 9fc7d1b9f2..977882b93b 100644 --- a/crates/bevy_reflect/src/path/mod.rs +++ b/crates/bevy_reflect/src/path/mod.rs @@ -9,6 +9,7 @@ pub use parse::ParseError; use parse::PathParser; use crate::{PartialReflect, Reflect}; +use alloc::vec::Vec; use core::fmt; use derive_more::derive::{Display, From}; diff --git a/crates/bevy_reflect/src/reflect.rs b/crates/bevy_reflect/src/reflect.rs index 993366e61d..7ed380c98c 100644 --- a/crates/bevy_reflect/src/reflect.rs +++ b/crates/bevy_reflect/src/reflect.rs @@ -3,6 +3,7 @@ use crate::{ tuple_debug, tuple_struct_debug, DynamicTypePath, DynamicTyped, OpaqueInfo, ReflectKind, ReflectKindMismatchError, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypePath, Typed, }; +use alloc::boxed::Box; use core::{ any::{Any, TypeId}, fmt::Debug, @@ -319,17 +320,17 @@ where note = "consider annotating `{Self}` with `#[derive(Reflect)]`" )] pub trait Reflect: PartialReflect + DynamicTyped + Any { - /// Returns the value as a [`Box`][std::any::Any]. + /// Returns the value as a [`Box`][core::any::Any]. /// /// For remote wrapper types, this will return the remote type instead. fn into_any(self: Box) -> Box; - /// Returns the value as a [`&dyn Any`][std::any::Any]. + /// Returns the value as a [`&dyn Any`][core::any::Any]. /// /// For remote wrapper types, this will return the remote type instead. fn as_any(&self) -> &dyn Any; - /// Returns the value as a [`&mut dyn Any`][std::any::Any]. + /// Returns the value as a [`&mut dyn Any`][core::any::Any]. /// /// For remote wrapper types, this will return the remote type instead. fn as_any_mut(&mut self) -> &mut dyn Any; diff --git a/crates/bevy_reflect/src/remote.rs b/crates/bevy_reflect/src/remote.rs index 22e663b20d..a19d3bdb14 100644 --- a/crates/bevy_reflect/src/remote.rs +++ b/crates/bevy_reflect/src/remote.rs @@ -41,7 +41,7 @@ use crate::Reflect; /// ``` /// /// [reflectable]: Reflect -/// [`transmute`]: std::mem::transmute +/// [`transmute`]: core::mem::transmute /// [very unsafe]: https://doc.rust-lang.org/1.71.0/nomicon/transmutes.html /// [`FromReflect`]: crate::FromReflect pub trait ReflectRemote: Reflect { diff --git a/crates/bevy_reflect/src/serde/de/arrays.rs b/crates/bevy_reflect/src/serde/de/arrays.rs index 1e9dafae3c..f1e0d60dd6 100644 --- a/crates/bevy_reflect/src/serde/de/arrays.rs +++ b/crates/bevy_reflect/src/serde/de/arrays.rs @@ -2,6 +2,7 @@ use crate::{ serde::{de::registration_utils::try_get_registration, TypedReflectDeserializer}, ArrayInfo, DynamicArray, TypeRegistry, }; +use alloc::{string::ToString, vec::Vec}; use core::{fmt, fmt::Formatter}; use serde::de::{Error, SeqAccess, Visitor}; diff --git a/crates/bevy_reflect/src/serde/de/deserialize_with_registry.rs b/crates/bevy_reflect/src/serde/de/deserialize_with_registry.rs index ace4dc65b8..d0c9703d40 100644 --- a/crates/bevy_reflect/src/serde/de/deserialize_with_registry.rs +++ b/crates/bevy_reflect/src/serde/de/deserialize_with_registry.rs @@ -1,5 +1,6 @@ use crate::serde::de::error_utils::make_custom_error; use crate::{FromType, PartialReflect, TypeRegistry}; +use alloc::boxed::Box; use serde::Deserializer; /// Trait used to provide finer control when deserializing a reflected type with one of diff --git a/crates/bevy_reflect/src/serde/de/deserializer.rs b/crates/bevy_reflect/src/serde/de/deserializer.rs index a177772ce2..1c20eaad07 100644 --- a/crates/bevy_reflect/src/serde/de/deserializer.rs +++ b/crates/bevy_reflect/src/serde/de/deserializer.rs @@ -12,6 +12,7 @@ use crate::{ }, PartialReflect, ReflectDeserialize, TypeInfo, TypePath, TypeRegistration, TypeRegistry, }; +use alloc::boxed::Box; use core::{fmt, fmt::Formatter}; use serde::de::{DeserializeSeed, Error, IgnoredAny, MapAccess, Visitor}; @@ -219,7 +220,7 @@ impl<'de, P: ReflectDeserializerProcessor> DeserializeSeed<'de> for ReflectDeser /// # Example /// /// ``` -/// # use std::any::TypeId; +/// # use core::any::TypeId; /// # use serde::de::DeserializeSeed; /// # use bevy_reflect::prelude::*; /// # use bevy_reflect::{DynamicStruct, TypeRegistry, serde::TypedReflectDeserializer}; diff --git a/crates/bevy_reflect/src/serde/de/helpers.rs b/crates/bevy_reflect/src/serde/de/helpers.rs index bdb567a22e..c48f8f8352 100644 --- a/crates/bevy_reflect/src/serde/de/helpers.rs +++ b/crates/bevy_reflect/src/serde/de/helpers.rs @@ -1,3 +1,7 @@ +use alloc::{ + string::{String, ToString}, + vec::Vec, +}; use core::{ fmt, fmt::{Debug, Display, Formatter}, diff --git a/crates/bevy_reflect/src/serde/de/processor.rs b/crates/bevy_reflect/src/serde/de/processor.rs index 1d4d81f4b9..98bcfa09b5 100644 --- a/crates/bevy_reflect/src/serde/de/processor.rs +++ b/crates/bevy_reflect/src/serde/de/processor.rs @@ -1,4 +1,5 @@ use crate::{PartialReflect, TypeRegistration, TypeRegistry}; +use alloc::boxed::Box; /// Allows overriding the default deserialization behavior of /// [`ReflectDeserializer`] and [`TypedReflectDeserializer`] for specific diff --git a/crates/bevy_reflect/src/serde/de/struct_utils.rs b/crates/bevy_reflect/src/serde/de/struct_utils.rs index 8f3a3250ff..9ac56d9a4a 100644 --- a/crates/bevy_reflect/src/serde/de/struct_utils.rs +++ b/crates/bevy_reflect/src/serde/de/struct_utils.rs @@ -9,6 +9,7 @@ use crate::{ }, DynamicStruct, NamedField, StructInfo, StructVariantInfo, TypeRegistration, TypeRegistry, }; +use alloc::string::ToString; use core::slice::Iter; use serde::de::{Error, MapAccess, SeqAccess}; diff --git a/crates/bevy_reflect/src/serde/de/tuple_utils.rs b/crates/bevy_reflect/src/serde/de/tuple_utils.rs index 9c96d78a67..13a65b4dd6 100644 --- a/crates/bevy_reflect/src/serde/de/tuple_utils.rs +++ b/crates/bevy_reflect/src/serde/de/tuple_utils.rs @@ -6,6 +6,7 @@ use crate::{ DynamicTuple, TupleInfo, TupleStructInfo, TupleVariantInfo, TypeRegistration, TypeRegistry, UnnamedField, }; +use alloc::string::ToString; use serde::de::{Error, SeqAccess}; use super::ReflectDeserializerProcessor; diff --git a/crates/bevy_reflect/src/serde/ser/serializable.rs b/crates/bevy_reflect/src/serde/ser/serializable.rs index b7420280a8..6a8a4c978f 100644 --- a/crates/bevy_reflect/src/serde/ser/serializable.rs +++ b/crates/bevy_reflect/src/serde/ser/serializable.rs @@ -1,3 +1,4 @@ +use alloc::boxed::Box; use core::ops::Deref; /// A type-erased serializable value. diff --git a/crates/bevy_reflect/src/serde/ser/serialize_with_registry.rs b/crates/bevy_reflect/src/serde/ser/serialize_with_registry.rs index 5d6c82efcd..25922a5bd9 100644 --- a/crates/bevy_reflect/src/serde/ser/serialize_with_registry.rs +++ b/crates/bevy_reflect/src/serde/ser/serialize_with_registry.rs @@ -1,4 +1,5 @@ use crate::{FromType, Reflect, TypeRegistry}; +use alloc::boxed::Box; use serde::{Serialize, Serializer}; /// Trait used to provide finer control when serializing a reflected type with one of diff --git a/crates/bevy_reflect/src/serde/type_data.rs b/crates/bevy_reflect/src/serde/type_data.rs index 35366b3909..de88f99831 100644 --- a/crates/bevy_reflect/src/serde/type_data.rs +++ b/crates/bevy_reflect/src/serde/type_data.rs @@ -1,4 +1,5 @@ use crate::Reflect; +use alloc::boxed::Box; use bevy_utils::{hashbrown::hash_map::Iter, HashMap}; /// Contains data relevant to the automatic reflect powered (de)serialization of a type. @@ -26,7 +27,7 @@ impl SerializationData { /// # Example /// /// ``` - /// # use std::any::TypeId; + /// # use core::any::TypeId; /// # use bevy_reflect::{Reflect, Struct, TypeRegistry, serde::SerializationData}; /// #[derive(Reflect)] /// struct MyStruct { @@ -66,7 +67,7 @@ impl SerializationData { /// # Example /// /// ``` - /// # use std::any::TypeId; + /// # use core::any::TypeId; /// # use bevy_reflect::{Reflect, Struct, TypeRegistry, serde::SerializationData}; /// #[derive(Reflect)] /// struct MyStruct { diff --git a/crates/bevy_reflect/src/set.rs b/crates/bevy_reflect/src/set.rs index 50c5a752d9..be66c53318 100644 --- a/crates/bevy_reflect/src/set.rs +++ b/crates/bevy_reflect/src/set.rs @@ -1,3 +1,4 @@ +use alloc::{boxed::Box, format, vec::Vec}; use core::fmt::{Debug, Formatter}; use bevy_reflect_derive::impl_type_path; @@ -42,7 +43,7 @@ use crate::{ /// ``` /// /// [`HashSet`]: std::collections::HashSet -/// [`BTreeSet`]: std::collections::BTreeSet +/// [`BTreeSet`]: alloc::collections::BTreeSet /// [set-like]: https://doc.rust-lang.org/stable/std/collections/struct.HashSet.html /// [reflection]: crate pub trait Set: PartialReflect { diff --git a/crates/bevy_reflect/src/std_traits.rs b/crates/bevy_reflect/src/std_traits.rs index 2f9b84735e..cad001132b 100644 --- a/crates/bevy_reflect/src/std_traits.rs +++ b/crates/bevy_reflect/src/std_traits.rs @@ -1,4 +1,5 @@ use crate::{FromType, Reflect}; +use alloc::boxed::Box; /// A struct used to provide the default value of a type. /// diff --git a/crates/bevy_reflect/src/struct_trait.rs b/crates/bevy_reflect/src/struct_trait.rs index 93fa1fac67..9ee7c11d47 100644 --- a/crates/bevy_reflect/src/struct_trait.rs +++ b/crates/bevy_reflect/src/struct_trait.rs @@ -6,7 +6,7 @@ use crate::{ ApplyError, Generics, NamedField, PartialReflect, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, Type, TypeInfo, TypePath, }; -use alloc::{borrow::Cow, sync::Arc}; +use alloc::{borrow::Cow, boxed::Box, sync::Arc, vec::Vec}; use bevy_reflect_derive::impl_type_path; use bevy_utils::HashMap; use core::{ diff --git a/crates/bevy_reflect/src/tuple.rs b/crates/bevy_reflect/src/tuple.rs index 5a576e2ffa..9790990a26 100644 --- a/crates/bevy_reflect/src/tuple.rs +++ b/crates/bevy_reflect/src/tuple.rs @@ -8,6 +8,7 @@ use crate::{ ReflectMut, ReflectOwned, ReflectRef, Type, TypeInfo, TypePath, TypeRegistration, TypeRegistry, Typed, UnnamedField, }; +use alloc::{boxed::Box, vec, vec::Vec}; use core::{ any::Any, fmt::{Debug, Formatter}, @@ -376,7 +377,7 @@ impl FromIterator> for DynamicTuple { impl IntoIterator for DynamicTuple { type Item = Box; - type IntoIter = alloc::vec::IntoIter; + type IntoIter = vec::IntoIter; fn into_iter(self) -> Self::IntoIter { self.fields.into_iter() @@ -697,6 +698,7 @@ macro_rules! impl_type_path_tuple { $(#[$meta])* impl <$param: TypePath> TypePath for ($param,) { fn type_path() -> &'static str { + use $crate::__macro_exports::alloc_utils::ToOwned; static CELL: GenericTypePathCell = GenericTypePathCell::new(); CELL.get_or_insert::(|| { "(".to_owned() + $param::type_path() + ",)" @@ -704,6 +706,7 @@ macro_rules! impl_type_path_tuple { } fn short_type_path() -> &'static str { + use $crate::__macro_exports::alloc_utils::ToOwned; static CELL: GenericTypePathCell = GenericTypePathCell::new(); CELL.get_or_insert::(|| { "(".to_owned() + $param::short_type_path() + ",)" @@ -716,6 +719,7 @@ macro_rules! impl_type_path_tuple { $(#[$meta])* impl <$($param: TypePath,)* $last: TypePath> TypePath for ($($param,)* $last) { fn type_path() -> &'static str { + use $crate::__macro_exports::alloc_utils::ToOwned; static CELL: GenericTypePathCell = GenericTypePathCell::new(); CELL.get_or_insert::(|| { "(".to_owned() $(+ $param::type_path() + ", ")* + $last::type_path() + ")" @@ -723,6 +727,7 @@ macro_rules! impl_type_path_tuple { } fn short_type_path() -> &'static str { + use $crate::__macro_exports::alloc_utils::ToOwned; static CELL: GenericTypePathCell = GenericTypePathCell::new(); CELL.get_or_insert::(|| { "(".to_owned() $(+ $param::short_type_path() + ", ")* + $last::short_type_path() + ")" diff --git a/crates/bevy_reflect/src/tuple_struct.rs b/crates/bevy_reflect/src/tuple_struct.rs index 79f3d46ac7..3445bfb6c8 100644 --- a/crates/bevy_reflect/src/tuple_struct.rs +++ b/crates/bevy_reflect/src/tuple_struct.rs @@ -8,7 +8,7 @@ use crate::{ ApplyError, DynamicTuple, Generics, PartialReflect, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, Tuple, Type, TypeInfo, TypePath, UnnamedField, }; -use alloc::sync::Arc; +use alloc::{boxed::Box, sync::Arc, vec::Vec}; use core::{ fmt::{Debug, Formatter}, slice::Iter, diff --git a/crates/bevy_reflect/src/type_info.rs b/crates/bevy_reflect/src/type_info.rs index 3493e1e06d..d396a6ba92 100644 --- a/crates/bevy_reflect/src/type_info.rs +++ b/crates/bevy_reflect/src/type_info.rs @@ -32,7 +32,7 @@ use derive_more::derive::{Display, Error}; /// # Example /// /// ``` -/// # use std::any::Any; +/// # use core::any::Any; /// # use bevy_reflect::{DynamicTypePath, NamedField, PartialReflect, Reflect, ReflectMut, ReflectOwned, ReflectRef, StructInfo, TypeInfo, TypePath, OpaqueInfo, ApplyError}; /// # use bevy_reflect::utility::NonGenericTypeInfoCell; /// use bevy_reflect::Typed; @@ -498,7 +498,7 @@ macro_rules! impl_type_methods { /// The [`TypeId`] of this type. /// - /// [`TypeId`]: std::any::TypeId + /// [`TypeId`]: core::any::TypeId pub fn type_id(&self) -> ::core::any::TypeId { self.ty().id() } @@ -528,7 +528,7 @@ macro_rules! impl_type_methods { /// and does not verify they share the same [`TypePath`] /// (though it implies they do). /// - /// [`TypeId`]: std::any::TypeId + /// [`TypeId`]: core::any::TypeId /// [`TypePath`]: crate::type_path::TypePath pub fn is(&self) -> bool { self.ty().is::() diff --git a/crates/bevy_reflect/src/type_info_stack.rs b/crates/bevy_reflect/src/type_info_stack.rs index c2806553dd..8f1161485f 100644 --- a/crates/bevy_reflect/src/type_info_stack.rs +++ b/crates/bevy_reflect/src/type_info_stack.rs @@ -4,6 +4,9 @@ use core::{ slice::Iter, }; +#[cfg(not(feature = "std"))] +use alloc::{boxed::Box, format, vec}; + /// Helper struct for managing a stack of [`TypeInfo`] instances. /// /// This is useful for tracking the type hierarchy when serializing and deserializing types. diff --git a/crates/bevy_reflect/src/type_path.rs b/crates/bevy_reflect/src/type_path.rs index 1287eeb882..3acc9bc94a 100644 --- a/crates/bevy_reflect/src/type_path.rs +++ b/crates/bevy_reflect/src/type_path.rs @@ -2,7 +2,7 @@ use core::fmt; /// A static accessor to type paths and names. /// -/// The engine uses this trait over [`std::any::type_name`] for stability and flexibility. +/// The engine uses this trait over [`core::any::type_name`] for stability and flexibility. /// /// This trait is automatically implemented by the `#[derive(Reflect)]` macro /// and allows type path information to be processed without an instance of that type. @@ -16,7 +16,7 @@ use core::fmt; /// Certain parts of the engine, e.g. [(de)serialization], rely on type paths as identifiers /// for matching dynamic values to concrete types. /// -/// Using [`std::any::type_name`], a scene containing `my_crate::foo::MyComponent` would break, +/// Using [`core::any::type_name`], a scene containing `my_crate::foo::MyComponent` would break, /// failing to deserialize if the component was moved from the `foo` module to the `bar` module, /// becoming `my_crate::bar::MyComponent`. /// This trait, through attributes when deriving itself or [`Reflect`], can ensure breaking changes are avoidable. diff --git a/crates/bevy_reflect/src/type_registry.rs b/crates/bevy_reflect/src/type_registry.rs index 1b0fd84c71..609c66d185 100644 --- a/crates/bevy_reflect/src/type_registry.rs +++ b/crates/bevy_reflect/src/type_registry.rs @@ -1,5 +1,6 @@ use crate::{serde::Serializable, FromReflect, Reflect, TypeInfo, TypePath, Typed}; use alloc::sync::Arc; +use alloc::{boxed::Box, string::String}; use bevy_ptr::{Ptr, PtrMut}; use bevy_utils::{HashMap, HashSet, TypeIdMap}; use core::{ @@ -9,8 +10,13 @@ use core::{ }; use downcast_rs::{impl_downcast, Downcast}; use serde::Deserialize; + +#[cfg(feature = "std")] use std::sync::{PoisonError, RwLock, RwLockReadGuard, RwLockWriteGuard}; +#[cfg(not(feature = "std"))] +use spin::rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard}; + /// A registry of [reflected] types. /// /// This struct is used as the central store for type information. @@ -40,12 +46,12 @@ pub struct TypeRegistryArc { impl Debug for TypeRegistryArc { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - self.internal - .read() - .unwrap_or_else(PoisonError::into_inner) - .type_path_to_id - .keys() - .fmt(f) + let read_lock = self.internal.read(); + + #[cfg(feature = "std")] + let read_lock = read_lock.unwrap_or_else(PoisonError::into_inner); + + read_lock.type_path_to_id.keys().fmt(f) } } @@ -131,7 +137,7 @@ impl TypeRegistry { /// # Example /// /// ``` - /// # use std::any::TypeId; + /// # use core::any::TypeId; /// # use bevy_reflect::{Reflect, TypeRegistry, std_traits::ReflectDefault}; /// #[derive(Reflect, Default)] /// #[reflect(Default)] @@ -428,14 +434,22 @@ impl TypeRegistry { impl TypeRegistryArc { /// Takes a read lock on the underlying [`TypeRegistry`]. pub fn read(&self) -> RwLockReadGuard<'_, TypeRegistry> { - self.internal.read().unwrap_or_else(PoisonError::into_inner) + let read_lock = self.internal.read(); + + #[cfg(feature = "std")] + let read_lock = read_lock.unwrap_or_else(PoisonError::into_inner); + + read_lock } /// Takes a write lock on the underlying [`TypeRegistry`]. pub fn write(&self) -> RwLockWriteGuard<'_, TypeRegistry> { - self.internal - .write() - .unwrap_or_else(PoisonError::into_inner) + let write_lock = self.internal.write(); + + #[cfg(feature = "std")] + let write_lock = write_lock.unwrap_or_else(PoisonError::into_inner); + + write_lock } } @@ -746,7 +760,7 @@ impl Deserialize<'a> + Reflect> FromType for ReflectDeserialize { /// ``` /// use bevy_reflect::{TypeRegistry, Reflect, ReflectFromPtr}; /// use bevy_ptr::Ptr; -/// use std::ptr::NonNull; +/// use core::ptr::NonNull; /// /// #[derive(Reflect)] /// struct Reflected(String); @@ -757,7 +771,7 @@ impl Deserialize<'a> + Reflect> FromType for ReflectDeserialize { /// let mut value = Reflected("Hello world!".to_string()); /// let value = Ptr::from(&value); /// -/// let reflect_data = type_registry.get(std::any::TypeId::of::()).unwrap(); +/// let reflect_data = type_registry.get(core::any::TypeId::of::()).unwrap(); /// let reflect_from_ptr = reflect_data.data::().unwrap(); /// // SAFE: `value` is of type `Reflected`, which the `ReflectFromPtr` was created for /// let value = unsafe { reflect_from_ptr.as_reflect(value) }; diff --git a/crates/bevy_reflect/src/utility.rs b/crates/bevy_reflect/src/utility.rs index f525572671..5395b2b28a 100644 --- a/crates/bevy_reflect/src/utility.rs +++ b/crates/bevy_reflect/src/utility.rs @@ -1,13 +1,19 @@ //! Helpers for working with Bevy reflection. use crate::TypeInfo; +use alloc::boxed::Box; use bevy_utils::{FixedState, NoOpHash, TypeIdMap}; use core::{ any::{Any, TypeId}, hash::BuildHasher, }; + +#[cfg(feature = "std")] use std::sync::{OnceLock, PoisonError, RwLock}; +#[cfg(not(feature = "std"))] +use spin::{Once as OnceLock, RwLock}; + /// A type that can be stored in a ([`Non`])[`GenericTypeCell`]. /// /// [`Non`]: NonGenericTypeCell @@ -22,6 +28,7 @@ pub struct TypePathComponent; mod sealed { use super::{TypeInfo, TypePathComponent, TypedProperty}; + use alloc::string::String; pub trait Sealed {} @@ -48,7 +55,7 @@ mod sealed { /// ## Example /// /// ``` -/// # use std::any::Any; +/// # use core::any::Any; /// # use bevy_reflect::{DynamicTypePath, NamedField, PartialReflect, Reflect, ReflectMut, ReflectOwned, ReflectRef, StructInfo, Typed, TypeInfo, TypePath, ApplyError}; /// use bevy_reflect::utility::NonGenericTypeInfoCell; /// @@ -114,7 +121,11 @@ impl NonGenericTypeCell { where F: FnOnce() -> T::Stored, { - self.0.get_or_init(f) + #[cfg(feature = "std")] + return self.0.get_or_init(f); + + #[cfg(not(feature = "std"))] + return self.0.call_once(f); } } @@ -137,7 +148,7 @@ impl Default for NonGenericTypeCell { /// Implementing [`TypeInfo`] with generics. /// /// ``` -/// # use std::any::Any; +/// # use core::any::Any; /// # use bevy_reflect::{DynamicTypePath, PartialReflect, Reflect, ReflectMut, ReflectOwned, ReflectRef, TupleStructInfo, Typed, TypeInfo, TypePath, UnnamedField, ApplyError, Generics, TypeParamInfo}; /// use bevy_reflect::utility::GenericTypeInfoCell; /// @@ -186,7 +197,7 @@ impl Default for NonGenericTypeCell { /// Implementing [`TypePath`] with generics. /// /// ``` -/// # use std::any::Any; +/// # use core::any::Any; /// # use bevy_reflect::TypePath; /// use bevy_reflect::utility::GenericTypePathCell; /// @@ -247,11 +258,12 @@ impl GenericTypeCell { /// /// This method will then return the correct [`TypedProperty`] reference for the given type `T`. fn get_by_type_id(&self, type_id: TypeId) -> Option<&T::Stored> { - self.0 - .read() - .unwrap_or_else(PoisonError::into_inner) - .get(&type_id) - .copied() + let read_lock = self.0.read(); + + #[cfg(feature = "std")] + let read_lock = read_lock.unwrap_or_else(PoisonError::into_inner); + + read_lock.get(&type_id).copied() } /// Returns a reference to the [`TypedProperty`] stored in the cell. @@ -269,9 +281,14 @@ impl GenericTypeCell { } fn insert_by_type_id(&self, type_id: TypeId, value: T::Stored) -> &T::Stored { - self.0 - .write() - .unwrap_or_else(PoisonError::into_inner) + let write_lock = self.0.write(); + + #[cfg(feature = "std")] + let write_lock = write_lock.unwrap_or_else(PoisonError::into_inner); + + let mut write_lock = write_lock; + + write_lock .entry(type_id) .insert({ // We leak here in order to obtain a `&'static` reference. diff --git a/tools/ci/src/commands/compile_check_no_std.rs b/tools/ci/src/commands/compile_check_no_std.rs index 82ba3d4688..a35186c81e 100644 --- a/tools/ci/src/commands/compile_check_no_std.rs +++ b/tools/ci/src/commands/compile_check_no_std.rs @@ -62,6 +62,22 @@ impl Prepare for CompileCheckNoStdCommand { "Please fix compiler errors in output above for bevy_mikktspace no_std compatibility.", )); + commands.push(PreparedCommand::new::( + cmd!( + sh, + "cargo check -p bevy_mikktspace --no-default-features --features libm --target {target}" + ), + "Please fix compiler errors in output above for bevy_mikktspace no_std compatibility.", + )); + + commands.push(PreparedCommand::new::( + cmd!( + sh, + "cargo check -p bevy_reflect --no-default-features --target {target}" + ), + "Please fix compiler errors in output above for bevy_reflect no_std compatibility.", + )); + commands.push(PreparedCommand::new::( cmd!( sh,