Skip to content

Commit

Permalink
Add print_stdout and print_stderr lints (#17446)
Browse files Browse the repository at this point in the history
  • Loading branch information
sirius94 committed Mar 10, 2025
1 parent 3b9e2e6 commit a5138bc
Show file tree
Hide file tree
Showing 23 changed files with 101 additions and 35 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_asset/src/asset_changed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,8 +284,8 @@ unsafe impl<A: AsAssetId> QueryFilter for AssetChanged<A> {
mod tests {
use crate::{AssetEvents, AssetPlugin, Handle};
use alloc::{vec, vec::Vec};
use bevy_log::info;
use core::num::NonZero;
use std::println;

use crate::{AssetApp, Assets};
use bevy_app::{App, AppExit, PostUpdate, Startup, TaskPoolPlugin, Update};
Expand Down Expand Up @@ -356,7 +356,7 @@ mod tests {
.find_map(|(h, a)| (a.0 == i).then_some(h))
.unwrap();
let asset = assets.get_mut(id).unwrap();
println!("setting new value for {}", asset.0);
info!("setting new value for {}", asset.0);
asset.1 = "new_value";
};
match *run_count {
Expand Down
13 changes: 7 additions & 6 deletions crates/bevy_ecs/examples/change_detection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
)]

use bevy_ecs::prelude::*;
use log::info;
use rand::Rng;
use std::ops::Deref;

Expand All @@ -37,7 +38,7 @@ fn main() {

// Simulate 10 frames in our world
for iteration in 1..=10 {
println!("Simulating frame {iteration}/10");
info!("Simulating frame {iteration}/10");
schedule.run(&mut world);
}
}
Expand Down Expand Up @@ -67,7 +68,7 @@ enum SimulationSet {
fn spawn_entities(mut commands: Commands, mut entity_counter: ResMut<EntityCounter>) {
if rand::thread_rng().gen_bool(0.6) {
let entity_id = commands.spawn(Age::default()).id();
println!(" spawning {entity_id:?}");
info!(" spawning {entity_id:?}");
entity_counter.value += 1;
}
}
Expand All @@ -83,10 +84,10 @@ fn print_changed_entities(
entity_with_mutated_component: Query<(Entity, &Age), Changed<Age>>,
) {
for entity in &entity_with_added_component {
println!(" {entity} has it's first birthday!");
info!(" {entity} has it's first birthday!");
}
for (entity, value) in &entity_with_mutated_component {
println!(" {entity} is now {value:?} frames old");
info!(" {entity} is now {value:?} frames old");
}
}

Expand All @@ -101,7 +102,7 @@ fn age_all_entities(mut entities: Query<&mut Age>) {
fn remove_old_entities(mut commands: Commands, entities: Query<(Entity, &Age)>) {
for (entity, age) in &entities {
if age.frames > 2 {
println!(" despawning {entity} due to age > 2");
info!(" despawning {entity} due to age > 2");
commands.entity(entity).despawn();
}
}
Expand All @@ -111,7 +112,7 @@ fn remove_old_entities(mut commands: Commands, entities: Query<(Entity, &Age)>)
// the last execution of the system.
fn print_counter_when_changed(entity_counter: Res<EntityCounter>) {
if entity_counter.is_changed() {
println!(
info!(
" total number of entities spawned: {}",
entity_counter.deref().value
);
Expand Down
5 changes: 3 additions & 2 deletions crates/bevy_ecs/examples/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//! If an event was send, it will be printed by the console in a receiving system.
use bevy_ecs::{event::EventRegistry, prelude::*};
use log::info;

fn main() {
// Create a new empty world and add the event as a resource
Expand Down Expand Up @@ -29,7 +30,7 @@ fn main() {

// Simulate 10 frames of our world
for iteration in 1..=10 {
println!("Simulating frame {iteration}/10");
info!("Simulating frame {iteration}/10");
schedule.run(&mut world);
}
}
Expand All @@ -56,7 +57,7 @@ fn sending_system(mut event_writer: EventWriter<MyEvent>) {
// If an event is received it will be printed to the console
fn receiving_system(mut event_reader: EventReader<MyEvent>) {
for my_event in event_reader.read() {
println!(
info!(
" Received message {}, with random value of {}",
my_event.message, my_event.random_value
);
Expand Down
7 changes: 4 additions & 3 deletions crates/bevy_ecs/examples/resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
)]

use bevy_ecs::prelude::*;
use log::info;
use rand::Rng;
use std::ops::Deref;

Expand All @@ -24,7 +25,7 @@ fn main() {
schedule.add_systems((increase_counter, print_counter).chain());

for iteration in 1..=10 {
println!("Simulating frame {iteration}/10");
info!("Simulating frame {iteration}/10");
schedule.run(&mut world);
}
}
Expand All @@ -38,10 +39,10 @@ struct Counter {
fn increase_counter(mut counter: ResMut<Counter>) {
if rand::thread_rng().gen_bool(0.5) {
counter.value += 1;
println!(" Increased counter value");
info!(" Increased counter value");
}
}

fn print_counter(counter: Res<Counter>) {
println!(" {:?}", counter.deref());
info!(" {:?}", counter.deref());
}
8 changes: 6 additions & 2 deletions crates/bevy_ecs/src/error/bevy_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,15 +137,19 @@ static SKIP_NORMAL_BACKTRACE: core::sync::atomic::AtomicUsize =

/// When called, this will skip the currently configured panic hook when a [`BevyError`] backtrace has already been printed.
#[cfg(feature = "std")]
#[expect(
clippy::print_stderr,
reason = "Panics should be printed even if no logger is set up."
)]
pub fn bevy_error_panic_hook(
current_hook: impl Fn(&std::panic::PanicHookInfo),
) -> impl Fn(&std::panic::PanicHookInfo) {
move |info| {
if SKIP_NORMAL_BACKTRACE.load(core::sync::atomic::Ordering::Relaxed) > 0 {
if let Some(payload) = info.payload().downcast_ref::<&str>() {
std::println!("{payload}");
std::eprintln!("{payload}");
} else if let Some(payload) = info.payload().downcast_ref::<alloc::string::String>() {
std::println!("{payload}");
std::eprintln!("{payload}");
}
SKIP_NORMAL_BACKTRACE.store(0, core::sync::atomic::Ordering::Relaxed);
return;
Expand Down
4 changes: 4 additions & 0 deletions crates/bevy_ecs/src/query/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2585,6 +2585,10 @@ impl<T> Ord for NeutralOrd<T> {
}

#[cfg(test)]
#[expect(
clippy::print_stdout,
reason = "It's acceptable to print to stdout inside of tests."
)]
mod tests {
use alloc::vec::Vec;
use std::println;
Expand Down
7 changes: 4 additions & 3 deletions crates/bevy_ecs/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ mod tests {
use alloc::{vec, vec::Vec};
use bevy_ecs_macros::QueryFilter;
use core::{any::type_name, fmt::Debug, hash::Hash};
use std::{collections::HashSet, println};
use log::info;
use std::collections::HashSet;

#[derive(Component, Debug, Hash, Eq, PartialEq, Clone, Copy, PartialOrd, Ord)]
struct A(usize);
Expand Down Expand Up @@ -199,7 +200,7 @@ mod tests {
query_type: &'static str,
) {
let len = iterator.len();
println!("len: {len}");
info!("len: {len}");
assert_all_sizes_iterator_equal(iterator, expected_size, skip, query_type);
assert_eq!(len, expected_size);
}
Expand All @@ -219,7 +220,7 @@ mod tests {
// the value is accurate to what the query returns.
let count = iterator.count();
// This will show up when one of the asserts in this function fails
println!(
info!(
"query declared sizes: \n\
for query: {query_type} \n\
expected: {expected_size} \n\
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ecs/src/schedule/executor/multi_threaded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ impl<'scope, 'env: 'scope, 'sys> Context<'scope, 'env, 'sys> {
.push(SystemResult { system_index })
.unwrap_or_else(|error| unreachable!("{}", error));
if let Err(payload) = res {
eprintln!("Encountered a panic in system `{}`!", &*system.name());
log::error!("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();
Expand Down
4 changes: 4 additions & 0 deletions crates/bevy_ecs/src/schedule/executor/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ impl SystemExecutor for SimpleExecutor {
});

#[cfg(feature = "std")]
#[expect(
clippy::print_stderr,
reason = "Printing information pertaining to panic to `stderr` is ok behind `std` feature flag."
)]
{
if let Err(payload) = std::panic::catch_unwind(f) {
eprintln!("Encountered a panic in system `{}`!", &*system.name());
Expand Down
4 changes: 4 additions & 0 deletions crates/bevy_ecs/src/schedule/executor/single_threaded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ impl SystemExecutor for SingleThreadedExecutor {
});

#[cfg(feature = "std")]
#[expect(
clippy::print_stderr,
reason = "Printing information pertaining to panic to `stderr` is ok behind `std` feature flag."
)]
{
if let Err(payload) = std::panic::catch_unwind(f) {
eprintln!("Encountered a panic in system `{}`!", &*system.name());
Expand Down
5 changes: 3 additions & 2 deletions crates/bevy_ecs/src/system/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,6 @@ mod tests {
use alloc::{vec, vec::Vec};
use bevy_utils::default;
use core::any::TypeId;
use std::println;

use crate::{
archetype::{ArchetypeComponentId, Archetypes},
Expand Down Expand Up @@ -375,9 +374,11 @@ mod tests {

#[test]
fn simple_system() {
use log::info;

fn sys(query: Query<&A>) {
for a in &query {
println!("{a:?}");
info!("{a:?}");
}
}

Expand Down
9 changes: 5 additions & 4 deletions crates/bevy_ecs/src/world/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3648,7 +3648,8 @@ mod tests {
panic,
sync::atomic::{AtomicBool, AtomicU32, Ordering},
};
use std::{println, sync::Mutex};
use log::info;
use std::sync::Mutex;

type ID = u8;

Expand All @@ -3673,7 +3674,7 @@ mod tests {
should_panic: bool,
id: u8,
) -> Self {
println!("creating component with id {id}");
info!("creating component with id {id}");
drop_log.lock().unwrap().push(DropLogItem::Create(id));

Self {
Expand All @@ -3687,7 +3688,7 @@ mod tests {

impl Drop for MayPanicInDrop {
fn drop(&mut self) {
println!("dropping component with id {}", self.id);
info!("dropping component with id {}", self.id);

{
let mut drop_log = self.drop_log.lock().unwrap();
Expand Down Expand Up @@ -3748,7 +3749,7 @@ mod tests {
.insert(helper.make_component(true, 0))
.insert(helper.make_component(false, 1));

println!("Done inserting! Dropping world...");
info!("Done inserting! Dropping world...");
});

let drop_log = helper.finish(res);
Expand Down
5 changes: 4 additions & 1 deletion crates/bevy_log/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,10 @@ impl Default for LogPlugin {
}

impl Plugin for LogPlugin {
#[expect(
clippy::print_stderr,
reason = "We cannot use the `error!` macro here because the logger is not ready yet."
)]
fn build(&self, app: &mut App) {
#[cfg(feature = "trace")]
{
Expand All @@ -282,7 +286,6 @@ impl Plugin for LogPlugin {
.source()
.and_then(|source| source.downcast_ref::<ParseError>())
.map(|parse_err| {
// we cannot use the `error!` macro here because the logger is not ready yet.
eprintln!("LogPlugin failed to parse filter from env: {}", parse_err);
});

Expand Down
4 changes: 4 additions & 0 deletions crates/bevy_math/src/bounding/bounded2d/primitive_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,10 @@ impl Bounded2d for Capsule2d {
}

#[cfg(test)]
#[expect(
clippy::print_stdout,
reason = "It's acceptable to print to stdout inside of tests and this crate does not depend on `bevy_log`."
)]
mod tests {
use core::f32::consts::{FRAC_PI_2, FRAC_PI_3, FRAC_PI_4, FRAC_PI_6, TAU};
use std::println;
Expand Down
14 changes: 10 additions & 4 deletions crates/bevy_math/src/direction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,16 @@ 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")]
eprintln!(
"Warning: {message} The length is {}.",
ops::sqrt(length_squared)
);
#[expect(
clippy::print_stderr,
reason = "This is ok behind `std` feature flag and this crate does not depend on `bevy_log`."
)]
{
eprintln!(
"Warning: {message} The length is {}.",
ops::sqrt(length_squared)
);
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions crates/bevy_mikktspace/examples/generate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
clippy::useless_conversion,
reason = "Crate auto-generated with many non-idiomatic decisions. See #7372 for details."
)]
#![expect(
clippy::print_stdout,
reason = "This crate does not depend on `bevy_log`."
)]

use glam::{Vec2, Vec3};

Expand Down
4 changes: 4 additions & 0 deletions crates/bevy_remote/src/builtin_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1758,6 +1758,10 @@ fn get_resource_type_registration<'r>(
}

#[cfg(test)]
#[expect(
clippy::print_stdout,
reason = "It's acceptable to print to stdout inside of tests and this crate does not depend on `bevy_log`."
)]
mod tests {
/// A generic function that tests serialization and deserialization of any type
/// implementing Serialize and Deserialize traits.
Expand Down
5 changes: 5 additions & 0 deletions crates/bevy_tasks/examples/busy_behavior.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
//! for 100ms. It's expected to take about a second to run (assuming the machine has >= 4 logical
//! cores)
#![expect(
clippy::print_stdout,
reason = "Printing to stdout is ok in examples and this crate does not depend on `bevy_log`."
)]

use bevy_platform_support::time::Instant;
use bevy_tasks::TaskPoolBuilder;
use core::time::Duration;
Expand Down
5 changes: 5 additions & 0 deletions crates/bevy_tasks/examples/idle_behavior.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
//! spinning. Other than the one thread, the system should remain idle, demonstrating good behavior
//! for small workloads.
#![expect(
clippy::print_stdout,
reason = "Printing to stdout is ok in examples and this crate does not depend on `bevy_log`."
)]

use bevy_platform_support::time::Instant;
use bevy_tasks::TaskPoolBuilder;
use core::time::Duration;
Expand Down
Loading

0 comments on commit a5138bc

Please sign in to comment.