Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modify derive_label to support no_std environments #15465

Merged
merged 2 commits into from
Sep 27, 2024

Conversation

bushrat011899
Copy link
Contributor

Objective

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.

We can't generate code that uses `::std::boxed::Box` in `no_std` environments, but we also can't rely on `::alloc::boxed::Box`, 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.
@bushrat011899 bushrat011899 added C-Feature A new feature, making something new possible D-Trivial Nice and easy! A great choice to get started with Bevy A-Utils Utility functions and types X-Contentious There are nontrivial implications that should be thought through S-Needs-Review Needs reviewer attention (from anyone!) to move forward D-Macros Code that generates Rust code labels Sep 27, 2024
fn dyn_clone(&self) -> ::std::boxed::Box<dyn #trait_path> {
::std::boxed::Box::new(::core::clone::Clone::clone(self))
}
const _: () = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this is needed? 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you check the description of the PR the goal is to allow invoking this macro in no_std crates, which is required for Bevy to become no_std.

We would normally use the fully qualified name:

::std::boxed::Box

However, in no_std we can't use the std namespace, so instead we need to use the original definition of Box in the alloc crate:

::alloc::boxed::Box

But that also doesn't work, because access to the alloc namespace requires explicitly linking it in the end-user's crate:

extern crate alloc;

So we need to include that extern statement. However, we can't place it in the global namespace, because it would then clash with other macro invocations.

To ensure alloc is available, but also prevent its name from clashing, we place the implementation inside an anonymous constant:

const _: () = {
    // private namespace so no clashes
};

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just not understand why code put in const _: () = { ... }. Thanks for detailed explanation!

@alice-i-cecile alice-i-cecile added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Sep 27, 2024
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Sep 27, 2024
Merged via the queue into bevyengine:main with commit 6963b58 Sep 27, 2024
27 checks passed
rudderbucky pushed a commit to rudderbucky/bevy that referenced this pull request Sep 27, 2024
)

# Objective

- Contributes to bevyengine#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>
robtfm pushed a commit to robtfm/bevy that referenced this pull request Oct 4, 2024
)

# Objective

- Contributes to bevyengine#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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Utils Utility functions and types C-Feature A new feature, making something new possible D-Macros Code that generates Rust code D-Trivial Nice and easy! A great choice to get started with Bevy S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it X-Contentious There are nontrivial implications that should be thought through
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants