Skip to content

Commit

Permalink
Added bevy_macros_compile_fail_tests crate
Browse files Browse the repository at this point in the history
Created with compile tests for the Deref/DerefMut derives
  • Loading branch information
MrGVSV committed May 15, 2023
1 parent b04f41c commit c6e6e03
Show file tree
Hide file tree
Showing 25 changed files with 396 additions and 0 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Expand Up @@ -16,6 +16,7 @@ rust-version = "1.67.0"
exclude = [
"benches",
"crates/bevy_ecs_compile_fail_tests",
"crates/bevy_macros_compile_fail_tests",
"crates/bevy_reflect_compile_fail_tests",
]
members = [
Expand Down
13 changes: 13 additions & 0 deletions crates/bevy_macros_compile_fail_tests/Cargo.toml
@@ -0,0 +1,13 @@
[package]
name = "bevy_macros_compile_fail_tests"
version = "0.1.0"
edition = "2021"
description = "Compile fail tests for Bevy Engine's various macros"
homepage = "https://bevyengine.org"
repository = "https://github.com/bevyengine/bevy"
license = "MIT OR Apache-2.0"
publish = false

[dependencies]
bevy_derive = { path = "../bevy_derive" }
trybuild = "1.0.71"
6 changes: 6 additions & 0 deletions crates/bevy_macros_compile_fail_tests/README.md
@@ -0,0 +1,6 @@
# Compile fail tests for Bevy macros

This crate is 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)).
1 change: 1 addition & 0 deletions crates/bevy_macros_compile_fail_tests/src/lib.rs
@@ -0,0 +1 @@
// Nothing here, check out the integration tests
6 changes: 6 additions & 0 deletions crates/bevy_macros_compile_fail_tests/tests/deref_derive.rs
@@ -0,0 +1,6 @@
#[test]
fn test() {
let t = trybuild::TestCases::new();
t.compile_fail("tests/deref_derive/*.fail.rs");
t.pass("tests/deref_derive/*.pass.rs");
}
@@ -0,0 +1,9 @@
use bevy_derive::Deref;

#[derive(Deref)]
struct UnitStruct;

#[derive(Deref)]
enum Enum {}

fn main() {}
@@ -0,0 +1,15 @@
error: Deref cannot be derived on field-less structs
--> tests/deref_derive/invalid_item.fail.rs:3:10
|
3 | #[derive(Deref)]
| ^^^^^
|
= note: this error originates in the derive macro `Deref` (in Nightly builds, run with -Z macro-backtrace for more info)

error: Deref can only be derived on structs
--> tests/deref_derive/invalid_item.fail.rs:6:10
|
6 | #[derive(Deref)]
| ^^^^^
|
= note: this error originates in the derive macro `Deref` (in Nightly builds, run with -Z macro-backtrace for more info)
@@ -0,0 +1,12 @@
use bevy_derive::Deref;

#[derive(Deref)]
struct TupleStruct(usize, String);

#[derive(Deref)]
struct Struct {
foo: usize,
bar: String,
}

fn main() {}
@@ -0,0 +1,15 @@
error: deriving Deref on multi-field structs requires one field to have the `#[deref]` attribute
--> tests/deref_derive/missing_attribute.fail.rs:3:10
|
3 | #[derive(Deref)]
| ^^^^^
|
= note: this error originates in the derive macro `Deref` (in Nightly builds, run with -Z macro-backtrace for more info)

error: deriving Deref on multi-field structs requires one field to have the `#[deref]` attribute
--> tests/deref_derive/missing_attribute.fail.rs:6:10
|
6 | #[derive(Deref)]
| ^^^^^
|
= note: this error originates in the derive macro `Deref` (in Nightly builds, run with -Z macro-backtrace for more info)
@@ -0,0 +1,14 @@
use bevy_derive::Deref;

#[derive(Deref)]
struct TupleStruct(#[deref] usize, #[deref] String);

#[derive(Deref)]
struct Struct {
#[deref]
foo: usize,
#[deref]
bar: String,
}

fn main() {}
@@ -0,0 +1,11 @@
error: `#[deref]` attribute can only be used on a single field
--> tests/deref_derive/multiple_attributes.fail.rs:4:36
|
4 | struct TupleStruct(#[deref] usize, #[deref] String);
| ^^^^^^^^

error: `#[deref]` attribute can only be used on a single field
--> tests/deref_derive/multiple_attributes.fail.rs:10:5
|
10 | #[deref]
| ^^^^^^^^
@@ -0,0 +1,22 @@
use bevy_derive::Deref;

#[derive(Deref)]
struct TupleStruct(usize, #[deref] String);

#[derive(Deref)]
struct Struct {
foo: usize,
#[deref]
bar: String,
}

fn main() {
let value = TupleStruct(123, "Hello world!".to_string());
let _: &String = &*value;

let value = Struct {
foo: 123,
bar: "Hello world!".to_string(),
};
let _: &String = &*value;
}
@@ -0,0 +1,6 @@
#[test]
fn test() {
let t = trybuild::TestCases::new();
t.compile_fail("tests/deref_mut_derive/*.fail.rs");
t.pass("tests/deref_mut_derive/*.pass.rs");
}
@@ -0,0 +1,9 @@
use bevy_derive::DerefMut;

#[derive(DerefMut)]
struct UnitStruct;

#[derive(DerefMut)]
enum Enum {}

fn main() {}
@@ -0,0 +1,15 @@
error: DerefMut cannot be derived on field-less structs
--> tests/deref_mut_derive/invalid_item.fail.rs:3:10
|
3 | #[derive(DerefMut)]
| ^^^^^^^^
|
= note: this error originates in the derive macro `DerefMut` (in Nightly builds, run with -Z macro-backtrace for more info)

error: DerefMut can only be derived on structs
--> tests/deref_mut_derive/invalid_item.fail.rs:6:10
|
6 | #[derive(DerefMut)]
| ^^^^^^^^
|
= note: this error originates in the derive macro `DerefMut` (in Nightly builds, run with -Z macro-backtrace for more info)
@@ -0,0 +1,30 @@
use bevy_derive::DerefMut;
use std::ops::Deref;

#[derive(DerefMut)]
struct TupleStruct(#[deref] usize, String);

impl Deref for TupleStruct {
type Target = String;

fn deref(&self) -> &Self::Target {
&self.1
}
}

#[derive(DerefMut)]
struct Struct {
#[deref]
foo: usize,
bar: String,
}

impl Deref for Struct {
type Target = String;

fn deref(&self) -> &Self::Target {
&self.bar
}
}

fn main() {}
@@ -0,0 +1,25 @@
error[E0308]: mismatched types
--> tests/deref_mut_derive/mismatched_target_type.fail.rs:4:10
|
4 | #[derive(DerefMut)]
| ^^^^^^^^
| |
| expected `&mut String`, found `&mut usize`
| expected `&mut String` because of return type
|
= note: expected mutable reference `&mut String`
found mutable reference `&mut usize`
= note: this error originates in the derive macro `DerefMut` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
--> tests/deref_mut_derive/mismatched_target_type.fail.rs:15:10
|
15 | #[derive(DerefMut)]
| ^^^^^^^^
| |
| expected `&mut String`, found `&mut usize`
| expected `&mut String` because of return type
|
= note: expected mutable reference `&mut String`
found mutable reference `&mut usize`
= note: this error originates in the derive macro `DerefMut` (in Nightly builds, run with -Z macro-backtrace for more info)
@@ -0,0 +1,29 @@
use bevy_derive::DerefMut;
use std::ops::Deref;

#[derive(DerefMut)]
struct TupleStruct(usize, String);

impl Deref for TupleStruct {
type Target = String;

fn deref(&self) -> &Self::Target {
&self.1
}
}

#[derive(DerefMut)]
struct Struct {
foo: usize,
bar: String,
}

impl Deref for Struct {
type Target = String;

fn deref(&self) -> &Self::Target {
&self.bar
}
}

fn main() {}
@@ -0,0 +1,15 @@
error: deriving DerefMut on multi-field structs requires one field to have the `#[deref]` attribute
--> tests/deref_mut_derive/missing_attribute.fail.rs:4:10
|
4 | #[derive(DerefMut)]
| ^^^^^^^^
|
= note: this error originates in the derive macro `DerefMut` (in Nightly builds, run with -Z macro-backtrace for more info)

error: deriving DerefMut on multi-field structs requires one field to have the `#[deref]` attribute
--> tests/deref_mut_derive/missing_attribute.fail.rs:15:10
|
15 | #[derive(DerefMut)]
| ^^^^^^^^
|
= note: this error originates in the derive macro `DerefMut` (in Nightly builds, run with -Z macro-backtrace for more info)
@@ -0,0 +1,13 @@
use bevy_derive::DerefMut;

#[derive(DerefMut)]
struct TupleStruct(usize, #[deref] String);

#[derive(DerefMut)]
struct Struct {
foo: usize,
#[deref]
bar: String,
}

fn main() {}
@@ -0,0 +1,39 @@
error[E0277]: the trait bound `TupleStruct: Deref` is not satisfied
--> tests/deref_mut_derive/missing_deref.fail.rs:4:8
|
4 | struct TupleStruct(usize, #[deref] String);
| ^^^^^^^^^^^ the trait `Deref` is not implemented for `TupleStruct`
|
note: required by a bound in `DerefMut`
--> $RUST/core/src/ops/deref.rs
|
| pub trait DerefMut: Deref {
| ^^^^^ required by this bound in `DerefMut`

error[E0277]: the trait bound `Struct: Deref` is not satisfied
--> tests/deref_mut_derive/missing_deref.fail.rs:7:8
|
7 | struct Struct {
| ^^^^^^ the trait `Deref` is not implemented for `Struct`
|
note: required by a bound in `DerefMut`
--> $RUST/core/src/ops/deref.rs
|
| pub trait DerefMut: Deref {
| ^^^^^ required by this bound in `DerefMut`

error[E0277]: the trait bound `TupleStruct: Deref` is not satisfied
--> tests/deref_mut_derive/missing_deref.fail.rs:3:10
|
3 | #[derive(DerefMut)]
| ^^^^^^^^ the trait `Deref` is not implemented for `TupleStruct`
|
= note: this error originates in the derive macro `DerefMut` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `Struct: Deref` is not satisfied
--> tests/deref_mut_derive/missing_deref.fail.rs:6:10
|
6 | #[derive(DerefMut)]
| ^^^^^^^^ the trait `Deref` is not implemented for `Struct`
|
= note: this error originates in the derive macro `DerefMut` (in Nightly builds, run with -Z macro-backtrace for more info)
@@ -0,0 +1,31 @@
use bevy_derive::DerefMut;
use std::ops::Deref;

#[derive(DerefMut)]
struct TupleStruct(#[deref] usize, #[deref] String);

impl Deref for TupleStruct {
type Target = String;

fn deref(&self) -> &Self::Target {
&self.1
}
}

#[derive(DerefMut)]
struct Struct {
#[deref]
foo: usize,
#[deref]
bar: String,
}

impl Deref for Struct {
type Target = String;

fn deref(&self) -> &Self::Target {
&self.bar
}
}

fn main() {}
@@ -0,0 +1,11 @@
error: `#[deref]` attribute can only be used on a single field
--> tests/deref_mut_derive/multiple_attributes.fail.rs:5:36
|
5 | struct TupleStruct(#[deref] usize, #[deref] String);
| ^^^^^^^^

error: `#[deref]` attribute can only be used on a single field
--> tests/deref_mut_derive/multiple_attributes.fail.rs:19:5
|
19 | #[deref]
| ^^^^^^^^

0 comments on commit c6e6e03

Please sign in to comment.