Skip to content

Commit 0bf4d5a

Browse files
authored
fix suggestion causes error of needless_for_each (#15262)
Fixes: #15256 changelog: fix suggestion causes error of [`needless_for_each`] when the `body.value` comes from macro expansion.
2 parents ba8da7a + c20faa0 commit 0bf4d5a

File tree

4 files changed

+32
-9
lines changed

4 files changed

+32
-9
lines changed

clippy_lints/src/needless_for_each.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_session::declare_lint_pass;
66
use rustc_span::Span;
77

88
use clippy_utils::diagnostics::span_lint_and_then;
9-
use clippy_utils::source::snippet_with_applicability;
9+
use clippy_utils::source::{snippet_with_applicability, snippet_with_context};
1010
use clippy_utils::ty::has_iter_method;
1111
use clippy_utils::{is_trait_method, sym};
1212

@@ -101,18 +101,23 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessForEach {
101101

102102
let body_param_sugg = snippet_with_applicability(cx, body.params[0].pat.span, "..", &mut applicability);
103103
let for_each_rev_sugg = snippet_with_applicability(cx, for_each_recv.span, "..", &mut applicability);
104-
let body_value_sugg = snippet_with_applicability(cx, body.value.span, "..", &mut applicability);
104+
let (body_value_sugg, is_macro_call) =
105+
snippet_with_context(cx, body.value.span, for_each_recv.span.ctxt(), "..", &mut applicability);
105106

106107
let sugg = format!(
107108
"for {} in {} {}",
108109
body_param_sugg,
109110
for_each_rev_sugg,
110-
match body.value.kind {
111-
ExprKind::Block(block, _) if is_let_desugar(block) => {
112-
format!("{{ {body_value_sugg} }}")
113-
},
114-
ExprKind::Block(_, _) => body_value_sugg.to_string(),
115-
_ => format!("{{ {body_value_sugg}; }}"),
111+
if is_macro_call {
112+
format!("{{ {body_value_sugg}; }}")
113+
} else {
114+
match body.value.kind {
115+
ExprKind::Block(block, _) if is_let_desugar(block) => {
116+
format!("{{ {body_value_sugg} }}")
117+
},
118+
ExprKind::Block(_, _) => body_value_sugg.to_string(),
119+
_ => format!("{{ {body_value_sugg}; }}"),
120+
}
116121
}
117122
);
118123

tests/ui/needless_for_each_fixable.fixed

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,9 @@ mod issue14734 {
143143
//~^ needless_for_each
144144
}
145145
}
146+
147+
fn issue15256() {
148+
let vec: Vec<i32> = Vec::new();
149+
for v in vec.iter() { println!("{v}"); }
150+
//~^ needless_for_each
151+
}

tests/ui/needless_for_each_fixable.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,9 @@ mod issue14734 {
143143
//~^ needless_for_each
144144
}
145145
}
146+
147+
fn issue15256() {
148+
let vec: Vec<i32> = Vec::new();
149+
vec.iter().for_each(|v| println!("{v}"));
150+
//~^ needless_for_each
151+
}

tests/ui/needless_for_each_fixable.stderr

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,5 +148,11 @@ error: needless use of `for_each`
148148
LL | rows.iter().for_each(|x| do_something(x, 1u8));
149149
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in rows.iter() { do_something(x, 1u8); }`
150150

151-
error: aborting due to 10 previous errors
151+
error: needless use of `for_each`
152+
--> tests/ui/needless_for_each_fixable.rs:149:5
153+
|
154+
LL | vec.iter().for_each(|v| println!("{v}"));
155+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for v in vec.iter() { println!("{v}"); }`
156+
157+
error: aborting due to 11 previous errors
152158

0 commit comments

Comments
 (0)