Skip to content

Commit 68b2bb9

Browse files
committed
Replace doc tests with trybuild tests that assert the compiler errors
1 parent 91c3b21 commit 68b2bb9

15 files changed

+241
-169
lines changed

crates/bevy_ecs/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ serde = "1"
2929
[dev-dependencies]
3030
parking_lot = "0.11"
3131
rand = "0.8"
32+
trybuild = "1.0"
3233

3334
[[example]]
3435
name = "events"

crates/bevy_ecs/src/system/mod.rs

Lines changed: 0 additions & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -786,172 +786,3 @@ mod tests {
786786
}
787787
}
788788
}
789-
790-
/// ```compile_fail E0499
791-
/// use bevy_ecs::prelude::*;
792-
/// #[derive(Component)]
793-
/// struct A(usize);
794-
/// fn system(mut query: Query<&mut A>, e: Res<Entity>) {
795-
/// let mut iter = query.iter_mut();
796-
/// let a = &mut *iter.next().unwrap();
797-
///
798-
/// let mut iter2 = query.iter_mut();
799-
/// let b = &mut *iter2.next().unwrap();
800-
///
801-
/// // this should fail to compile
802-
/// println!("{}", a.0);
803-
/// }
804-
/// ```
805-
#[allow(unused)]
806-
#[cfg(doctest)]
807-
fn system_query_iter_lifetime_safety_test() {}
808-
809-
/// ```compile_fail E0499
810-
/// use bevy_ecs::prelude::*;
811-
/// #[derive(Component)]
812-
/// struct A(usize);
813-
/// fn system(mut query: Query<&mut A>, e: Res<Entity>) {
814-
/// let mut a1 = query.get_mut(*e).unwrap();
815-
/// let mut a2 = query.get_mut(*e).unwrap();
816-
/// // this should fail to compile
817-
/// println!("{} {}", a1.0, a2.0);
818-
/// }
819-
/// ```
820-
#[allow(unused)]
821-
#[cfg(doctest)]
822-
fn system_query_get_lifetime_safety_test() {}
823-
824-
/// ```compile_fail E0499
825-
/// use bevy_ecs::prelude::*;
826-
/// #[derive(Component)]
827-
/// struct A(usize);
828-
/// fn query_set(mut queries: QuerySet<(QueryState<&mut A>, QueryState<&A>)>, e: Res<Entity>) {
829-
/// let mut q2 = queries.q0();
830-
/// let mut iter2 = q2.iter_mut();
831-
/// let mut b = iter2.next().unwrap();
832-
///
833-
/// let q1 = queries.q1();
834-
/// let mut iter = q1.iter();
835-
/// let a = &*iter.next().unwrap();
836-
///
837-
/// // this should fail to compile
838-
/// b.0 = a.0
839-
/// }
840-
/// ```
841-
#[allow(unused)]
842-
#[cfg(doctest)]
843-
fn system_query_set_iter_lifetime_safety_test() {}
844-
845-
/// ```compile_fail E0499
846-
/// use bevy_ecs::prelude::*;
847-
/// #[derive(Component)]
848-
/// struct A(usize);
849-
/// fn query_set(mut queries: QuerySet<(QueryState<&mut A>, QueryState<&A>)>, e: Res<Entity>) {
850-
/// let q1 = queries.q1();
851-
/// let mut iter = q1.iter();
852-
/// let a = &*iter.next().unwrap();
853-
///
854-
/// let mut q2 = queries.q0();
855-
/// let mut iter2 = q2.iter_mut();
856-
/// let mut b = iter2.next().unwrap();
857-
///
858-
/// // this should fail to compile
859-
/// b.0 = a.0;
860-
/// }
861-
/// ```
862-
#[allow(unused)]
863-
#[cfg(doctest)]
864-
fn system_query_set_iter_flip_lifetime_safety_test() {}
865-
866-
/// ```compile_fail E0499
867-
/// use bevy_ecs::prelude::*;
868-
/// #[derive(Component)]
869-
/// struct A(usize);
870-
/// fn query_set(mut queries: QuerySet<(QueryState<&mut A>, QueryState<&A>)>, e: Res<Entity>) {
871-
/// let mut q2 = queries.q0();
872-
/// let mut b = q2.get_mut(*e).unwrap();
873-
///
874-
/// let q1 = queries.q1();
875-
/// let a = q1.get(*e).unwrap();
876-
///
877-
/// // this should fail to compile
878-
/// b.0 = a.0
879-
/// }
880-
/// ```
881-
#[allow(unused)]
882-
#[cfg(doctest)]
883-
fn system_query_set_get_lifetime_safety_test() {}
884-
885-
/// ```compile_fail E0499
886-
/// use bevy_ecs::prelude::*;
887-
/// #[derive(Component)]
888-
/// struct A(usize);
889-
/// fn query_set(mut queries: QuerySet<(QueryState<&mut A>, QueryState<&A>)>, e: Res<Entity>) {
890-
/// let q1 = queries.q1();
891-
/// let a = q1.get(*e).unwrap();
892-
///
893-
/// let mut q2 = queries.q0();
894-
/// let mut b = q2.get_mut(*e).unwrap();
895-
/// // this should fail to compile
896-
/// b.0 = a.0
897-
/// }
898-
/// ```
899-
#[allow(unused)]
900-
#[cfg(doctest)]
901-
fn system_query_set_get_flip_lifetime_safety_test() {}
902-
903-
/// ```compile_fail E0502
904-
/// use bevy_ecs::prelude::*;
905-
/// use bevy_ecs::system::SystemState;
906-
/// #[derive(Component)]
907-
/// struct A(usize);
908-
/// #[derive(Component)]
909-
/// struct B(usize);
910-
/// struct State {
911-
/// state_r: SystemState<Query<'static, 'static, &'static A>>,
912-
/// state_w: SystemState<Query<'static, 'static, &'static mut A>>,
913-
/// }
914-
///
915-
/// impl State {
916-
/// fn get_component<'w>(&mut self, world: &'w mut World, entity: Entity) {
917-
/// let q1 = self.state_r.get(&world);
918-
/// let a1 = q1.get(entity).unwrap();
919-
///
920-
/// let mut q2 = self.state_w.get_mut(world);
921-
/// let a2 = q2.get_mut(entity).unwrap();
922-
///
923-
/// // this should fail to compile
924-
/// println!("{}", a1.0);
925-
/// }
926-
/// }
927-
/// ```
928-
#[allow(unused)]
929-
#[cfg(doctest)]
930-
fn system_state_get_lifetime_safety_test() {}
931-
932-
/// ```compile_fail E0502
933-
/// use bevy_ecs::prelude::*;
934-
/// use bevy_ecs::system::SystemState;
935-
/// #[derive(Component)]
936-
/// struct A(usize);
937-
/// #[derive(Component)]
938-
/// struct B(usize);
939-
/// struct State {
940-
/// state_r: SystemState<Query<'static, 'static, &'static A>>,
941-
/// state_w: SystemState<Query<'static, 'static, &'static mut A>>,
942-
/// }
943-
///
944-
/// impl State {
945-
/// fn get_components<'w>(&mut self, world: &'w mut World) {
946-
/// let q1 = self.state_r.get(&world);
947-
/// let a1 = q1.iter().next().unwrap();
948-
/// let mut q2 = self.state_w.get_mut(world);
949-
/// let a2 = q2.iter_mut().next().unwrap();
950-
/// // this should fail to compile
951-
/// println!("{}", a1.0);
952-
/// }
953-
/// }
954-
/// ```
955-
#[allow(unused)]
956-
#[cfg(doctest)]
957-
fn system_state_iter_lifetime_safety_test() {}

crates/bevy_ecs/tests/ui.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#[test]
2+
fn test() {
3+
let t = trybuild::TestCases::new();
4+
t.compile_fail("tests/ui/*.rs");
5+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
use bevy_ecs::prelude::*;
2+
3+
#[derive(Component)]
4+
struct A(usize);
5+
6+
fn system(mut query: Query<&mut A>, e: Res<Entity>) {
7+
let a1 = query.get_mut(*e).unwrap();
8+
let a2 = query.get_mut(*e).unwrap();
9+
// this should fail to compile
10+
println!("{} {}", a1.0, a2.0);
11+
}
12+
13+
fn main() {}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error[E0499]: cannot borrow `query` as mutable more than once at a time
2+
--> tests/ui/system_query_get_lifetime_safety.rs:8:14
3+
|
4+
7 | let a1 = query.get_mut(*e).unwrap();
5+
| ----------------- first mutable borrow occurs here
6+
8 | let a2 = query.get_mut(*e).unwrap();
7+
| ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here
8+
9 | // this should fail to compile
9+
10 | println!("{} {}", a1.0, a2.0);
10+
| -- first borrow later used here
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
use bevy_ecs::prelude::*;
2+
3+
#[derive(Component)]
4+
struct A(usize);
5+
6+
fn system(mut query: Query<&mut A>) {
7+
let mut iter = query.iter_mut();
8+
let a = &mut *iter.next().unwrap();
9+
10+
let mut iter2 = query.iter_mut();
11+
let _ = &mut *iter2.next().unwrap();
12+
13+
// this should fail to compile
14+
println!("{}", a.0);
15+
}
16+
17+
fn main() {}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0499]: cannot borrow `query` as mutable more than once at a time
2+
--> tests/ui/system_query_iter_lifetime_safety.rs:10:21
3+
|
4+
7 | let mut iter = query.iter_mut();
5+
| ---------------- first mutable borrow occurs here
6+
...
7+
10 | let mut iter2 = query.iter_mut();
8+
| ^^^^^^^^^^^^^^^^ second mutable borrow occurs here
9+
...
10+
14 | println!("{}", a.0);
11+
| --- first borrow later used here
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
use bevy_ecs::prelude::*;
2+
3+
#[derive(Component)]
4+
struct A(usize);
5+
6+
fn query_set(mut queries: QuerySet<(QueryState<&mut A>, QueryState<&A>)>, e: Res<Entity>) {
7+
let mut q2 = queries.q0();
8+
let mut b = q2.get_mut(*e).unwrap();
9+
10+
let q1 = queries.q1();
11+
let a = q1.get(*e).unwrap();
12+
13+
// this should fail to compile
14+
b.0 = a.0
15+
}
16+
17+
fn query_set_flip(mut queries: QuerySet<(QueryState<&mut A>, QueryState<&A>)>, e: Res<Entity>) {
18+
let q1 = queries.q1();
19+
let a = q1.get(*e).unwrap();
20+
21+
let mut q2 = queries.q0();
22+
let mut b = q2.get_mut(*e).unwrap();
23+
24+
// this should fail to compile
25+
b.0 = a.0
26+
}
27+
28+
fn main() {}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
error[E0499]: cannot borrow `queries` as mutable more than once at a time
2+
--> tests/ui/system_query_set_get_lifetime_safety.rs:10:14
3+
|
4+
7 | let mut q2 = queries.q0();
5+
| ------------ first mutable borrow occurs here
6+
...
7+
10 | let q1 = queries.q1();
8+
| ^^^^^^^^^^^^ second mutable borrow occurs here
9+
...
10+
14 | b.0 = a.0
11+
| - first borrow later used here
12+
13+
error[E0499]: cannot borrow `queries` as mutable more than once at a time
14+
--> tests/ui/system_query_set_get_lifetime_safety.rs:21:18
15+
|
16+
18 | let q1 = queries.q1();
17+
| ------------ first mutable borrow occurs here
18+
...
19+
21 | let mut q2 = queries.q0();
20+
| ^^^^^^^^^^^^ second mutable borrow occurs here
21+
...
22+
25 | b.0 = a.0
23+
| --- first borrow later used here
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
use bevy_ecs::prelude::*;
2+
3+
#[derive(Component)]
4+
struct A(usize);
5+
6+
fn query_set(mut queries: QuerySet<(QueryState<&mut A>, QueryState<&A>)>) {
7+
let mut q2 = queries.q0();
8+
let mut iter2 = q2.iter_mut();
9+
let mut b = iter2.next().unwrap();
10+
11+
let q1 = queries.q1();
12+
let mut iter = q1.iter();
13+
let a = &*iter.next().unwrap();
14+
15+
// this should fail to compile
16+
b.0 = a.0
17+
}
18+
19+
fn query_set_flip(mut queries: QuerySet<(QueryState<&mut A>, QueryState<&A>)>) {
20+
let q1 = queries.q1();
21+
let mut iter = q1.iter();
22+
let a = &*iter.next().unwrap();
23+
24+
let mut q2 = queries.q0();
25+
let mut iter2 = q2.iter_mut();
26+
let mut b = iter2.next().unwrap();
27+
28+
// this should fail to compile
29+
b.0 = a.0;
30+
}
31+
32+
fn main() {}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
error[E0499]: cannot borrow `queries` as mutable more than once at a time
2+
--> tests/ui/system_query_set_iter_lifetime_safety.rs:11:14
3+
|
4+
7 | let mut q2 = queries.q0();
5+
| ------------ first mutable borrow occurs here
6+
...
7+
11 | let q1 = queries.q1();
8+
| ^^^^^^^^^^^^ second mutable borrow occurs here
9+
...
10+
16 | b.0 = a.0
11+
| - first borrow later used here
12+
13+
error[E0499]: cannot borrow `queries` as mutable more than once at a time
14+
--> tests/ui/system_query_set_iter_lifetime_safety.rs:24:18
15+
|
16+
20 | let q1 = queries.q1();
17+
| ------------ first mutable borrow occurs here
18+
...
19+
24 | let mut q2 = queries.q0();
20+
| ^^^^^^^^^^^^ second mutable borrow occurs here
21+
...
22+
29 | b.0 = a.0;
23+
| --- first borrow later used here
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
use bevy_ecs::prelude::*;
2+
use bevy_ecs::system::SystemState;
3+
4+
#[derive(Component)]
5+
struct A(usize);
6+
7+
#[derive(Component)]
8+
struct B(usize);
9+
10+
struct State {
11+
state_r: SystemState<Query<'static, 'static, &'static A>>,
12+
state_w: SystemState<Query<'static, 'static, &'static mut A>>,
13+
}
14+
15+
impl State {
16+
fn get_component(&mut self, world: &mut World, entity: Entity) {
17+
let q1 = self.state_r.get(&world);
18+
let a1 = q1.get(entity).unwrap();
19+
20+
let mut q2 = self.state_w.get_mut(world);
21+
let _ = q2.get_mut(entity).unwrap();
22+
23+
// this should fail to compile
24+
println!("{}", a1.0);
25+
}
26+
}
27+
28+
fn main() {}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0502]: cannot borrow `*world` as mutable because it is also borrowed as immutable
2+
--> tests/ui/system_state_get_lifetime_safety.rs:20:22
3+
|
4+
17 | let q1 = self.state_r.get(&world);
5+
| ------ immutable borrow occurs here
6+
...
7+
20 | let mut q2 = self.state_w.get_mut(world);
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
9+
...
10+
24 | println!("{}", a1.0);
11+
| ---- immutable borrow later used here

0 commit comments

Comments
 (0)