zombie_processes: do not complain about early early returns
If an early return is found under the HIR local declaration node but before the child process is created, it should not trigger the lint because the child process has not yet been created.
This commit is contained in:
parent
beaf15532a
commit
3c8bfd144b
2 changed files with 21 additions and 15 deletions
|
|
@ -5,7 +5,7 @@ use rustc_ast::Mutability;
|
|||
use rustc_ast::visit::visit_opt;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_hir::intravisit::{Visitor, walk_block, walk_expr, walk_local};
|
||||
use rustc_hir::intravisit::{Visitor, walk_block, walk_expr};
|
||||
use rustc_hir::{Expr, ExprKind, HirId, LetStmt, Node, PatKind, Stmt, StmtKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::hir::nested_filter;
|
||||
|
|
@ -69,8 +69,9 @@ impl<'tcx> LateLintPass<'tcx> for ZombieProcesses {
|
|||
let mut vis = WaitFinder {
|
||||
cx,
|
||||
local_id,
|
||||
create_id: expr.hir_id,
|
||||
body_id: cx.tcx.hir_enclosing_body_owner(expr.hir_id),
|
||||
state: VisitorState::WalkUpToLocal,
|
||||
state: VisitorState::WalkUpToCreate,
|
||||
early_return: None,
|
||||
missing_wait_branch: None,
|
||||
};
|
||||
|
|
@ -131,6 +132,7 @@ struct MaybeWait(Span);
|
|||
struct WaitFinder<'a, 'tcx> {
|
||||
cx: &'a LateContext<'tcx>,
|
||||
local_id: HirId,
|
||||
create_id: HirId,
|
||||
body_id: LocalDefId,
|
||||
state: VisitorState,
|
||||
early_return: Option<Span>,
|
||||
|
|
@ -141,8 +143,8 @@ struct WaitFinder<'a, 'tcx> {
|
|||
|
||||
#[derive(PartialEq)]
|
||||
enum VisitorState {
|
||||
WalkUpToLocal,
|
||||
LocalFound,
|
||||
WalkUpToCreate,
|
||||
CreateFound,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
|
|
@ -155,19 +157,13 @@ impl<'tcx> Visitor<'tcx> for WaitFinder<'_, 'tcx> {
|
|||
type NestedFilter = nested_filter::OnlyBodies;
|
||||
type Result = ControlFlow<MaybeWait>;
|
||||
|
||||
fn visit_local(&mut self, l: &'tcx LetStmt<'tcx>) -> Self::Result {
|
||||
if self.state == VisitorState::WalkUpToLocal
|
||||
&& let PatKind::Binding(_, pat_id, ..) = l.pat.kind
|
||||
&& self.local_id == pat_id
|
||||
{
|
||||
self.state = VisitorState::LocalFound;
|
||||
fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) -> Self::Result {
|
||||
if ex.hir_id == self.create_id {
|
||||
self.state = VisitorState::CreateFound;
|
||||
return Continue(());
|
||||
}
|
||||
|
||||
walk_local(self, l)
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) -> Self::Result {
|
||||
if self.state != VisitorState::LocalFound {
|
||||
if self.state != VisitorState::CreateFound {
|
||||
return walk_expr(self, ex);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -198,3 +198,13 @@ mod issue14677 {
|
|||
child.wait().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn issue14911() -> std::io::Result<String> {
|
||||
let (mut recv, send) = std::io::pipe()?;
|
||||
let mut command = Command::new("ls")
|
||||
.stdout(send.try_clone()?)
|
||||
.spawn()
|
||||
.expect("Could not spawn new process...");
|
||||
command.wait()?;
|
||||
Ok("".into())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue