Skip to content

Commit 5506e0d

Browse files
bors[bot]yotamofek
andauthored
Merge #10139
10139: Fix replacing for loops over ranges with for_each. r=yotamofek a=yotamofek Previously, the assist would turn this: ```rust for x in 0..92 { ... } ``` into the syntactically incorrect code below: ```rust 0..92.for_each(|x| ...) ``` This fixes the assist by parenthesizing range expressions. Co-authored-by: Yotam Ofek <[email protected]>
2 parents 7234f94 + dd9433c commit 5506e0d

File tree

1 file changed

+42
-5
lines changed

1 file changed

+42
-5
lines changed

crates/ide_assists/src/handlers/replace_for_loop_with_for_each.rs

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,15 @@ pub(crate) fn replace_for_loop_with_for_each(acc: &mut Assists, ctx: &AssistCont
5050
// We have either "for x in &col" and col implements a method called iter
5151
// or "for x in &mut col" and col implements a method called iter_mut
5252
format_to!(buf, "{}.{}()", expr_behind_ref, method);
53+
} else if let ast::Expr::RangeExpr(..) = iterable {
54+
// range expressions need to be parenthesized for the syntax to be correct
55+
format_to!(buf, "({})", iterable);
5356
} else if impls_core_iter(&ctx.sema, &iterable) {
5457
format_to!(buf, "{}", iterable);
58+
} else if let ast::Expr::RefExpr(_) = iterable {
59+
format_to!(buf, "({}).into_iter()", iterable);
5560
} else {
56-
if let ast::Expr::RefExpr(_) = iterable {
57-
format_to!(buf, "({}).into_iter()", iterable);
58-
} else {
59-
format_to!(buf, "{}.into_iter()", iterable);
60-
}
61+
format_to!(buf, "{}.into_iter()", iterable);
6162
}
6263

6364
format_to!(buf, ".for_each(|{}| {});", pat, body);
@@ -167,6 +168,42 @@ fn main() {
167168
)
168169
}
169170

171+
#[test]
172+
fn test_for_in_range() {
173+
check_assist(
174+
replace_for_loop_with_for_each,
175+
r#"
176+
//- minicore: range, iterators
177+
impl<T> core::iter::Iterator for core::ops::Range<T> {
178+
type Item = T;
179+
180+
fn next(&mut self) -> Option<Self::Item> {
181+
None
182+
}
183+
}
184+
185+
fn main() {
186+
for $0x in 0..92 {
187+
print!("{}", x);
188+
}
189+
}"#,
190+
r#"
191+
impl<T> core::iter::Iterator for core::ops::Range<T> {
192+
type Item = T;
193+
194+
fn next(&mut self) -> Option<Self::Item> {
195+
None
196+
}
197+
}
198+
199+
fn main() {
200+
(0..92).for_each(|x| {
201+
print!("{}", x);
202+
});
203+
}"#,
204+
)
205+
}
206+
170207
#[test]
171208
fn not_available_in_body() {
172209
cov_mark::check!(not_available_in_body);

0 commit comments

Comments
 (0)