bevy/crates/bevy_ecs/compile_fail
Chris Russell 94e6fa168f
Fix unsoundness in QueryIter::sort_by (#17826)
# 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 { /* ... */ }
2025-02-26 20:36:37 +00:00
..
src Move compile fail tests (#13196) 2024-05-03 13:35:21 +00:00
tests Fix unsoundness in QueryIter::sort_by (#17826) 2025-02-26 20:36:37 +00:00
.gitignore Move compile fail tests (#13196) 2024-05-03 13:35:21 +00:00
Cargo.toml Upgrade to Rust Edition 2024 (#17967) 2025-02-24 03:54:47 +00:00
README.md Move compile fail tests (#13196) 2024-05-03 13:35:21 +00:00

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.