Skip to content

Commit 9242ad1

Browse files
committed
add test
1 parent 60586ff commit 9242ad1

File tree

2 files changed

+133
-0
lines changed

2 files changed

+133
-0
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
use bevy_ecs::prelude::*;
2+
3+
#[derive(Component, Eq, PartialEq, Debug)]
4+
struct A(Box<usize>);
5+
6+
#[derive(Component)]
7+
struct B;
8+
9+
fn main() {
10+
let mut world = World::default();
11+
let e = world.spawn().insert(A(Box::new(10_usize))).id();
12+
13+
let mut e_mut = world.entity_mut(e);
14+
15+
{
16+
let gotten: &A = e_mut.get::<A>().unwrap();
17+
let gotten2: A = e_mut.remove::<A>().unwrap();
18+
assert_eq!(gotten, &gotten2); // oops UB
19+
}
20+
21+
e_mut.insert(A(Box::new(12_usize)));
22+
23+
{
24+
let mut gotten: Mut<A> = e_mut.get_mut::<A>().unwrap();
25+
let mut gotten2: A = e_mut.remove::<A>().unwrap();
26+
assert_eq!(&mut *gotten, &mut gotten2); // oops UB
27+
}
28+
29+
e_mut.insert(A(Box::new(14_usize)));
30+
31+
{
32+
let gotten: &A = e_mut.get::<A>().unwrap();
33+
e_mut.despawn();
34+
assert_eq!(gotten, &A(Box::new(14_usize))); // oops UB
35+
}
36+
37+
let e = world.spawn().insert(A(Box::new(16_usize))).id();
38+
let mut e_mut = world.entity_mut(e);
39+
40+
{
41+
let gotten: &A = e_mut.get::<A>().unwrap();
42+
let gotten_mut: Mut<A> = e_mut.get_mut::<A>().unwrap();
43+
assert_eq!(gotten, &*gotten_mut); // oops UB
44+
}
45+
46+
{
47+
let gotten_mut: Mut<A> = e_mut.get_mut::<A>().unwrap();
48+
let gotten: &A = e_mut.get::<A>().unwrap();
49+
assert_eq!(gotten, &*gotten_mut); // oops UB
50+
}
51+
52+
{
53+
let gotten: &A = e_mut.get::<A>().unwrap();
54+
e_mut.insert::<B>(B);
55+
assert_eq!(gotten, &A(Box::new(16_usize))); // oops UB
56+
e_mut.remove::<B>();
57+
}
58+
59+
{
60+
let mut gotten_mut: Mut<A> = e_mut.get_mut::<A>().unwrap();
61+
e_mut.insert::<B>(B);
62+
assert_eq!(&mut *gotten_mut, &mut A(Box::new(16_usize))); // oops UB
63+
}
64+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
error[E0502]: cannot borrow `e_mut` as mutable because it is also borrowed as immutable
2+
--> tests/ui/entity_ref_mut_lifetime_safety.rs:17:26
3+
|
4+
16 | let gotten: &A = e_mut.get::<A>().unwrap();
5+
| ---------------- immutable borrow occurs here
6+
17 | let gotten2: A = e_mut.remove::<A>().unwrap();
7+
| ^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
8+
18 | assert_eq!(gotten, &gotten2); // oops UB
9+
| ---------------------------- immutable borrow later used here
10+
11+
error[E0499]: cannot borrow `e_mut` as mutable more than once at a time
12+
--> tests/ui/entity_ref_mut_lifetime_safety.rs:25:30
13+
|
14+
24 | let mut gotten: Mut<A> = e_mut.get_mut::<A>().unwrap();
15+
| -------------------- first mutable borrow occurs here
16+
25 | let mut gotten2: A = e_mut.remove::<A>().unwrap();
17+
| ^^^^^^^^^^^^^^^^^^^ second mutable borrow occurs here
18+
26 | assert_eq!(&mut *gotten, &mut gotten2); // oops UB
19+
| ------ first borrow later used here
20+
21+
error[E0505]: cannot move out of `e_mut` because it is borrowed
22+
--> tests/ui/entity_ref_mut_lifetime_safety.rs:33:9
23+
|
24+
32 | let gotten: &A = e_mut.get::<A>().unwrap();
25+
| ---------------- borrow of `e_mut` occurs here
26+
33 | e_mut.despawn();
27+
| ^^^^^ move out of `e_mut` occurs here
28+
34 | assert_eq!(gotten, &A(Box::new(14_usize))); // oops UB
29+
| ------------------------------------------ borrow later used here
30+
31+
error[E0502]: cannot borrow `e_mut` as mutable because it is also borrowed as immutable
32+
--> tests/ui/entity_ref_mut_lifetime_safety.rs:42:34
33+
|
34+
41 | let gotten: &A = e_mut.get::<A>().unwrap();
35+
| ---------------- immutable borrow occurs here
36+
42 | let gotten_mut: Mut<A> = e_mut.get_mut::<A>().unwrap();
37+
| ^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
38+
43 | assert_eq!(gotten, &*gotten_mut); // oops UB
39+
| -------------------------------- immutable borrow later used here
40+
41+
error[E0502]: cannot borrow `e_mut` as immutable because it is also borrowed as mutable
42+
--> tests/ui/entity_ref_mut_lifetime_safety.rs:48:26
43+
|
44+
47 | let gotten_mut: Mut<A> = e_mut.get_mut::<A>().unwrap();
45+
| -------------------- mutable borrow occurs here
46+
48 | let gotten: &A = e_mut.get::<A>().unwrap();
47+
| ^^^^^^^^^^^^^^^^ immutable borrow occurs here
48+
49 | assert_eq!(gotten, &*gotten_mut); // oops UB
49+
| ---------- mutable borrow later used here
50+
51+
error[E0502]: cannot borrow `e_mut` as mutable because it is also borrowed as immutable
52+
--> tests/ui/entity_ref_mut_lifetime_safety.rs:54:9
53+
|
54+
53 | let gotten: &A = e_mut.get::<A>().unwrap();
55+
| ---------------- immutable borrow occurs here
56+
54 | e_mut.insert::<B>(B);
57+
| ^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
58+
55 | assert_eq!(gotten, &A(Box::new(16_usize))); // oops UB
59+
| ------------------------------------------ immutable borrow later used here
60+
61+
error[E0499]: cannot borrow `e_mut` as mutable more than once at a time
62+
--> tests/ui/entity_ref_mut_lifetime_safety.rs:61:9
63+
|
64+
60 | let mut gotten_mut: Mut<A> = e_mut.get_mut::<A>().unwrap();
65+
| -------------------- first mutable borrow occurs here
66+
61 | e_mut.insert::<B>(B);
67+
| ^^^^^^^^^^^^^^^^^^^^ second mutable borrow occurs here
68+
62 | assert_eq!(&mut *gotten_mut, &mut A(Box::new(16_usize))); // oops UB
69+
| ---------- first borrow later used here

0 commit comments

Comments
 (0)