Skip to content

Commit 549107d

Browse files
authored
Fix zombie_processes FP inside closures (#14696)
Closes rust-lang/rust-clippy#14677 changelog: [`zombie_processes`] fix FP inside closures
2 parents 542762e + 5123ad5 commit 549107d

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

clippy_lints/src/zombie_processes.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use clippy_utils::{fn_def_id, get_enclosing_block, path_to_local_id};
44
use rustc_ast::Mutability;
55
use rustc_ast::visit::visit_opt;
66
use rustc_errors::Applicability;
7+
use rustc_hir::def_id::LocalDefId;
78
use rustc_hir::intravisit::{Visitor, walk_block, walk_expr, walk_local};
89
use rustc_hir::{Expr, ExprKind, HirId, LetStmt, Node, PatKind, Stmt, StmtKind};
910
use rustc_lint::{LateContext, LateLintPass};
@@ -68,6 +69,7 @@ impl<'tcx> LateLintPass<'tcx> for ZombieProcesses {
6869
let mut vis = WaitFinder {
6970
cx,
7071
local_id,
72+
body_id: cx.tcx.hir_enclosing_body_owner(expr.hir_id),
7173
state: VisitorState::WalkUpToLocal,
7274
early_return: None,
7375
missing_wait_branch: None,
@@ -129,6 +131,7 @@ struct MaybeWait(Span);
129131
struct WaitFinder<'a, 'tcx> {
130132
cx: &'a LateContext<'tcx>,
131133
local_id: HirId,
134+
body_id: LocalDefId,
132135
state: VisitorState,
133136
early_return: Option<Span>,
134137
// When joining two if branches where one of them doesn't call `wait()`, stores its span for more targeted help
@@ -186,7 +189,7 @@ impl<'tcx> Visitor<'tcx> for WaitFinder<'_, 'tcx> {
186189
}
187190
} else {
188191
match ex.kind {
189-
ExprKind::Ret(e) => {
192+
ExprKind::Ret(e) if self.cx.tcx.hir_enclosing_body_owner(ex.hir_id) == self.body_id => {
190193
visit_opt!(self, visit_expr, e);
191194
if self.early_return.is_none() {
192195
self.early_return = Some(ex.span);

tests/ui/zombie_processes.rs

+22
Original file line numberDiff line numberDiff line change
@@ -176,3 +176,25 @@ fn return_wait() -> ExitStatus {
176176
let mut x = Command::new("").spawn().unwrap();
177177
return x.wait().unwrap();
178178
}
179+
180+
mod issue14677 {
181+
use std::io;
182+
use std::process::Command;
183+
184+
fn do_something<F: Fn() -> Result<(), ()>>(f: F) {
185+
todo!()
186+
}
187+
188+
fn foo() {
189+
let mut child = Command::new("true").spawn().unwrap();
190+
let some_condition = true;
191+
do_something(|| {
192+
if some_condition {
193+
return Err(());
194+
}
195+
Ok(())
196+
});
197+
child.kill().unwrap();
198+
child.wait().unwrap();
199+
}
200+
}

0 commit comments

Comments
 (0)