Skip to content

Commit

Permalink
Merge #10139
Browse files Browse the repository at this point in the history
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 <yotam.ofek@gmail.com>
  • Loading branch information
bors[bot] and yotamofek authored Sep 3, 2021
2 parents 7234f94 + dd9433c commit 5506e0d
Showing 1 changed file with 42 additions and 5 deletions.
47 changes: 42 additions & 5 deletions crates/ide_assists/src/handlers/replace_for_loop_with_for_each.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,15 @@ pub(crate) fn replace_for_loop_with_for_each(acc: &mut Assists, ctx: &AssistCont
// We have either "for x in &col" and col implements a method called iter
// or "for x in &mut col" and col implements a method called iter_mut
format_to!(buf, "{}.{}()", expr_behind_ref, method);
} else if let ast::Expr::RangeExpr(..) = iterable {
// range expressions need to be parenthesized for the syntax to be correct
format_to!(buf, "({})", iterable);
} else if impls_core_iter(&ctx.sema, &iterable) {
format_to!(buf, "{}", iterable);
} else if let ast::Expr::RefExpr(_) = iterable {
format_to!(buf, "({}).into_iter()", iterable);
} else {
if let ast::Expr::RefExpr(_) = iterable {
format_to!(buf, "({}).into_iter()", iterable);
} else {
format_to!(buf, "{}.into_iter()", iterable);
}
format_to!(buf, "{}.into_iter()", iterable);
}

format_to!(buf, ".for_each(|{}| {});", pat, body);
Expand Down Expand Up @@ -167,6 +168,42 @@ fn main() {
)
}

#[test]
fn test_for_in_range() {
check_assist(
replace_for_loop_with_for_each,
r#"
//- minicore: range, iterators
impl<T> core::iter::Iterator for core::ops::Range<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
None
}
}
fn main() {
for $0x in 0..92 {
print!("{}", x);
}
}"#,
r#"
impl<T> core::iter::Iterator for core::ops::Range<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
None
}
}
fn main() {
(0..92).for_each(|x| {
print!("{}", x);
});
}"#,
)
}

#[test]
fn not_available_in_body() {
cov_mark::check!(not_available_in_body);
Expand Down

0 comments on commit 5506e0d

Please sign in to comment.