add targeted help messages to zombie_processes diagnostic (#13760)

Fixes #13748

Diagnostic for that issue with this change:
```
warning: spawned process is not `wait()`ed on in all code paths
   --> x.rs:167:19
    |
167 |     let mut cmd = cmd.unwrap();
    |                   ^^^^^^^^^^^^
    |
note: no `wait()` call exists on the code path to this early return
   --> x.rs:178:47
    |
178 |             std::io::ErrorKind::BrokenPipe => return Some(0),
    |                                               ^^^^^^^^^^^^^^
note: `wait()` call exists, but it is unreachable due to the early return
   --> x.rs:185:10
    |
185 |     Some(cmd.wait().unwrap().code().unwrap()) // <-- wait()!
    |          ^^^
    = help: consider calling `.wait()` in all code paths
    = note: not doing so might leave behind zombie processes
    = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning
```
Instead of saying "wait() is **never** called", it now says it's not
called by all code paths and points out the early return in particular.

changelog: none
This commit is contained in:
Manish Goregaokar 2024-12-02 18:42:42 +00:00 committed by GitHub
commit df46e4cf13
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 292 additions and 107 deletions

View file

@ -1,7 +1,7 @@
#![warn(clippy::zombie_processes)]
#![allow(clippy::if_same_then_else, clippy::ifs_same_cond)]
#![allow(clippy::if_same_then_else, clippy::ifs_same_cond, clippy::needless_return)]
use std::process::{Child, Command};
use std::process::{Child, Command, ExitStatus};
fn main() {
{
@ -12,7 +12,7 @@ fn main() {
{
let mut x = Command::new("").spawn().unwrap();
//~^ ERROR: spawned process is never `wait()`ed on
//~^ zombie_processes
x.kill();
x.id();
}
@ -39,7 +39,7 @@ fn main() {
}
{
let mut x = Command::new("").spawn().unwrap();
//~^ ERROR: spawned process is never `wait()`ed on
//~^ zombie_processes
let v = &x;
// (allow shared refs is fine because one cannot call `.wait()` through that)
}
@ -64,14 +64,14 @@ fn main() {
// It should assume that it might not exit and still lint
{
let mut x = Command::new("").spawn().unwrap();
//~^ ERROR: spawned process is never `wait()`ed on
//~^ zombie_processes
if true {
std::process::exit(0);
}
}
{
let mut x = Command::new("").spawn().unwrap();
//~^ ERROR: spawned process is never `wait()`ed on
//~^ zombie_processes
if true {
while false {}
// Calling `exit()` after leaving a while loop should still be linted.
@ -97,7 +97,7 @@ fn main() {
{
let mut x = Command::new("").spawn().unwrap();
//~^ ERROR: spawned process is never `wait()`ed on
//~^ zombie_processes
if true {
return;
}
@ -106,12 +106,32 @@ fn main() {
{
let mut x = Command::new("").spawn().unwrap();
//~^ ERROR: spawned process is never `wait()`ed on
//~^ zombie_processes
if true {
x.wait().unwrap();
}
}
{
let mut x = Command::new("").spawn().unwrap();
//~^ zombie_processes
if true {
x.wait().unwrap();
} else {
// this else block exists to test the other help message
}
}
{
let mut x = Command::new("").spawn().unwrap();
//~^ zombie_processes
if true {
// this else block exists to test the other help message
} else {
x.wait().unwrap();
}
}
{
let mut x = Command::new("").spawn().unwrap();
if true {
@ -143,3 +163,8 @@ fn main() {
fn process_child(c: Child) {
todo!()
}
fn return_wait() -> ExitStatus {
let mut x = Command::new("").spawn().unwrap();
return x.wait().unwrap();
}

View file

@ -4,7 +4,7 @@ error: spawned process is never `wait()`ed on
LL | let mut x = Command::new("").spawn().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: consider calling `.wait()`
= help: consider calling `.wait()`
= note: not doing so might leave behind zombie processes
= note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning
= note: `-D clippy::zombie-processes` implied by `-D warnings`
@ -16,7 +16,7 @@ error: spawned process is never `wait()`ed on
LL | let mut x = Command::new("").spawn().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: consider calling `.wait()`
= help: consider calling `.wait()`
= note: not doing so might leave behind zombie processes
= note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning
@ -26,7 +26,7 @@ error: spawned process is never `wait()`ed on
LL | let mut x = Command::new("").spawn().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: consider calling `.wait()`
= help: consider calling `.wait()`
= note: not doing so might leave behind zombie processes
= note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning
@ -36,29 +36,96 @@ error: spawned process is never `wait()`ed on
LL | let mut x = Command::new("").spawn().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: consider calling `.wait()`
= help: consider calling `.wait()`
= note: not doing so might leave behind zombie processes
= note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning
error: spawned process is never `wait()`ed on
error: spawned process is not `wait()`ed on in all code paths
--> tests/ui/zombie_processes.rs:99:21
|
LL | let mut x = Command::new("").spawn().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: consider calling `.wait()`
note: no `wait()` call exists on the code path to this early return
--> tests/ui/zombie_processes.rs:102:13
|
LL | return;
| ^^^^^^
note: `wait()` call exists, but it is unreachable due to the early return
--> tests/ui/zombie_processes.rs:104:9
|
LL | x.wait().unwrap();
| ^
= help: consider calling `.wait()` in all code paths
= note: not doing so might leave behind zombie processes
= note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning
error: spawned process is never `wait()`ed on
error: spawned process is not `wait()`ed on in all code paths
--> tests/ui/zombie_processes.rs:108:21
|
LL | let mut x = Command::new("").spawn().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: consider calling `.wait()`
note: this if expression has a `wait()` call, but it is missing an else block
--> tests/ui/zombie_processes.rs:110:9
|
LL | / if true {
LL | | x.wait().unwrap();
LL | | }
| |_________^
note: `wait()` called here
--> tests/ui/zombie_processes.rs:111:13
|
LL | x.wait().unwrap();
| ^
= help: consider calling `.wait()` in all code paths
= note: not doing so might leave behind zombie processes
= note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning
error: aborting due to 6 previous errors
error: spawned process is not `wait()`ed on in all code paths
--> tests/ui/zombie_processes.rs:116:21
|
LL | let mut x = Command::new("").spawn().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: `wait()` is not called in this if branch
--> tests/ui/zombie_processes.rs:120:10
|
LL | } else {
| __________^
LL | | // this else block exists to test the other help message
LL | | }
| |_________^
note: `wait()` is called in the other branch
--> tests/ui/zombie_processes.rs:119:13
|
LL | x.wait().unwrap();
| ^
= help: consider calling `.wait()` in all code paths
= note: not doing so might leave behind zombie processes
= note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning
error: spawned process is not `wait()`ed on in all code paths
--> tests/ui/zombie_processes.rs:126:21
|
LL | let mut x = Command::new("").spawn().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: `wait()` is not called in this if branch
--> tests/ui/zombie_processes.rs:128:9
|
LL | / if true {
LL | | // this else block exists to test the other help message
LL | | } else {
| |_________^
note: `wait()` is called in the other branch
--> tests/ui/zombie_processes.rs:131:13
|
LL | x.wait().unwrap();
| ^
= help: consider calling `.wait()` in all code paths
= note: not doing so might leave behind zombie processes
= note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning
error: aborting due to 8 previous errors