From 0cf02bab2930701ff77cc7e37edb6a2132cfe5f6 Mon Sep 17 00:00:00 2001 From: Ellen Date: Thu, 17 Mar 2022 20:21:10 +0000 Subject: [PATCH] compile fail test --- .../tests/ui/query_lifetime_safety.rs | 92 ++++++++++++++ .../tests/ui/query_lifetime_safety.stderr | 119 ++++++++++++++++++ 2 files changed, 211 insertions(+) create mode 100644 crates/bevy_ecs_compile_fail_tests/tests/ui/query_lifetime_safety.rs create mode 100644 crates/bevy_ecs_compile_fail_tests/tests/ui/query_lifetime_safety.stderr diff --git a/crates/bevy_ecs_compile_fail_tests/tests/ui/query_lifetime_safety.rs b/crates/bevy_ecs_compile_fail_tests/tests/ui/query_lifetime_safety.rs new file mode 100644 index 0000000000000..bb9ff14111ff3 --- /dev/null +++ b/crates/bevy_ecs_compile_fail_tests/tests/ui/query_lifetime_safety.rs @@ -0,0 +1,92 @@ +use bevy_ecs::prelude::*; +use bevy_ecs::system::SystemState; + +#[derive(Component, Eq, PartialEq, Debug)] +struct Foo(u32); + +fn main() { + let mut world = World::default(); + let e = world.spawn().insert(Foo(10_u32)).id(); + + let mut system_state = SystemState::>::new(&mut world); + { + let mut query = system_state.get_mut(&mut world); + dbg!("hi"); + { + let data: &Foo = query.get(e).unwrap(); + let mut data2: Mut = query.get_mut(e).unwrap(); + assert_eq!(data, &mut *data2); // oops UB + } + + { + let mut data2: Mut = query.get_mut(e).unwrap(); + let data: &Foo = query.get(e).unwrap(); + assert_eq!(data, &mut *data2); // oops UB + } + + { + let data: &Foo = query.get_component::(e).unwrap(); + let mut data2: Mut = query.get_component_mut(e).unwrap(); + assert_eq!(data, &mut *data2); // oops UB + } + + { + let mut data2: Mut = query.get_component_mut(e).unwrap(); + let data: &Foo = query.get_component::(e).unwrap(); + assert_eq!(data, &mut *data2); // oops UB + } + + { + let data: &Foo = query.single(); + let mut data2: Mut = query.single_mut(); + assert_eq!(data, &mut *data2); // oops UB + } + + { + let mut data2: Mut = query.single_mut(); + let data: &Foo = query.single(); + assert_eq!(data, &mut *data2); // oops UB + } + + { + let data: &Foo = query.get_single().unwrap(); + let mut data2: Mut = query.get_single_mut().unwrap(); + assert_eq!(data, &mut *data2); // oops UB + } + + { + let mut data2: Mut = query.get_single_mut().unwrap(); + let data: &Foo = query.get_single().unwrap(); + assert_eq!(data, &mut *data2); // oops UB + } + + { + let data: &Foo = query.iter().next().unwrap(); + let mut data2: Mut = query.iter_mut().next().unwrap(); + assert_eq!(data, &mut *data2); // oops UB + } + + { + let mut data2: Mut = query.iter_mut().next().unwrap(); + let data: &Foo = query.iter().next().unwrap(); + assert_eq!(data, &mut *data2); // oops UB + } + + { + let mut opt_data: Option<&Foo> = None; + let mut opt_data_2: Option> = None; + query.for_each(|data| opt_data = Some(data)); + query.for_each_mut(|data| opt_data_2 = Some(data)); + assert_eq!(opt_data.unwrap(), &mut *opt_data_2.unwrap()); // oops UB + } + + { + let mut opt_data_2: Option> = None; + let mut opt_data: Option<&Foo> = None; + query.for_each_mut(|data| opt_data_2 = Some(data)); + query.for_each(|data| opt_data = Some(data)); + assert_eq!(opt_data.unwrap(), &mut *opt_data_2.unwrap()); // oops UB + } + dbg!("bye"); + } +} diff --git a/crates/bevy_ecs_compile_fail_tests/tests/ui/query_lifetime_safety.stderr b/crates/bevy_ecs_compile_fail_tests/tests/ui/query_lifetime_safety.stderr new file mode 100644 index 0000000000000..7b1d0fe610e9c --- /dev/null +++ b/crates/bevy_ecs_compile_fail_tests/tests/ui/query_lifetime_safety.stderr @@ -0,0 +1,119 @@ +error[E0502]: cannot borrow `query` as mutable because it is also borrowed as immutable + --> tests/ui/query_lifetime_safety.rs:17:39 + | +16 | let data: &Foo = query.get(e).unwrap(); + | ------------ immutable borrow occurs here +17 | let mut data2: Mut = query.get_mut(e).unwrap(); + | ^^^^^^^^^^^^^^^^ mutable borrow occurs here +18 | assert_eq!(data, &mut *data2); // oops UB + | ----------------------------- immutable borrow later used here + +error[E0502]: cannot borrow `query` as immutable because it is also borrowed as mutable + --> tests/ui/query_lifetime_safety.rs:23:30 + | +22 | let mut data2: Mut = query.get_mut(e).unwrap(); + | ---------------- mutable borrow occurs here +23 | let data: &Foo = query.get(e).unwrap(); + | ^^^^^^^^^^^^ immutable borrow occurs here +24 | assert_eq!(data, &mut *data2); // oops UB + | ----- mutable borrow later used here + +error[E0502]: cannot borrow `query` as mutable because it is also borrowed as immutable + --> tests/ui/query_lifetime_safety.rs:29:39 + | +28 | let data: &Foo = query.get_component::(e).unwrap(); + | ----------------------------- immutable borrow occurs here +29 | let mut data2: Mut = query.get_component_mut(e).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here +30 | assert_eq!(data, &mut *data2); // oops UB + | ----------------------------- immutable borrow later used here + +error[E0502]: cannot borrow `query` as immutable because it is also borrowed as mutable + --> tests/ui/query_lifetime_safety.rs:35:30 + | +34 | let mut data2: Mut = query.get_component_mut(e).unwrap(); + | -------------------------- mutable borrow occurs here +35 | let data: &Foo = query.get_component::(e).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ immutable borrow occurs here +36 | assert_eq!(data, &mut *data2); // oops UB + | ----- mutable borrow later used here + +error[E0502]: cannot borrow `query` as mutable because it is also borrowed as immutable + --> tests/ui/query_lifetime_safety.rs:41:39 + | +40 | let data: &Foo = query.single(); + | -------------- immutable borrow occurs here +41 | let mut data2: Mut = query.single_mut(); + | ^^^^^^^^^^^^^^^^^^ mutable borrow occurs here +42 | assert_eq!(data, &mut *data2); // oops UB + | ----------------------------- immutable borrow later used here + +error[E0502]: cannot borrow `query` as immutable because it is also borrowed as mutable + --> tests/ui/query_lifetime_safety.rs:47:30 + | +46 | let mut data2: Mut = query.single_mut(); + | ------------------ mutable borrow occurs here +47 | let data: &Foo = query.single(); + | ^^^^^^^^^^^^^^ immutable borrow occurs here +48 | assert_eq!(data, &mut *data2); // oops UB + | ----- mutable borrow later used here + +error[E0502]: cannot borrow `query` as mutable because it is also borrowed as immutable + --> tests/ui/query_lifetime_safety.rs:53:39 + | +52 | let data: &Foo = query.get_single().unwrap(); + | ------------------ immutable borrow occurs here +53 | let mut data2: Mut = query.get_single_mut().unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here +54 | assert_eq!(data, &mut *data2); // oops UB + | ----------------------------- immutable borrow later used here + +error[E0502]: cannot borrow `query` as immutable because it is also borrowed as mutable + --> tests/ui/query_lifetime_safety.rs:59:30 + | +58 | let mut data2: Mut = query.get_single_mut().unwrap(); + | ---------------------- mutable borrow occurs here +59 | let data: &Foo = query.get_single().unwrap(); + | ^^^^^^^^^^^^^^^^^^ immutable borrow occurs here +60 | assert_eq!(data, &mut *data2); // oops UB + | ----- mutable borrow later used here + +error[E0502]: cannot borrow `query` as mutable because it is also borrowed as immutable + --> tests/ui/query_lifetime_safety.rs:65:39 + | +64 | let data: &Foo = query.iter().next().unwrap(); + | ------------ immutable borrow occurs here +65 | let mut data2: Mut = query.iter_mut().next().unwrap(); + | ^^^^^^^^^^^^^^^^ mutable borrow occurs here +66 | assert_eq!(data, &mut *data2); // oops UB + | ----------------------------- immutable borrow later used here + +error[E0502]: cannot borrow `query` as immutable because it is also borrowed as mutable + --> tests/ui/query_lifetime_safety.rs:71:30 + | +70 | let mut data2: Mut = query.iter_mut().next().unwrap(); + | ---------------- mutable borrow occurs here +71 | let data: &Foo = query.iter().next().unwrap(); + | ^^^^^^^^^^^^ immutable borrow occurs here +72 | assert_eq!(data, &mut *data2); // oops UB + | ----- mutable borrow later used here + +error[E0502]: cannot borrow `query` as mutable because it is also borrowed as immutable + --> tests/ui/query_lifetime_safety.rs:79:13 + | +78 | query.for_each(|data| opt_data = Some(data)); + | -------------------------------------------- immutable borrow occurs here +79 | query.for_each_mut(|data| opt_data_2 = Some(data)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here +80 | assert_eq!(opt_data.unwrap(), &mut *opt_data_2.unwrap()); // oops UB + | -------- immutable borrow later used here + +error[E0502]: cannot borrow `query` as immutable because it is also borrowed as mutable + --> tests/ui/query_lifetime_safety.rs:87:13 + | +86 | query.for_each_mut(|data| opt_data_2 = Some(data)); + | -------------------------------------------------- mutable borrow occurs here +87 | query.for_each(|data| opt_data = Some(data)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ immutable borrow occurs here +88 | assert_eq!(opt_data.unwrap(), &mut *opt_data_2.unwrap()); // oops UB + | ---------- mutable borrow later used here