Skip to content

Commit a2bd02b

Browse files
committed
Auto merge of #12515 - bend-n:🦀, r=llogiq
fix `for x in y unsafe { }` fixes #12514 ---- changelog: [`needless_for_each`]: unsafe block in for loop body suggestion
2 parents 1325425 + a3ef100 commit a2bd02b

File tree

3 files changed

+22
-2
lines changed

3 files changed

+22
-2
lines changed

clippy_lints/src/needless_for_each.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rustc_errors::Applicability;
22
use rustc_hir::intravisit::{walk_expr, Visitor};
3-
use rustc_hir::{Closure, Expr, ExprKind, Stmt, StmtKind};
3+
use rustc_hir::{Block, BlockCheckMode, Closure, Expr, ExprKind, Stmt, StmtKind};
44
use rustc_lint::{LateContext, LateLintPass};
55
use rustc_session::declare_lint_pass;
66
use rustc_span::{sym, Span, Symbol};
@@ -35,6 +35,16 @@ declare_clippy_lint! {
3535
/// println!("{}", elem);
3636
/// }
3737
/// ```
38+
///
39+
/// ### Known Problems
40+
/// When doing things such as:
41+
/// ```ignore
42+
/// let v = vec![0, 1, 2];
43+
/// v.iter().for_each(|elem| unsafe {
44+
/// libc::printf(c"%d\n".as_ptr(), elem);
45+
/// });
46+
/// ```
47+
/// This lint will not trigger.
3848
#[clippy::version = "1.53.0"]
3949
pub NEEDLESS_FOR_EACH,
4050
pedantic,
@@ -68,7 +78,9 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessForEach {
6878
// e.g. `v.iter().for_each(f)` is simpler and clearer than using `for` loop.
6979
&& let ExprKind::Closure(&Closure { body, .. }) = for_each_arg.kind
7080
&& let body = cx.tcx.hir().body(body)
71-
&& let ExprKind::Block(..) = body.value.kind
81+
// Skip the lint if the body is not safe, so as not to suggest `for … in … unsafe {}`
82+
// and suggesting `for … in … { unsafe { } }` is a little ugly.
83+
&& let ExprKind::Block(Block { rules: BlockCheckMode::DefaultBlock, .. }, ..) = body.value.kind
7284
{
7385
let mut ret_collector = RetCollector::default();
7486
ret_collector.visit_expr(body.value);

tests/ui/needless_for_each_fixable.fixed

+4
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ fn should_not_lint() {
113113
let _ = v.iter().for_each(|elem| {
114114
acc += elem;
115115
});
116+
// `for_each` has a closure with an unsafe block.
117+
v.iter().for_each(|elem| unsafe {
118+
acc += elem;
119+
});
116120
}
117121

118122
fn main() {}

tests/ui/needless_for_each_fixable.rs

+4
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ fn should_not_lint() {
113113
let _ = v.iter().for_each(|elem| {
114114
acc += elem;
115115
});
116+
// `for_each` has a closure with an unsafe block.
117+
v.iter().for_each(|elem| unsafe {
118+
acc += elem;
119+
});
116120
}
117121

118122
fn main() {}

0 commit comments

Comments
 (0)