Add print_stdout and print_stderr lints (#17446) (#18233)

# Objective

- Prevent usage of `println!`, `eprintln!` and the like because they
require `std`
- Fixes #17446

## Solution

- Enable the `print_stdout` and `print_stderr` clippy lints
- Replace all `println!` and `eprintln!` occurrences with `log::*` where
applicable or alternatively ignore the warnings

## Testing

- Run `cargo clippy --workspace` to ensure that there are no warnings
relating to printing to `stdout` or `stderr`
This commit is contained in:
Cyrill Schenkel 2025-03-11 20:35:48 +01:00 committed by GitHub
parent 4f6241178f
commit 8570af1d96
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
26 changed files with 58 additions and 14 deletions

View File

@ -51,6 +51,8 @@ unwrap_or_default = "warn"
needless_lifetimes = "allow"
too_many_arguments = "allow"
nonstandard_macro_braces = "warn"
print_stdout = "warn"
print_stderr = "warn"
ptr_as_ptr = "warn"
ptr_cast_constness = "warn"

View File

@ -281,6 +281,7 @@ unsafe impl<A: AsAssetId> QueryFilter for AssetChanged<A> {
}
#[cfg(test)]
#[expect(clippy::print_stdout, reason = "Allowed in tests.")]
mod tests {
use crate::{AssetEvents, AssetPlugin, Handle};
use alloc::{vec, vec::Vec};

View File

@ -8,6 +8,7 @@
#![expect(
clippy::std_instead_of_core,
clippy::print_stdout,
reason = "Examples should not follow this lint"
)]

View File

@ -1,6 +1,8 @@
//! In this example a system sends a custom event with a 50/50 chance during any frame.
//! If an event was send, it will be printed by the console in a receiving system.
#![expect(clippy::print_stdout, reason = "Allowed in examples.")]
use bevy_ecs::{event::EventRegistry, prelude::*};
fn main() {

View File

@ -3,6 +3,7 @@
#![expect(
clippy::std_instead_of_core,
clippy::print_stdout,
reason = "Examples should not follow this lint"
)]

View File

@ -139,6 +139,7 @@ std::thread_local! {
/// When called, this will skip the currently configured panic hook when a [`BevyError`] backtrace has already been printed.
#[cfg(feature = "backtrace")]
#[expect(clippy::print_stdout, reason = "Allowed behind `std` feature gate.")]
pub fn bevy_error_panic_hook(
current_hook: impl Fn(&std::panic::PanicHookInfo),
) -> impl Fn(&std::panic::PanicHookInfo) {

View File

@ -2585,6 +2585,7 @@ impl<T> Ord for NeutralOrd<T> {
}
#[cfg(test)]
#[expect(clippy::print_stdout, reason = "Allowed in tests.")]
mod tests {
use alloc::vec::Vec;
use std::println;

View File

@ -102,6 +102,7 @@ impl<T> DebugCheckedUnwrap for Option<T> {
}
#[cfg(test)]
#[expect(clippy::print_stdout, reason = "Allowed in tests.")]
mod tests {
use crate::{
archetype::Archetype,

View File

@ -5,10 +5,9 @@ use bevy_utils::{default, syncunsafecell::SyncUnsafeCell};
use concurrent_queue::ConcurrentQueue;
use core::{any::Any, panic::AssertUnwindSafe};
use fixedbitset::FixedBitSet;
use std::{
eprintln,
sync::{Mutex, MutexGuard},
};
#[cfg(feature = "std")]
use std::eprintln;
use std::sync::{Mutex, MutexGuard};
#[cfg(feature = "trace")]
use tracing::{info_span, Span};
@ -283,7 +282,11 @@ impl<'scope, 'env: 'scope, 'sys> Context<'scope, 'env, 'sys> {
.push(SystemResult { system_index })
.unwrap_or_else(|error| unreachable!("{}", error));
if let Err(payload) = res {
#[cfg(feature = "std")]
#[expect(clippy::print_stderr, reason = "Allowed behind `std` feature gate.")]
{
eprintln!("Encountered a panic in system `{}`!", &*system.name());
}
// set the payload to propagate the error
{
let mut panic_payload = self.environment.executor.panic_payload.lock().unwrap();
@ -741,10 +744,14 @@ fn apply_deferred(
system.apply_deferred(world);
}));
if let Err(payload) = res {
#[cfg(feature = "std")]
#[expect(clippy::print_stderr, reason = "Allowed behind `std` feature gate.")]
{
eprintln!(
"Encountered a panic when applying buffers for system `{}`!",
&*system.name()
);
}
return Err(payload);
}
}

View File

@ -118,6 +118,7 @@ impl SystemExecutor for SimpleExecutor {
});
#[cfg(feature = "std")]
#[expect(clippy::print_stderr, reason = "Allowed behind `std` feature gate.")]
{
if let Err(payload) = std::panic::catch_unwind(f) {
eprintln!("Encountered a panic in system `{}`!", &*system.name());

View File

@ -144,6 +144,7 @@ impl SystemExecutor for SingleThreadedExecutor {
});
#[cfg(feature = "std")]
#[expect(clippy::print_stderr, reason = "Allowed behind `std` feature gate.")]
{
if let Err(payload) = std::panic::catch_unwind(f) {
eprintln!("Encountered a panic in system `{}`!", &*system.name());

View File

@ -823,6 +823,7 @@ impl ScheduleState {
}
#[cfg(all(test, feature = "bevy_debug_stepping"))]
#[expect(clippy::print_stdout, reason = "Allowed in tests.")]
mod tests {
use super::*;
use crate::{prelude::*, schedule::ScheduleLabel};

View File

@ -323,6 +323,7 @@ pub fn assert_system_does_not_conflict<Out, Params, S: IntoSystem<(), Out, Param
}
#[cfg(test)]
#[expect(clippy::print_stdout, reason = "Allowed in tests.")]
mod tests {
use alloc::{vec, vec::Vec};
use bevy_utils::default;

View File

@ -3663,6 +3663,7 @@ impl<T: Default> FromWorld for T {
}
#[cfg(test)]
#[expect(clippy::print_stdout, reason = "Allowed in tests.")]
mod tests {
use super::{FromWorld, World};
use crate::{

View File

@ -259,6 +259,7 @@ impl Default for LogPlugin {
}
impl Plugin for LogPlugin {
#[expect(clippy::print_stderr, reason = "Allowed during logger setup")]
fn build(&self, app: &mut App) {
#[cfg(feature = "trace")]
{

View File

@ -438,6 +438,7 @@ impl Bounded2d for Capsule2d {
}
#[cfg(test)]
#[expect(clippy::print_stdout, reason = "Allowed in tests.")]
mod tests {
use core::f32::consts::{FRAC_PI_2, FRAC_PI_3, FRAC_PI_4, FRAC_PI_6, TAU};
use std::println;

View File

@ -69,12 +69,15 @@ fn assert_is_normalized(message: &str, length_squared: f32) {
} else if length_error_squared > 2e-4 {
// Length error is approximately 1e-4 or more.
#[cfg(feature = "std")]
#[expect(clippy::print_stderr, reason = "Allowed behind `std` feature gate.")]
{
eprintln!(
"Warning: {message} The length is {}.",
ops::sqrt(length_squared)
);
}
}
}
/// A normalized vector pointing in a direction in 2D space
#[derive(Clone, Copy, Debug, PartialEq)]

View File

@ -5,6 +5,7 @@
clippy::useless_conversion,
reason = "Crate auto-generated with many non-idiomatic decisions. See #7372 for details."
)]
#![expect(clippy::print_stdout, reason = "Allowed in examples.")]
use glam::{Vec2, Vec3};

View File

@ -6,6 +6,8 @@
//!
//! These scenarios can readily be achieved by using `bevy_reflect` with the `documentation` feature.
#![expect(clippy::print_stdout, reason = "Allowed in examples.")]
use bevy_reflect::{Reflect, TypeInfo, Typed};
fn main() {

View File

@ -1758,6 +1758,7 @@ fn get_resource_type_registration<'r>(
}
#[cfg(test)]
#[expect(clippy::print_stdout, reason = "Allowed in tests.")]
mod tests {
/// A generic function that tests serialization and deserialization of any type
/// implementing Serialize and Deserialize traits.

View File

@ -2,6 +2,8 @@
//! for 100ms. It's expected to take about a second to run (assuming the machine has >= 4 logical
//! cores)
#![expect(clippy::print_stdout, reason = "Allowed in examples.")]
use bevy_platform_support::time::Instant;
use bevy_tasks::TaskPoolBuilder;
use core::time::Duration;

View File

@ -2,6 +2,8 @@
//! spinning. Other than the one thread, the system should remain idle, demonstrating good behavior
//! for small workloads.
#![expect(clippy::print_stdout, reason = "Allowed in examples.")]
use bevy_platform_support::time::Instant;
use bevy_tasks::TaskPoolBuilder;
use core::time::Duration;

View File

@ -175,6 +175,7 @@ pub fn time_system(
}
#[cfg(test)]
#[expect(clippy::print_stdout, reason = "Allowed in tests.")]
mod tests {
use crate::{Fixed, Time, TimePlugin, TimeUpdateStrategy, Virtual};
use bevy_app::{App, FixedUpdate, Startup, Update};

View File

@ -27,9 +27,12 @@ fn assert_is_normalized(message: &str, length_squared: f32) {
} else if length_error_squared > 2e-4 {
// Length error is approximately 1e-4 or more.
#[cfg(feature = "std")]
#[expect(clippy::print_stderr, reason = "Allowed behind `std` feature gate.")]
{
eprintln!("Warning: {message}",);
}
}
}
/// Describe the position of an entity. If the entity has a parent, the position is relative
/// to its parent position.

View File

@ -1,4 +1,7 @@
//! Generates graphs for the `EaseFunction` docs.
#![expect(clippy::print_stdout, reason = "Allowed in tools.")]
use std::path::PathBuf;
use bevy_math::curve::{CurveExt, EaseFunction, EasingCurve, JumpAt};

View File

@ -1,5 +1,7 @@
//! Tool to run all examples or generate a showcase page for the Bevy website.
#![expect(clippy::print_stdout, reason = "Allowed in tools.")]
use core::{
fmt::Display,
hash::{Hash, Hasher},