Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-assists/src/handlers/convert_for_to_while_let.rs')
-rw-r--r--crates/ide-assists/src/handlers/convert_for_to_while_let.rs73
1 files changed, 66 insertions, 7 deletions
diff --git a/crates/ide-assists/src/handlers/convert_for_to_while_let.rs b/crates/ide-assists/src/handlers/convert_for_to_while_let.rs
index 2d6a59a7c3..d64e9ceda2 100644
--- a/crates/ide-assists/src/handlers/convert_for_to_while_let.rs
+++ b/crates/ide-assists/src/handlers/convert_for_to_while_let.rs
@@ -1,11 +1,8 @@
-use hir::{
- Name,
- sym::{self},
-};
+use hir::{Name, sym};
use ide_db::{famous_defs::FamousDefs, syntax_helpers::suggest_name};
use syntax::{
AstNode,
- ast::{self, HasLoopBody, edit::IndentLevel, make, syntax_factory::SyntaxFactory},
+ ast::{self, HasAttrs, HasLoopBody, edit::IndentLevel, make, syntax_factory::SyntaxFactory},
syntax_editor::Position,
};
@@ -82,6 +79,18 @@ pub(crate) fn convert_for_loop_to_while_let(
Some(iterable),
);
let indent = IndentLevel::from_node(for_loop.syntax());
+
+ if let Some(label) = for_loop.label() {
+ let label = label.syntax().clone_for_update();
+ editor.insert(Position::before(for_loop.syntax()), make.whitespace(" "));
+ editor.insert(Position::before(for_loop.syntax()), label);
+ }
+ crate::utils::insert_attributes(
+ for_loop.syntax(),
+ &mut editor,
+ for_loop.attrs().map(|it| it.clone_for_update()),
+ );
+
editor.insert(
Position::before(for_loop.syntax()),
make::tokens::whitespace(format!("\n{indent}").as_str()),
@@ -129,7 +138,7 @@ fn is_ref_and_impls_iter_method(
let iter_trait = FamousDefs(sema, krate).core_iter_Iterator()?;
let has_wanted_method = ty
- .iterate_method_candidates(sema.db, &scope, None, Some(&wanted_method), |func| {
+ .iterate_method_candidates(sema.db, &scope, Some(&wanted_method), |func| {
if func.ret_type(sema.db).impls_trait(sema.db, iter_trait, &[]) {
return Some(());
}
@@ -150,7 +159,7 @@ fn impls_core_iter(sema: &hir::Semantics<'_, ide_db::RootDatabase>, iterable: &a
let module = sema.scope(iterable.syntax())?.module();
- let krate = module.krate();
+ let krate = module.krate(sema.db);
let iter_trait = FamousDefs(sema, krate).core_iter_Iterator()?;
cov_mark::hit!(test_already_impls_iterator);
Some(it_typ.impls_trait(sema.db, iter_trait, &[]))
@@ -187,6 +196,56 @@ fn main() {
}
#[test]
+ fn each_to_for_with_label() {
+ check_assist(
+ convert_for_loop_to_while_let,
+ r"
+fn main() {
+ let mut x = vec![1, 2, 3];
+ 'a: for $0v in x {
+ v *= 2;
+ break 'a;
+ };
+}",
+ r"
+fn main() {
+ let mut x = vec![1, 2, 3];
+ let mut tmp = x.into_iter();
+ 'a: while let Some(v) = tmp.next() {
+ v *= 2;
+ break 'a;
+ };
+}",
+ )
+ }
+
+ #[test]
+ fn each_to_for_with_attributes() {
+ check_assist(
+ convert_for_loop_to_while_let,
+ r"
+fn main() {
+ let mut x = vec![1, 2, 3];
+ #[allow(unused)]
+ #[deny(unsafe_code)]
+ for $0v in x {
+ v *= 2;
+ };
+}",
+ r"
+fn main() {
+ let mut x = vec![1, 2, 3];
+ let mut tmp = x.into_iter();
+ #[allow(unused)]
+ #[deny(unsafe_code)]
+ while let Some(v) = tmp.next() {
+ v *= 2;
+ };
+}",
+ )
+ }
+
+ #[test]
fn each_to_for_for_in_range() {
check_assist(
convert_for_loop_to_while_let,