From 1cfb47e1512dffc6137e801c3d875bba1ac2526e Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Mon, 2 Jan 2023 21:07:33 +0000 Subject: [PATCH] bevy_reflect: Add compile fail tests for bevy_reflect (#7041) # Objective There isn't really a way to test that code using bevy_reflect compiles or doesn't compile for certain scenarios. This would be especially useful for macro-centric PRs like #6511 and #6042. ## Solution Using `bevy_ecs_compile_fail_tests` as reference, added the `bevy_reflect_compile_fail_tests` crate. Currently, this crate contains a very simple test case. This is so that we can get the basic foundation of this crate agreed upon and merged so that more tests can be added by other PRs. ### Open Questions - [x] Should this be added to CI? (Answer: Yes) --- ## Changelog - Added the `bevy_reflect_compile_fail_tests` crate for testing compilation errors --- .github/workflows/ci.yml | 1 + Cargo.toml | 2 +- .../Cargo.toml | 13 ++++++++++ .../bevy_reflect_compile_fail_tests/README.md | 7 ++++++ .../src/lib.rs | 1 + .../tests/reflect_derive.rs | 6 +++++ .../tests/reflect_derive/lifetimes.fail.rs | 9 +++++++ .../reflect_derive/lifetimes.fail.stderr | 13 ++++++++++ .../tests/reflect_derive/lifetimes.pass.rs | 10 ++++++++ tools/ci/src/main.rs | 24 ++++++++++++++----- 10 files changed, 79 insertions(+), 7 deletions(-) create mode 100644 crates/bevy_reflect_compile_fail_tests/Cargo.toml create mode 100644 crates/bevy_reflect_compile_fail_tests/README.md create mode 100644 crates/bevy_reflect_compile_fail_tests/src/lib.rs create mode 100644 crates/bevy_reflect_compile_fail_tests/tests/reflect_derive.rs create mode 100644 crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/lifetimes.fail.rs create mode 100644 crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/lifetimes.fail.stderr create mode 100644 crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/lifetimes.pass.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 00a5dd8040c700..c5b282b74a27c4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -108,6 +108,7 @@ jobs: ~/.cargo/git/db/ target/ crates/bevy_ecs_compile_fail_tests/target/ + crates/bevy_reflect_compile_fail_tests/target/ key: ${{ runner.os }}-cargo-check-compiles-${{ hashFiles('**/Cargo.toml') }} - uses: dtolnay/rust-toolchain@stable with: diff --git a/Cargo.toml b/Cargo.toml index 794f03d2db6205..11e7cc5fb06d98 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ readme = "README.md" repository = "https://github.com/bevyengine/bevy" [workspace] -exclude = ["benches", "crates/bevy_ecs_compile_fail_tests"] +exclude = ["benches", "crates/bevy_ecs_compile_fail_tests", "crates/bevy_reflect_compile_fail_tests"] members = [ "crates/*", "examples/android", diff --git a/crates/bevy_reflect_compile_fail_tests/Cargo.toml b/crates/bevy_reflect_compile_fail_tests/Cargo.toml new file mode 100644 index 00000000000000..5af57acd621f85 --- /dev/null +++ b/crates/bevy_reflect_compile_fail_tests/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "bevy_reflect_compile_fail_tests" +version = "0.1.0" +edition = "2021" +description = "Compile fail tests for Bevy Engine's reflection system" +homepage = "https://bevyengine.org" +repository = "https://github.com/bevyengine/bevy" +license = "MIT OR Apache-2.0" +publish = false + +[dev-dependencies] +bevy_reflect = { path = "../bevy_reflect" } +trybuild = "1.0.71" diff --git a/crates/bevy_reflect_compile_fail_tests/README.md b/crates/bevy_reflect_compile_fail_tests/README.md new file mode 100644 index 00000000000000..52faa4f1d60348 --- /dev/null +++ b/crates/bevy_reflect_compile_fail_tests/README.md @@ -0,0 +1,7 @@ +# Compile fail tests for bevy_reflect + +This crate is separate from `bevy_reflect` 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](../../tools/ci/src/main.rs)). diff --git a/crates/bevy_reflect_compile_fail_tests/src/lib.rs b/crates/bevy_reflect_compile_fail_tests/src/lib.rs new file mode 100644 index 00000000000000..d0d1683dd6b97c --- /dev/null +++ b/crates/bevy_reflect_compile_fail_tests/src/lib.rs @@ -0,0 +1 @@ +// Nothing here, check out the integration tests diff --git a/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive.rs b/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive.rs new file mode 100644 index 00000000000000..dbab6a4ef08f68 --- /dev/null +++ b/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive.rs @@ -0,0 +1,6 @@ +#[test] +fn test() { + let t = trybuild::TestCases::new(); + t.compile_fail("tests/reflect_derive/*.fail.rs"); + t.pass("tests/reflect_derive/*.pass.rs"); +} diff --git a/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/lifetimes.fail.rs b/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/lifetimes.fail.rs new file mode 100644 index 00000000000000..4a97e5d8278a2f --- /dev/null +++ b/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/lifetimes.fail.rs @@ -0,0 +1,9 @@ +use bevy_reflect::Reflect; + +#[derive(Reflect)] +struct Foo<'a> { + #[reflect(ignore)] + value: &'a str, +} + +fn main() {} diff --git a/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/lifetimes.fail.stderr b/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/lifetimes.fail.stderr new file mode 100644 index 00000000000000..156fb6cda17d7c --- /dev/null +++ b/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/lifetimes.fail.stderr @@ -0,0 +1,13 @@ +error[E0478]: lifetime bound not satisfied + --> tests/reflect_derive/lifetimes.fail.rs:3:10 + | +3 | #[derive(Reflect)] + | ^^^^^^^ + | +note: lifetime parameter instantiated with the lifetime `'a` as defined here + --> tests/reflect_derive/lifetimes.fail.rs:4:12 + | +4 | struct Foo<'a> { + | ^^ + = note: but lifetime parameter must outlive the static lifetime + = note: this error originates in the derive macro `Reflect` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/lifetimes.pass.rs b/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/lifetimes.pass.rs new file mode 100644 index 00000000000000..60d32b81f38ec5 --- /dev/null +++ b/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/lifetimes.pass.rs @@ -0,0 +1,10 @@ +use bevy_reflect::Reflect; + +// Reason: Reflection relies on `Any` which requires `'static` +#[derive(Reflect)] +struct Foo<'a: 'static> { + #[reflect(ignore)] + value: &'a str, +} + +fn main() {} diff --git a/tools/ci/src/main.rs b/tools/ci/src/main.rs index 38d720c94406b6..4fad887d3a974c 100644 --- a/tools/ci/src/main.rs +++ b/tools/ci/src/main.rs @@ -88,12 +88,24 @@ fn main() { } if what_to_run.contains(Check::COMPILE_FAIL) { - // Run UI tests (they do not get executed with the workspace tests) - // - See crates/bevy_ecs_compile_fail_tests/README.md - let _subdir = sh.push_dir("crates/bevy_ecs_compile_fail_tests"); - cmd!(sh, "cargo test --target-dir ../../target") - .run() - .expect("Compiler errors of the ECS compile fail tests seem to be different than expected! Check locally and compare rust versions."); + { + // ECS Compile Fail Tests + // Run UI tests (they do not get executed with the workspace tests) + // - See crates/bevy_ecs_compile_fail_tests/README.md + let _subdir = sh.push_dir("crates/bevy_ecs_compile_fail_tests"); + cmd!(sh, "cargo test --target-dir ../../target") + .run() + .expect("Compiler errors of the ECS compile fail tests seem to be different than expected! Check locally and compare rust versions."); + } + { + // Reflect Compile Fail Tests + // Run tests (they do not get executed with the workspace tests) + // - See crates/bevy_reflect_compile_fail_tests/README.md + let _subdir = sh.push_dir("crates/bevy_reflect_compile_fail_tests"); + cmd!(sh, "cargo test --target-dir ../../target") + .run() + .expect("Compiler errors of the Reflect compile fail tests seem to be different than expected! Check locally and compare rust versions."); + } } if what_to_run.contains(Check::TEST) {