mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-13 05:38:46 +00:00
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 <yotam.ofek@gmail.com>
This commit is contained in:
commit
5506e0dfaf
1 changed files with 42 additions and 5 deletions
|
@ -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
|
// 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
|
// or "for x in &mut col" and col implements a method called iter_mut
|
||||||
format_to!(buf, "{}.{}()", expr_behind_ref, method);
|
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) {
|
} else if impls_core_iter(&ctx.sema, &iterable) {
|
||||||
format_to!(buf, "{}", iterable);
|
format_to!(buf, "{}", iterable);
|
||||||
|
} else if let ast::Expr::RefExpr(_) = iterable {
|
||||||
|
format_to!(buf, "({}).into_iter()", iterable);
|
||||||
} else {
|
} else {
|
||||||
if let ast::Expr::RefExpr(_) = iterable {
|
format_to!(buf, "{}.into_iter()", iterable);
|
||||||
format_to!(buf, "({}).into_iter()", iterable);
|
|
||||||
} else {
|
|
||||||
format_to!(buf, "{}.into_iter()", iterable);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
format_to!(buf, ".for_each(|{}| {});", pat, body);
|
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<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]
|
#[test]
|
||||||
fn not_available_in_body() {
|
fn not_available_in_body() {
|
||||||
cov_mark::check!(not_available_in_body);
|
cov_mark::check!(not_available_in_body);
|
||||||
|
|
Loading…
Reference in a new issue