![]() # Objective `QueryIter::sort_by()` is unsound. It passes the lens items with the full `'w` lifetime, and a malicious user could smuggle them out of the closure where they could alias with the query results. ## Solution Make the sort closures generic in the lifetime parameter of the lens item. This ensures the lens items cannot outlive the call to the closure. ## Testing Added a compile-fail test that demonstrates the unsound pattern. ## Migration Guide The `sort` family of methods on `QueryIter` unsoundly gave access `L::Item<'w>` with the full `'w` lifetime. It has been shortened to `L::Item<'w>` so that items cannot escape the comparer. If you get lifetime errors using these methods, you will need to make the comparer generic in the new lifetime. Often this can be done by replacing named `'w` with `'_`, or by replacing the use of a function item with a closure. ```rust // Before: Now fails with "error: implementation of `FnMut` is not general enough" query.iter().sort_by::<&C>(Ord::cmp); // After: Wrap in a closure query.iter().sort_by::<&C>(|l, r| Ord::cmp(l, r)); query.iter().sort_by::<&C>(comparer); // Before: Uses specific `'w` lifetime from some outer scope // now fails with "error: implementation of `FnMut` is not general enough" fn comparer(left: &&'w C, right: &&'w C) -> Ordering { /* ... */ } // After: Accepts any lifetime using inferred lifetime parameter fn comparer(left: &&C, right: &&C) -> Ordering { /* ... */ } |
||
---|---|---|
.. | ||
src | ||
tests | ||
.gitignore | ||
Cargo.toml | ||
README.md |
Compile fail tests for bevy_ecs
This crate is separate from bevy_ecs
and not part of the Bevy workspace in order to not fail crater
tests for Bevy. The tests assert on the exact compiler errors and can easily fail for new Rust versions due to updated compiler errors (e.g. changes in spans).
The CI
workflow executes these tests on the stable rust toolchain (see tools/ci).
For information on writing tests see compile_fail_utils/README.md.