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.rs | 73 |
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, |