# Objective
Part of #11590.
## Solution
Remove most of the `#[expect(unsafe_op_in_unsafe_fn)]` in bevy_ecs and
add unsafe blocks/safety comments where needed. Doesn't yet remove the
exceptions from `bevy_ecs::storage`, `bevy_ecs::query` and
`bevy_ecs::system::system_param`.
---------
Co-authored-by: Trashtalk217 <trashtalk217@gmail.com>
# Objective
Currently, when deriving `Bundle`[^1], and using the
`clippy::mem_forget` lint from the `clippy::restricted` group, the lint
will fire:
```rs
#![warn(clippy::mem_forget)]
#[derive(Bundle);
struct MyStruct;
```
This is because `Bundle` utilizes the
[`deconstruct_moving_ptr`](https://docs.rs/bevy/latest/bevy/ecs/ptr/macro.deconstruct_moving_ptr.html)
macro from `bevy_ptr`. This macro, in turn, moves the fields from
`MovingPtr` out, and needs to call `core::mem::forget` on the original
value, in order to avoid the freeing of used memory.
Because this is inside a `derive` macro, the lint is fired in the
*calling code*, rather than in the bevy crate.
Additionally, since the code is generated in the *implementation of the
trait*, rather than in the struct, it's not simply enough to add an
expect attribute for the lint above the derive.
This PR simply allows the macro to be called without firing the lint.
[^1]: There may be other traits that cause the same behavior, but this
is the one that motivated this PR.
## Solution
Add an `expect(clippy::mem_forget)` attribute to all `mem::forget` calls
in `deconstruct_moving_ptr`.
It needs to be an expect rather than an allow because otherwise
`clippy::allow_attributes` might fire.
## Testing
Run the example code above with the modified crate.
Co-authored-by: Leandro Vandari <leandrovandari@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
Fix typos and other small issues in the documentation. I can drop the
changes to `bevy_reflect`'s and `bevy_anti_alias`'s crate descriptions
if it's a problem.
# Objective
- `MovingPtr::assign_to` is currently unsound if the destructor of
`*dst` panics because it will leave it populated with the old value
whose destructor panicked. When the owner of `*dst` then drops it it
will result in a double drop.
- Fix this unsoundness, fixes#23500
## Solution
- Use a drop guard to ensure that no matter what happens when dropping
`*dst`, it will be overwritten with the value from `self.` This has the
same semantics as normal assignments except it will prevent generating
multiple `memcpy`s.
- ~~Rewrite the method to use a normal assignment to the reference so
that the language itself takes care of this issue.~~ This ended up
making two `memcpy`s
## Testing
- A regression test has been added
# Objective
- Improve declarative macro hygiene.
- Fix declarative macros using non-imported items.
- `AnimatedField` is unqualified in the `animated_field` macro.
- `offset_of` is unqualified in the `impl_atomic_pod` macro.
- `format` is unqualified in `hash_error` macro (requires import in
`no_std`).
## Solution
- Qualify unqualified items and use absolute paths in every public
(`#[macro_export]`) `macro_rules`.
- Re-export `format` in `bevy_reflect::__macro_exports::alloc_utils`.
## Testing
- Ran `cargo run -p ci -- compile`
# Objective
Enables accessing slices from tables directly via Queries.
Fixes: #21861
## Solution
One new trait:
- `ContiguousQueryData` allows to fetch all values from tables all at
once (an implementation for `&T` returns a slice of components in the
set table, for `&mut T` returns a mutable slice of components in the set
table as well as a struct with methods to set update ticks (to match the
`fetch` implementation))
Methods `contiguous_iter`, `contiguous_iter_mut` and similar in `Query`
and `QueryState` making possible to iterate using these traits.
Macro `QueryData` was updated to support contiguous items when
`contiguous(target)` attribute is added (a target can be `all`,
`mutable` and `immutable`, refer to the `custom_query_param` example)
## Testing
- `sparse_set_contiguous_query` test verifies that you can't use
`next_contiguous` with sparse set components
- `test_contiguous_query_data` test verifies that returned values are
valid
- `base_contiguous` benchmark (file is named
`iter_simple_contiguous.rs`)
- `base_no_detection` benchmark (file is named
`iter_simple_no_detection.rs`)
- `base_no_detection_contiguous` benchmark (file is named
`iter_simple_no_detection_contiguous.rs`)
- `base_contiguous_avx2` benchmark (file is named
`iter_simple_contiguous_avx2.rs`)
---
## Showcase
Examples `contiguous_query`, `custom_query_param`
### Example
```rust
// - self.0 is a World
// - self.1 is a QueryState
// - velocity is a slice of components with Vec3 inside.
// - position is a data structure which implements Deref/DerefMut and IntoIterator methods to access the slice
// as well as mechanism to update update ticks (which it does automatically on dereference),
// which may be bypassed via `bypass_change_detection` methods.
for (velocity, mut position) in self.1.contiguous_iter_mut(&mut self.0).unwrap() {
assert!(velocity.len() == position.len());
for (v, p) in velocity.iter().zip(position.iter_mut()) {
p.0 += v.0;
}
}
```
### Benchmarks
Code for `base` benchmark:
```rust
#[derive(Component, Copy, Clone)]
struct Transform(Mat4);
#[derive(Component, Copy, Clone)]
struct Position(Vec3);
#[derive(Component, Copy, Clone)]
struct Rotation(Vec3);
#[derive(Component, Copy, Clone)]
struct Velocity(Vec3);
pub struct Benchmark<'w>(World, QueryState<(&'w Velocity, &'w mut Position)>);
impl<'w> Benchmark<'w> {
pub fn new() -> Self {
let mut world = World::new();
world.spawn_batch(core::iter::repeat_n(
(
Transform(Mat4::from_scale(Vec3::ONE)),
Position(Vec3::X),
Rotation(Vec3::X),
Velocity(Vec3::X),
),
10_000,
));
let query = world.query::<(&Velocity, &mut Position)>();
Self(world, query)
}
#[inline(never)]
pub fn run(&mut self) {
for (velocity, mut position) in self.1.iter_mut(&mut self.0) {
position.0 += velocity.0;
}
}
}
```
Iterating over 10000 entities from **a single** table and increasing a
3-dimensional vector from component `Position` by a 3-dimensional vector
from component `Velocity`
| Name | Time | Time (AVX2) | Description |
|------------------------------|-----------|-------------|--------------------------------------------------------------------|
| base | 5.5828 µs | 5.5122 µs | Iteration over components |
| base_contiguous | 4.8825 µs | 1.8665 µs | Iteration over contiguous
chunks |
| base_contiguous_avx2 | 2.0740 µs | 1.8665 µs | Iteration over
contiguous chunks with enforced avx2 optimizations |
| base_no_detection | 4.8065 µs | 4.7723 µs | Iteration over components
while bypassing change detection through `bypass_change_detection()`
method |
| base_no_detection_contiguous | 4.3979 µs | 1.5797 µs | Iteration over
components without registering update ticks |
Using contiguous 'iterator' makes the program a little bit faster and it
can be further vectorized to make it even faster
Bump version after release
This PR has been auto-generated
---------
Co-authored-by: Bevy Auto Releaser <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: François Mockers <francois.mockers@vleue.com>
# Objective
Fixes#22059
## Solution
Just `#[derive(Clone, Copy)]` on `ConstNonNull` since it`s just a
wrapper around `NonNull` which implements them
## Testing
Just tested if it compiles and functions as it should
# Objective
- `bevy_ptr::dangling_with_align()` is only used once, in `bevy_ecs`'s
`BlobArray::with_capacity()`, and it isn't generally useful outside of
the engine's internals. We can remove the function and inline its
implementation into its call site.
- Additionally, `bevy_ptr::dangling_with_align()` has a TODO comment
that was leftover from
https://github.com/bevyengine/bevy/pull/15311#discussion_r1768091379,
where it was suggested that `dangling_with_align()` should use
`without_provenance()`.
- `with_addr()`, mentioned in the TODO comment, could also be used, but
it's a more roundabout solution. The reason it was mentioned was because
the original author thought it would be stabilized before
`without_provenance()`.
## Solution
- Remove `dangling_with_align()`.
- Replace its usage with `NonNull::without_provenance()` (since it is
now stable and doesn't require `unsafe` or pointer math)
## Testing
- I ran Miri with strict provenance checking enabled to ensure the
behavior is maintained.
- `MIRIFLAGS="-Zmiri-strict-provenance" cargo +nightly miri test`
## But what is this provenance thingy?
[The official docs provide a more in-depth
explanation](https://doc.rust-lang.org/stable/std/ptr/index.html#provenance),
but basically a pointer is more than just a number referring to a memory
address. Pointers have _permissions_ associated with them that track:
- What set of memory addresses are allowed to be accessed
- When the pointer is allowed to access those addresses
- If the pointer is allowed to mutate the memory, or just read it
These permissions are pointer provenance. They aren't stored at runtime,
the Rust compiler doesn't know them at compile time! Miri is the only
tool that I know of that tracks provenance, which it uses to ensure
pointers adheres to their spatial, temporal, and mutability permissions.
That's why I mentioned Miri in the Testing section. :)
# Objective
- Although unsafe, `ThinSlicePtr::get()` doesn't signal that it doesn't
perform bounds checking unless you are familiar with the API.
- `ThinSlicePtr::get()` takes `self`, not `&self`, meaning it consumes
the `ThinSlicePtr` each time `get()` is called. This does not match the
behavior of
[`slice.get()`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.get),
which takes `&self`.
- This small issue was hidden by the fact that `ThinSlicePtr` implements
`Copy`. This isn't a large issue because it all compiles down to the
same machine code, but there's no point to `get()` requiring `self`.
- `ThinSlicePtr` could use better documentation, and could be improved a
little in some areas.
## Solution
- Rename `ThinSlicePtr::get()` to `get_unchecked()`, making the API
mirror
[`slice.get_unchecked()`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.get_unchecked).
The old `get()` is kept as a deprecated method, to be removed in 1.19.0.
- Make the new `slice.get_unchecked()` take `&self` rather than `self`.
- Add more documentation and slightly re-arrange code, while maintaining
original behavior.
## Testing
- Any unintentional changes should be caught by the Rust Compiler and
Miri!
---------
Co-authored-by: François Mockers <francois.mockers@vleue.com>
# Objective
Simplify implementation of `debug_ensure_aligned`.
The code has a comment asking for the implementation to be replaced when
`ptr::is_aligned_to` is stable. While `is_aligned_to` hasn't been
stabilized, `ptr::is_aligned` has, and is what we want here anyway.
## Solution
Use `ptr::is_aligned`.
## Objective
Fixes#21303 (but does not add any testing that similar issues will not
recur).
## Solution
Globally replace `feature(doc_auto_cfg)` with `feature(doc_cfg)`.
## Testing
Tested that `RUSTDOCFLAGS=--cfg=docsrs cargo +nightly doc -p
bevy_platform` succeeds. This is not a test of all documentation builds,
but I do not know of a way to do that until bevy’s dependencies catch
up.
# Objective
The 0.17 release candidate process has been started. We should be able
to start merging PRs scheduled for 0.18 now.
## Solution
Update the crate versions all to `0.18.0-dev`
# Objective
Make it possible to call `deconstruct_moving_ptr` with safe code. It
currently needs to be `unsafe` because you can pass the same field name
multiple times and cause mutable aliasing.
Fix some other small issues:
* Allow the trailing comma to be omitted
* Prevent passing a `&mut MovingPtr` or `&MovingPtr`, which would still
call `move_field` but would forget the reference instead of the
`MovingPtr`
* Tighten safety requirements on `move_maybe_uninit_field`, since
mutable aliasing is still UB for `MaybeUninit`
## Solution
Have the `deconstruct_moving_ptr` macro emit code that borrows all of
the provided fields at once from a `&mut T`. If the same field is
provided more than once, this will fail with an error of "cannot borrow
value as mutable more than once at a time".
That code will *also* fail to compile on a `repr(packed)` struct, since
we can't borrow fields from that at all. So, drop support for those.
That means `move_field` on an aligned pointer can return an aligned
pointer, removing the need for `.try_into().debug_checked_unwrap()`.
---------
Co-authored-by: François Mockers <francois.mockers@vleue.com>
# Objective
Fixes#21050
## Solution
Use the `$crate` metavariable in the `move_as_ptr` macro so that it
always resolves the `bevy_ptr` crate correctly.
# Objective
1. Fix incorrect macro usage in Debug implementation.
2. (unimportant) Enforce consistent formatting for unsafe blocks.
## Solution
1. I'm not sure why `$ptr` appeared in the `Debug` implementation for
`MovingPtr`, as this isn't in a macro context. I believe it was a
mistake, so I changed `stringify!($ptr)` to `"MovingPtr"`.
2. If a function has no return value (returns `()`), the final statement
should end with a semicolon. (At least maintain a consistent style.)
Therefore, change `unsafe { ... };` and `unsafe { ... }` to the unified
`unsafe { ...; }`.
## Testing
- `cargo test -p bevy_ptr` is passed.
- Several examples have been running normally.
- No more testing is needed.
# Objective
Fix#20571.
## Solution
* Avoid passing the bundle by value further than one layer deep, and
pass a `MovingPtr<'_, T>` of the Bundle instead.
* Pass `MovingPtr<'_, Self>` to `DynamicBundle::get_components` and its
recursive children.
* Instead of returning an `BundleEffect`, directly apply the effect from
a `MovingPtr<'_, MaybeUninit<Self>>`.
* Remove the now unused `BundleEffect` trait.
This should avoid most if not all extra stack copies of the bundle and
its components. This won't 100% fix stack overflows via bundles, but it
does mitigate them until much larger bundles are used.
This started as a subset of the changes made in #20593.
## Testing
Ran `cargo r --example feathers --features="experimental_bevy_feathers"`
on Windows, no stack overflow.
Co-Authored By: janis <janis@nirgendwo.xyz>
---------
Co-authored-by: Talin <viridia@gmail.com>
Co-authored-by: Janis <janis@nirgendwo.xyz>
Co-authored-by: Janis <130913856+janis-bhm@users.noreply.github.com>
Co-authored-by: Kristoffer Søholm <k.soeholm@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Mike <mike.hsu@gmail.com>
Co-authored-by: Chris Russell <8494645+chescock@users.noreply.github.com>
# Objective
Make moving potentially large values, like those seen in #20571 and
those seen by #20772, safer and easier to review.
## Solution
Introduce `MovingPtr<'a, T>` as a wrapper around `NonNull<T>`. This
type:
- Wraps a pointer and is thus cheap to pass through to functions.
- Acts like a `Box<T>` that does not own the allocation it points to. It
will drop the value it points to when it's dropped, but will not
deallocate when it's dropped.
- Acts like a `OwningPtr` in that it owns the values it points to and
has an associated lifetime, but it has a concrete type.
- As it owns the value, it does not implement `Clone` or `Copy`.
- Does not support arbitrary pointer arithmetic other than to get
`MovingPtr`s of the value's fields.
- Does not support casting to types other than `ManuallyDrop<T>` and
`MaybeUninit<T>`.
- Has methods that consume the `MovingPtr` that copies the value into a
target pointer or reads it onto the stack.
- Provide unsafe functions for partially moving values of members out
and returns a `MovingPtr<'a, MaybeUninit<T>>` in its stead.
- Optionally supports unaligned pointers like `OwningPtr` for use cases
like #20593.
- Provides `From` impl for converting to `OwningPtr` to type erasure
without loss of the lifetime or alignment requirements.
- Provides a `TryFrom` impl to attempt to convert an unaligned instance
into a aligned one. Can be combined with `DebugCheckedUnwrap` to assert
that the conversion is sound.
- The `deconstruct_moving_ptr` provides a less error-prone way of
decomposing a `MovingPtr` into separate `MovingPtr` for its fields.
This design is loosely based on the outptr proposal for [in-place
construction](https://github.com/rust-lang/lang-team/issues/336#issuecomment-3049593105),
but currently eschews the requirements for a derive macro.
## Testing
CI, new doc tests pass.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Giacomo Stevanato <giaco.stevanato@gmail.com>
Co-authored-by: Chris Russell <8494645+chescock@users.noreply.github.com>
Co-authored-by: Sandor <alexaegis@pm.me>
# Objective
Fix https://github.com/bevyengine/bevy/issues/19617
# Solution
Add newlines before all impl blocks.
I suspect that at least some of these will be objectionable! If there's
a desired Bevy style for this then I'll update the PR. If not then we
can just close it - it's the work of a single find and replace.
Bump version after release
This PR has been auto-generated
Fixes#19766
---------
Co-authored-by: Bevy Auto Releaser <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: François Mockers <francois.mockers@vleue.com>
Co-authored-by: François Mockers <mockersf@gmail.com>
# Objective
Fixes#17988
## Solution
Added two Debug impls to the `impl_ptr` macro - one for Aligned and one
for Unaligned.
## Testing
No tests have been added. Would a test guaranteeing debug layout be
appropriate?
---
## Showcase
The debug representation of a `Ptr<'_, Aligned>` follows. `PtrMut` and
`OwningPtr` are similar.
`Ptr<Aligned>(0x0123456789ab)`
# Objective
- Fixes#17960
## Solution
- Followed the [edition upgrade
guide](https://doc.rust-lang.org/edition-guide/editions/transitioning-an-existing-project-to-a-new-edition.html)
## Testing
- CI
---
## Summary of Changes
### Documentation Indentation
When using lists in documentation, proper indentation is now linted for.
This means subsequent lines within the same list item must start at the
same indentation level as the item.
```rust
/* Valid */
/// - Item 1
/// Run-on sentence.
/// - Item 2
struct Foo;
/* Invalid */
/// - Item 1
/// Run-on sentence.
/// - Item 2
struct Foo;
```
### Implicit `!` to `()` Conversion
`!` (the never return type, returned by `panic!`, etc.) no longer
implicitly converts to `()`. This is particularly painful for systems
with `todo!` or `panic!` statements, as they will no longer be functions
returning `()` (or `Result<()>`), making them invalid systems for
functions like `add_systems`. The ideal fix would be to accept functions
returning `!` (or rather, _not_ returning), but this is blocked on the
[stabilisation of the `!` type
itself](https://doc.rust-lang.org/std/primitive.never.html), which is
not done.
The "simple" fix would be to add an explicit `-> ()` to system
signatures (e.g., `|| { todo!() }` becomes `|| -> () { todo!() }`).
However, this is _also_ banned, as there is an existing lint which (IMO,
incorrectly) marks this as an unnecessary annotation.
So, the "fix" (read: workaround) is to put these kinds of `|| -> ! { ...
}` closuers into variables and give the variable an explicit type (e.g.,
`fn()`).
```rust
// Valid
let system: fn() = || todo!("Not implemented yet!");
app.add_systems(..., system);
// Invalid
app.add_systems(..., || todo!("Not implemented yet!"));
```
### Temporary Variable Lifetimes
The order in which temporary variables are dropped has changed. The
simple fix here is _usually_ to just assign temporaries to a named
variable before use.
### `gen` is a keyword
We can no longer use the name `gen` as it is reserved for a future
generator syntax. This involved replacing uses of the name `gen` with
`r#gen` (the raw-identifier syntax).
### Formatting has changed
Use statements have had the order of imports changed, causing a
substantial +/-3,000 diff when applied. For now, I have opted-out of
this change by amending `rustfmt.toml`
```toml
style_edition = "2021"
```
This preserves the original formatting for now, reducing the size of
this PR. It would be a simple followup to update this to 2024 and run
`cargo fmt`.
### New `use<>` Opt-Out Syntax
Lifetimes are now implicitly included in RPIT types. There was a handful
of instances where it needed to be added to satisfy the borrow checker,
but there may be more cases where it _should_ be added to avoid
breakages in user code.
### `MyUnitStruct { .. }` is an invalid pattern
Previously, you could match against unit structs (and unit enum
variants) with a `{ .. }` destructuring. This is no longer valid.
### Pretty much every use of `ref` and `mut` are gone
Pattern binding has changed to the point where these terms are largely
unused now. They still serve a purpose, but it is far more niche now.
### `iter::repeat(...).take(...)` is bad
New lint recommends using the more explicit `iter::repeat_n(..., ...)`
instead.
## Migration Guide
The lifetimes of functions using return-position impl-trait (RPIT) are
likely _more_ conservative than they had been previously. If you
encounter lifetime issues with such a function, please create an issue
to investigate the addition of `+ use<...>`.
## Notes
- Check the individual commits for a clearer breakdown for what
_actually_ changed.
---------
Co-authored-by: François Mockers <francois.mockers@vleue.com>
# Objective
- publish script copy the license files to all subcrates, meaning that
all publish are dirty. this breaks git verification of crates
- the order and list of crates to publish is manually maintained,
leading to error. cargo 1.84 is more strict and the list is currently
wrong
## Solution
- duplicate all the licenses to all crates and remove the
`--allow-dirty` flag
- instead of a manual list of crates, get it from `cargo package
--workspace`
- remove the `--no-verify` flag to... verify more things?
# Objective
The safety documentation for `Ptr::assert_unique` is incomplete.
Currently it only mentions the existence of other `Ptr` instances, but
it should also mention that the underlying data must be mutable and that
there cannot be active references to it.
# Objective
Fixes https://github.com/bevyengine/bevy/issues/17111
## Solution
Move `#![warn(clippy::allow_attributes,
clippy::allow_attributes_without_reason)]` to the workspace `Cargo.toml`
## Testing
Lots of CI testing, and local testing too.
---------
Co-authored-by: Benjamin Brienen <benjamin.brienen@outlook.com>
# Objective
I realized that setting these to `deny` may have been a little
aggressive - especially since we upgrade warnings to denies in CI.
## Solution
Downgrades these lints to `warn`, so that compiles can work locally. CI
will still treat these as denies.
# Objective
- https://github.com/bevyengine/bevy/issues/17111
## Solution
Set the `clippy::allow_attributes` and
`clippy::allow_attributes_without_reason` lints to `deny`, and bring
`bevy_ptr` in line with the new restrictions.
## Testing
`cargo clippy --tests` was run, and no errors were encountered.
I was expecting this crate to give more of a fight.
Bump version after release
This PR has been auto-generated
---------
Co-authored-by: Bevy Auto Releaser <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: François Mockers <mockersf@gmail.com>
# Objective
MSRV in the standalone crates should be accurate
## Solution
Determine the msrv of each crate and set it
## Testing
Adding better msrv checks to the CI is a next-step.
## Methodology
A good metric that correlates with compile time is the amount of code
generated by the compiler itself; even if the end binary is exactly the
same size, having more copies of the same code can really slow down
compile time, since it has to figure out whether it needs to include
them or not.
The measurement for this used was the [`cargo-llvm-lines`
crate](https://docs.rs/crate/cargo-llvm-lines) which can measure which
functions are generating the most lines of LLVM IR, which generally
means more code compiled. The example compiled was the `breakout` game,
to choose something that touches a decent portion of the engine.
## Solution
Based upon the measurements, `bevy_ptr::OwnedPtr::make` was taking up
4061 lines of LLVM IR in the example code. So, I separated part of this
function into a less-monomorphised version to reduce the amount of
generated code. This was by far the most lines emitted by any single
function.
## Results
After this change, only 2560 lines are emitted, accounting for a 36%
decrease. I tried timing the results and it seemed like it did decrease
compile times a bit, but honestly, the data is really noisy and I can't
be bothered to compile bevy for hours on end to get enough data points.
The tweak feels like an improvement, so, I'll offer it, however small.
# Objective
Bevy seems to want to standardize on "American English" spellings. Not
sure if this is laid out anywhere in writing, but see also #15947.
While perusing the docs for `typos`, I noticed that it has a `locale`
config option and tried it out.
## Solution
Switch to `en-us` locale in the `typos` config and run `typos -w`
## Migration Guide
The following methods or fields have been renamed from `*dependants*` to
`*dependents*`.
- `ProcessorAssetInfo::dependants`
- `ProcessorAssetInfos::add_dependant`
- `ProcessorAssetInfos::non_existent_dependants`
- `AssetInfo::dependants_waiting_on_load`
- `AssetInfo::dependants_waiting_on_recursive_dep_load`
- `AssetInfos::loader_dependants`
- `AssetInfos::remove_dependants_and_labels`
# Objective
- Fixes#6370
- Closes#6581
## Solution
- Added the following lints to the workspace:
- `std_instead_of_core`
- `std_instead_of_alloc`
- `alloc_instead_of_core`
- Used `cargo +nightly fmt` with [item level use
formatting](https://rust-lang.github.io/rustfmt/?version=v1.6.0&search=#Item%5C%3A)
to split all `use` statements into single items.
- Used `cargo clippy --workspace --all-targets --all-features --fix
--allow-dirty` to _attempt_ to resolve the new linting issues, and
intervened where the lint was unable to resolve the issue automatically
(usually due to needing an `extern crate alloc;` statement in a crate
root).
- Manually removed certain uses of `std` where negative feature gating
prevented `--all-features` from finding the offending uses.
- Used `cargo +nightly fmt` with [crate level use
formatting](https://rust-lang.github.io/rustfmt/?version=v1.6.0&search=#Crate%5C%3A)
to re-merge all `use` statements matching Bevy's previous styling.
- Manually fixed cases where the `fmt` tool could not re-merge `use`
statements due to conditional compilation attributes.
## Testing
- Ran CI locally
## Migration Guide
The MSRV is now 1.81. Please update to this version or higher.
## Notes
- This is a _massive_ change to try and push through, which is why I've
outlined the semi-automatic steps I used to create this PR, in case this
fails and someone else tries again in the future.
- Making this change has no impact on user code, but does mean Bevy
contributors will be warned to use `core` and `alloc` instead of `std`
where possible.
- This lint is a critical first step towards investigating `no_std`
options for Bevy.
---------
Co-authored-by: François Mockers <francois.mockers@vleue.com>
# Objective
> Rust 1.81 released the #[expect(...)] attribute, which works like
#[allow(...)] but throws a warning if the lint isn't raised. This is
preferred to #[allow(...)] because it tells us when it can be removed.
- Adopts the parts of #15118 that are complete, and updates the branch
so it can be merged.
- There were a few conflicts, let me know if I misjudged any of 'em.
Alice's
[recommendation](https://github.com/bevyengine/bevy/issues/15059#issuecomment-2349263900)
seems well-taken, let's do this crate by crate now that @BD103 has done
the lion's share of this!
(Relates to, but doesn't yet completely finish #15059.)
Crates this _doesn't_ cover:
- bevy_input
- bevy_gilrs
- bevy_window
- bevy_winit
- bevy_state
- bevy_render
- bevy_picking
- bevy_core_pipeline
- bevy_sprite
- bevy_text
- bevy_pbr
- bevy_ui
- bevy_gltf
- bevy_gizmos
- bevy_dev_tools
- bevy_internal
- bevy_dylib
---------
Co-authored-by: BD103 <59022059+BD103@users.noreply.github.com>
Co-authored-by: Ben Frankel <ben.frankel7@gmail.com>
Co-authored-by: Antony <antony.m.3012@gmail.com>
# Objective
- Remove an int2ptr cast in `bevy_ptr::dangling_with_align`
- This is flagged by MIRI unless `-Zmiri-permissive-provenance` is used
(like in CI)
- Remove `-Zmiri-permissive-provenance` in CI
## Solution
- Create the raw pointer like
[`std::ptr::without_provenance`](https://doc.rust-lang.org/stable/std/ptr/fn.without_provenance_mut.html)
does, i.e. by starting from a null pointer.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: François Mockers <francois.mockers@vleue.com>
# Objective
- fix#12853
- Make `Table::allocate` faster
## Solution
The PR consists of multiple steps:
1) For the component data: create a new data-structure that's similar to
`BlobVec` but doesn't store `len` & `capacity` inside of it: "BlobArray"
(name suggestions welcome)
2) For the `Tick` data: create a new data-structure that's similar to
`ThinSlicePtr` but supports dynamic reallocation: "ThinArrayPtr" (name
suggestions welcome)
3) Create a new data-structure that's very similar to `Column` that
doesn't store `len` & `capacity` inside of it: "ThinColumn"
4) Adjust the `Table` implementation to use `ThinColumn` instead of
`Column`
The result is that only one set of `len` & `capacity` is stored in
`Table`, in `Table::entities`
### Notes Regarding Performance
Apart from shaving off some excess memory in `Table`, the changes have
also brought noteworthy performance improvements:
The previous implementation relied on `Vec::reserve` &
`BlobVec::reserve`, but that redundantly repeated the same if statement
(`capacity` == `len`). Now that check could be made at the `Table` level
because the capacity and length of all the columns are synchronized;
saving N branches per allocation. The result is a respectable
performance improvement per every `Table::reserve` (and subsequently
`Table::allocate`) call.
I'm hesitant to give exact numbers because I don't have a lot of
experience in profiling and benchmarking, but these are the results I
got so far:
*`add_remove_big/table` benchmark after the implementation:*

*`add_remove_big/table` benchmark in main branch (measured in comparison
to the implementation):*

*`add_remove_very_big/table` benchmark after the implementation:*

*`add_remove_very_big/table` benchmark in main branch (measured in
comparison to the implementation):*

cc @james7132 to verify
---
## Changelog
- New data-structure that's similar to `BlobVec` but doesn't store `len`
& `capacity` inside of it: `BlobArray`
- New data-structure that's similar to `ThinSlicePtr` but supports
dynamic allocation:`ThinArrayPtr`
- New data-structure that's very similar to `Column` that doesn't store
`len` & `capacity` inside of it: `ThinColumn`
- Adjust the `Table` implementation to use `ThinColumn` instead of
`Column`
- New benchmark: `add_remove_very_big` to benchmark the performance of
spawning a lot of entities with a lot of components (15) each
## Migration Guide
`Table` now uses `ThinColumn` instead of `Column`. That means that
methods that previously returned `Column`, will now return `ThinColumn`
instead.
`ThinColumn` has a much more limited and low-level API, but you can
still achieve the same things in `ThinColumn` as you did in `Column`.
For example, instead of calling `Column::get_added_tick`, you'd call
`ThinColumn::get_added_ticks_slice` and index it to get the specific
added tick.
---------
Co-authored-by: James Liu <contact@jamessliu.com>
# Objective
- Fixes#14974
## Solution
- Replace all* instances of `NonZero*` with `NonZero<*>`
## Testing
- CI passed locally.
---
## Notes
Within the `bevy_reflect` implementations for `std` types,
`impl_reflect_value!()` will continue to use the type aliases instead,
as it inappropriately parses the concrete type parameter as a generic
argument. If the `ZeroablePrimitive` trait was stable, or the macro
could be modified to accept a finite list of types, then we could fully
migrate.
# Objective
Fixes#14782
## Solution
Enable the lint and fix all upcoming hints (`--fix`). Also tried to
figure out the false-positive (see review comment). Maybe split this PR
up into multiple parts where only the last one enables the lint, so some
can already be merged resulting in less many files touched / less
potential for merge conflicts?
Currently, there are some cases where it might be easier to read the
code with the qualifier, so perhaps remove the import of it and adapt
its cases? In the current stage it's just a plain adoption of the
suggestions in order to have a base to discuss.
## Testing
`cargo clippy` and `cargo run -p ci` are happy.
# Objective
- Fix issue #2611
## Solution
- Add `--generate-link-to-definition` to all the `rustdoc-args` arrays
in the `Cargo.toml`s (for docs.rs)
- Add `--generate-link-to-definition` to the `RUSTDOCFLAGS` environment
variable in the docs workflow (for dev-docs.bevyengine.org)
- Document all the workspace crates in the docs workflow (needed because
otherwise only the source code of the `bevy` package will be included,
making the argument useless)
- I think this also fixes#3662, since it fixes the bug on
dev-docs.bevyengine.org, while on docs.rs it has been fixed for a while
on their side.
---
## Changelog
- The source code viewer on docs.rs now includes links to the
definitions.
# Objective
- Currently `bevy_ptr::{Ptr, PtrMut}` have `From` implementations from
references.
- These implementations impose an implicit `Sized` bound so `bevy_ptr`
types cannot be created from references to slices and trait objects.
- I ran into this trying to use `Ptr<'static>` as an untyped `&'static
dyn Any`, and [had to work around
it](https://github.com/soqb/perfect-reflect/blob/f32b41512c77ad2d7e0f126b0a0fdf388e3e4717/src/registry.rs#L214-L219).
## Solution
- Relax the `Sized` bound on the relevant `From` implementations.
Bump version after release
This PR has been auto-generated
Co-authored-by: Bevy Auto Releaser <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: François Mockers <mockersf@gmail.com>
# Objective
- I wanted to store a Ptr in a struct of mine that has a
`#[derive(Debug)]` and I noticed that the Ptrs don't implement Debug,
even though the underlying `NonNull<u8>` does
## Solution
- Add `#[derive(Debug)]`
# Objective
- `README.md` is a common file that usually gives an overview of the
folder it is in.
- When on <https://crates.io>, `README.md` is rendered as the main
description.
- Many crates in this repository are lacking `README.md` files, which
makes it more difficult to understand their purpose.
<img width="1552" alt="image"
src="https://github.com/bevyengine/bevy/assets/59022059/78ebf91d-b0c4-4b18-9874-365d6310640f">
- There are also a few inconsistencies with `README.md` files that this
PR and its follow-ups intend to fix.
## Solution
- Create a `README.md` file for all crates that do not have one.
- This file only contains the title of the crate (underscores removed,
proper capitalization, acronyms expanded) and the <https://shields.io>
badges.
- Remove the `readme` field in `Cargo.toml` for `bevy` and
`bevy_reflect`.
- This field is redundant because [Cargo automatically detects
`README.md`
files](https://doc.rust-lang.org/cargo/reference/manifest.html#the-readme-field).
The field is only there if you name it something else, like `INFO.md`.
- Fix capitalization of `bevy_utils`'s `README.md`.
- It was originally `Readme.md`, which is inconsistent with the rest of
the project.
- I created two commits renaming it to `README.md`, because Git appears
to be case-insensitive.
- Expand acronyms in title of `bevy_ptr` and `bevy_utils`.
- In the commit where I created all the new `README.md` files, I
preferred using expanded acronyms in the titles. (E.g. "Bevy Developer
Tools" instead of "Bevy Dev Tools".)
- This commit changes the title of existing `README.md` files to follow
the same scheme.
- I do not feel strongly about this change, please comment if you
disagree and I can revert it.
- Add <https://shields.io> badges to `bevy_time` and `bevy_transform`,
which are the only crates currently lacking them.
---
## Changelog
- Added `README.md` files to all crates missing it.