mirror of
https://github.com/bevyengine/bevy
synced 2024-11-21 12:13:25 +00:00
Modify derive_label
to support no_std
environments (#15465)
# Objective - Contributes to #15460 ## Solution - Wrap `derive_label` `quote!` in an anonymous constant which contains an `extern crate alloc` statement, allowing use of the `alloc` namespace even when a user has not brought in the crate themselves. ## Testing - CI passed locally. ## Notes We can't generate code that uses `::std::boxed::Box` in `no_std` environments, but we also can't rely on `::alloc::boxed::Box` either, since the user might not have declared `extern crate alloc`. To resolve this, the generated code is wrapped in an anonymous constant which contains the `extern crate alloc` invocation. This does mean the macro is no longer hygienic against cases where the user provides an alternate `alloc` crate, however I believe this is an acceptable compromise. Additionally, this crate itself doesn't need to be `no_std`, it just needs to _generate_ `no_std` compatible code. --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
This commit is contained in:
parent
60cf7ca025
commit
6963b58eba
1 changed files with 17 additions and 12 deletions
|
@ -81,21 +81,26 @@ pub fn derive_label(
|
|||
.unwrap(),
|
||||
);
|
||||
quote! {
|
||||
impl #impl_generics #trait_path for #ident #ty_generics #where_clause {
|
||||
fn dyn_clone(&self) -> ::std::boxed::Box<dyn #trait_path> {
|
||||
::std::boxed::Box::new(::core::clone::Clone::clone(self))
|
||||
}
|
||||
// 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 as_dyn_eq(&self) -> &dyn #dyn_eq_path {
|
||||
self
|
||||
}
|
||||
impl #impl_generics #trait_path for #ident #ty_generics #where_clause {
|
||||
fn dyn_clone(&self) -> alloc::boxed::Box<dyn #trait_path> {
|
||||
alloc::boxed::Box::new(::core::clone::Clone::clone(self))
|
||||
}
|
||||
|
||||
fn dyn_hash(&self, mut state: &mut dyn ::core::hash::Hasher) {
|
||||
let ty_id = ::core::any::TypeId::of::<Self>();
|
||||
::core::hash::Hash::hash(&ty_id, &mut state);
|
||||
::core::hash::Hash::hash(self, &mut state);
|
||||
fn as_dyn_eq(&self) -> &dyn #dyn_eq_path {
|
||||
self
|
||||
}
|
||||
|
||||
fn dyn_hash(&self, mut state: &mut dyn ::core::hash::Hasher) {
|
||||
let ty_id = ::core::any::TypeId::of::<Self>();
|
||||
::core::hash::Hash::hash(&ty_id, &mut state);
|
||||
::core::hash::Hash::hash(self, &mut state);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue