Auto merge of #9465 - Alexendoo:peekable-fp, r=flip1995
Fix `unused_peekable` closure and `f(&mut peekable)` false positives changelog: Fix [`unused_peekable`] false positive when peeked in a closure or called as `f(&mut peekable)` The `return`/`break` changes aren't part of the fix, they allow an earlier return in some cases. `break` is replaced with `return` for style purposes as they do the same thing in this case Fixes #9456 Fixes #9462
This commit is contained in:
commit
9c9aa92898
@ -6,6 +6,7 @@
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_hir::{Block, Expr, ExprKind, HirId, Local, Node, PatKind, PathSegment, StmtKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::hir::nested_filter::OnlyBodies;
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::sym;
|
||||
|
||||
@ -109,8 +110,14 @@ fn new(cx: &'a LateContext<'tcx>, expected_hir_id: HirId) -> Self {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Visitor<'_> for PeekableVisitor<'_, 'tcx> {
|
||||
fn visit_expr(&mut self, ex: &'_ Expr<'_>) {
|
||||
impl<'tcx> Visitor<'tcx> for PeekableVisitor<'_, 'tcx> {
|
||||
type NestedFilter = OnlyBodies;
|
||||
|
||||
fn nested_visit_map(&mut self) -> Self::Map {
|
||||
self.cx.tcx.hir()
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
|
||||
if self.found_peek_call {
|
||||
return;
|
||||
}
|
||||
@ -136,12 +143,11 @@ fn visit_expr(&mut self, ex: &'_ Expr<'_>) {
|
||||
return;
|
||||
}
|
||||
|
||||
if args.iter().any(|arg| {
|
||||
matches!(arg.kind, ExprKind::Path(_)) && arg_is_mut_peekable(self.cx, arg)
|
||||
}) {
|
||||
if args.iter().any(|arg| arg_is_mut_peekable(self.cx, arg)) {
|
||||
self.found_peek_call = true;
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
},
|
||||
// Catch anything taking a Peekable mutably
|
||||
ExprKind::MethodCall(
|
||||
@ -190,21 +196,21 @@ fn visit_expr(&mut self, ex: &'_ Expr<'_>) {
|
||||
Node::Local(Local { init: Some(init), .. }) => {
|
||||
if arg_is_mut_peekable(self.cx, init) {
|
||||
self.found_peek_call = true;
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
return;
|
||||
},
|
||||
Node::Stmt(stmt) => match stmt.kind {
|
||||
StmtKind::Expr(_) | StmtKind::Semi(_) => {},
|
||||
_ => {
|
||||
self.found_peek_call = true;
|
||||
return;
|
||||
},
|
||||
Node::Stmt(stmt) => {
|
||||
match stmt.kind {
|
||||
StmtKind::Local(_) | StmtKind::Item(_) => self.found_peek_call = true,
|
||||
StmtKind::Expr(_) | StmtKind::Semi(_) => {},
|
||||
}
|
||||
|
||||
return;
|
||||
},
|
||||
Node::Block(_) | Node::ExprField(_) => {},
|
||||
_ => {
|
||||
break;
|
||||
return;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -57,12 +57,22 @@ fn takes_peekable(_peek: Peekable<Empty<u32>>) {}
|
||||
impl PeekableConsumer {
|
||||
fn consume(&self, _: Peekable<Empty<u32>>) {}
|
||||
fn consume_mut_ref(&self, _: &mut Peekable<Empty<u32>>) {}
|
||||
fn consume_assoc(_: Peekable<Empty<u32>>) {}
|
||||
fn consume_assoc_mut_ref(_: &mut Peekable<Empty<u32>>) {}
|
||||
}
|
||||
|
||||
let peekable_consumer = PeekableConsumer;
|
||||
let mut passed_along_to_method = std::iter::empty::<u32>().peekable();
|
||||
peekable_consumer.consume_mut_ref(&mut passed_along_to_method);
|
||||
peekable_consumer.consume(passed_along_to_method);
|
||||
|
||||
let peekable = std::iter::empty::<u32>().peekable();
|
||||
peekable_consumer.consume(peekable);
|
||||
|
||||
let mut peekable = std::iter::empty::<u32>().peekable();
|
||||
peekable_consumer.consume_mut_ref(&mut peekable);
|
||||
|
||||
let peekable = std::iter::empty::<u32>().peekable();
|
||||
PeekableConsumer::consume_assoc(peekable);
|
||||
|
||||
let mut peekable = std::iter::empty::<u32>().peekable();
|
||||
PeekableConsumer::consume_assoc_mut_ref(&mut peekable);
|
||||
|
||||
// `peek` called in another block
|
||||
let mut peekable_in_block = std::iter::empty::<u32>().peekable();
|
||||
@ -141,4 +151,19 @@ struct PeekableWrapper {
|
||||
{
|
||||
peekable_last_expr.peek();
|
||||
}
|
||||
|
||||
let mut peek_in_closure = std::iter::empty::<u32>().peekable();
|
||||
let _ = || {
|
||||
let _ = peek_in_closure.peek();
|
||||
};
|
||||
|
||||
trait PeekTrait {}
|
||||
impl<I> PeekTrait for Peekable<I> where I: Iterator {}
|
||||
|
||||
let mut peekable = std::iter::empty::<u32>().peekable();
|
||||
let _dyn = &mut peekable as &mut dyn PeekTrait;
|
||||
|
||||
fn takes_dyn(_: &mut dyn PeekTrait) {}
|
||||
let mut peekable = std::iter::empty::<u32>().peekable();
|
||||
takes_dyn(&mut peekable);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user