|
1 | 1 | use rustc_errors::Applicability;
|
2 | 2 | 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}; |
4 | 4 | use rustc_lint::{LateContext, LateLintPass};
|
5 | 5 | use rustc_session::declare_lint_pass;
|
6 | 6 | use rustc_span::{sym, Span, Symbol};
|
@@ -35,6 +35,16 @@ declare_clippy_lint! {
|
35 | 35 | /// println!("{}", elem);
|
36 | 36 | /// }
|
37 | 37 | /// ```
|
| 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. |
38 | 48 | #[clippy::version = "1.53.0"]
|
39 | 49 | pub NEEDLESS_FOR_EACH,
|
40 | 50 | pedantic,
|
@@ -68,7 +78,9 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessForEach {
|
68 | 78 | // e.g. `v.iter().for_each(f)` is simpler and clearer than using `for` loop.
|
69 | 79 | && let ExprKind::Closure(&Closure { body, .. }) = for_each_arg.kind
|
70 | 80 | && 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 |
72 | 84 | {
|
73 | 85 | let mut ret_collector = RetCollector::default();
|
74 | 86 | ret_collector.visit_expr(body.value);
|
|
0 commit comments