diff --git a/bevy_lint/src/lib.rs b/bevy_lint/src/lib.rs index 42c76e1e..c84683ab 100644 --- a/bevy_lint/src/lib.rs +++ b/bevy_lint/src/lib.rs @@ -2,6 +2,8 @@ #![feature(rustc_private)] // Allows chaining `if let` multiple times using `&&`. #![feature(let_chains)] +// Warn on internal `rustc` lints that check for poor usage of internal compiler APIs. +#![warn(rustc::internal)] // This is a list of every single `rustc` crate used within this library. If you need another, add // it here! diff --git a/bevy_lint/tests/ui.rs b/bevy_lint/tests/ui.rs index 2213ef43..ea5e2f00 100644 --- a/bevy_lint/tests/ui.rs +++ b/bevy_lint/tests/ui.rs @@ -82,8 +82,10 @@ fn config() -> color_eyre::Result { #[derive(Deserialize, Debug)] #[serde(rename = "compiler-artifact", tag = "reason")] struct ArtifactMessage<'a> { - package_id: &'a str, + #[serde(borrow)] target: ArtifactTarget<'a>, + + #[serde(borrow)] filenames: Vec<&'a Path>, } @@ -91,6 +93,8 @@ struct ArtifactMessage<'a> { #[derive(Deserialize, Debug)] struct ArtifactTarget<'a> { name: &'a str, + + #[serde(borrow)] kind: Vec<&'a str>, } @@ -114,19 +118,17 @@ fn find_bevy_rlib() -> color_eyre::Result { ensure!(output.status.success(), "`cargo build --test=ui` failed."); - // The package ID of the `bevy` crate starts with this string. - const BEVY_PACKAGE_ID_PREFIX: &str = - "registry+https://github.com/rust-lang/crates.io-index#bevy@"; - // It's theoretically possible for there to be multiple messages about building `libbevy.rlib`. // We support this, but optimize for just 1 message. let mut messages = Vec::with_capacity(1); + // Convert the `stdout` to a string, replacing invalid characters with `�`. + let stdout = String::from_utf8_lossy(&output.stdout); + // Iterate over each line in stdout, trying to deserialize it from JSON. - for line in output.stdout.split(|&byte| byte == b'\n') { - if let Ok(message) = serde_json::from_slice::(line) + for line in stdout.lines() { + if let Ok(message) = serde_json::from_str::(line) // If the message passes the following conditions, it's probably the one we want. - && message.package_id.starts_with(BEVY_PACKAGE_ID_PREFIX) && message.target.name == "bevy" && message.target.kind.contains(&"lib") { diff --git a/bevy_lint/tests/ui/main_return_without_appexit.rs b/bevy_lint/tests/ui/main_return_without_appexit.rs new file mode 100644 index 00000000..8e6cffb1 --- /dev/null +++ b/bevy_lint/tests/ui/main_return_without_appexit.rs @@ -0,0 +1,10 @@ +#![feature(register_tool)] +#![register_tool(bevy)] +#![deny(bevy::main_return_without_appexit)] + +use bevy::prelude::*; + +fn main() { + App::new().run(); + //~^ ERROR: an entrypoint that calls `App::run()` does not return `AppExit` +} diff --git a/bevy_lint/tests/ui/main_return_without_appexit.stderr b/bevy_lint/tests/ui/main_return_without_appexit.stderr new file mode 100644 index 00000000..c5b137f0 --- /dev/null +++ b/bevy_lint/tests/ui/main_return_without_appexit.stderr @@ -0,0 +1,17 @@ +error: an entrypoint that calls `App::run()` does not return `AppExit` + --> tests/ui/main_return_without_appexit.rs:8:16 + | +7 | fn main() { + | - help: try: `-> AppExit` +8 | App::new().run(); + | ^^^^^ + | + = note: `App::run()` returns `AppExit`, which can be used to determine whether the app exited successfully or not +note: the lint level is defined here + --> tests/ui/main_return_without_appexit.rs:3:9 + | +3 | #![deny(bevy::main_return_without_appexit)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error +