From 0d453cc2be9130864bbc8387ad7ba48dcf642a21 Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Fri, 3 Sep 2021 19:43:40 +0300 Subject: [PATCH 1/2] Fix replacing for loops over ranges with for_each. --- .../replace_for_loop_with_for_each.rs | 47 +++++++++++++++++-- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/crates/ide_assists/src/handlers/replace_for_loop_with_for_each.rs b/crates/ide_assists/src/handlers/replace_for_loop_with_for_each.rs index 371223e79d..c5bdbfbbe7 100644 --- a/crates/ide_assists/src/handlers/replace_for_loop_with_for_each.rs +++ b/crates/ide_assists/src/handlers/replace_for_loop_with_for_each.rs @@ -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 matches!(iterable, ast::Expr::RangeExpr(..)) { + // 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); @@ -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 core::iter::Iterator for core::ops::Range { + type Item = T; + + fn next(&mut self) -> Option { + None + } +} + +fn main() { + for $0x in 0..92 { + print!("{}", x); + } +}"#, + r#" +impl core::iter::Iterator for core::ops::Range { + type Item = T; + + fn next(&mut self) -> Option { + None + } +} + +fn main() { + (0..92).for_each(|x| { + print!("{}", x); + }); +}"#, + ) + } + #[test] fn not_available_in_body() { cov_mark::check!(not_available_in_body); From dd9433cc6326b868a07bf7aa9ecb09db244162ad Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Fri, 3 Sep 2021 21:02:48 +0300 Subject: [PATCH 2/2] Update crates/ide_assists/src/handlers/replace_for_loop_with_for_each.rs Co-authored-by: Aleksey Kladov --- .../ide_assists/src/handlers/replace_for_loop_with_for_each.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ide_assists/src/handlers/replace_for_loop_with_for_each.rs b/crates/ide_assists/src/handlers/replace_for_loop_with_for_each.rs index c5bdbfbbe7..fcf7973bd0 100644 --- a/crates/ide_assists/src/handlers/replace_for_loop_with_for_each.rs +++ b/crates/ide_assists/src/handlers/replace_for_loop_with_for_each.rs @@ -50,7 +50,7 @@ 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 matches!(iterable, ast::Expr::RangeExpr(..)) { + } 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) {