Skip to content

Commit 68ee73a

Browse files
committed
fix suggestion causes error of needless_for_each
1 parent 7e2d26f commit 68ee73a

File tree

4 files changed

+47
-8
lines changed

4 files changed

+47
-8
lines changed

clippy_lints/src/needless_for_each.rs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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 =
105+
snippet_with_applicability(cx, get_user_code_span(body.value.span), "..", &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 body.value.span.from_expansion() {
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

@@ -126,6 +131,22 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessForEach {
126131
}
127132
}
128133

134+
/// Get user code span from macro expansion span if it is a macro expansion span
135+
/// or return the original span
136+
fn get_user_code_span(span: Span) -> Span {
137+
if span.from_expansion() {
138+
// Recursively get the original call site
139+
let mut current_span = span;
140+
while current_span.from_expansion() {
141+
let expn_data = current_span.ctxt().outer_expn_data();
142+
current_span = expn_data.call_site;
143+
}
144+
current_span
145+
} else {
146+
span
147+
}
148+
}
149+
129150
/// Check if the block is a desugared `_ = expr` statement.
130151
fn is_let_desugar(block: &Block<'_>) -> bool {
131152
matches!(

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)