about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-03-06 18:31:30 +0000
committerGitHub <noreply@github.com>2022-03-06 18:31:30 +0000
commit5fae65dd28b450a437ebc800a410164c3af1d516 (patch)
treec5882be14e5996804e84e0105a5d668342a353ec
parentb9538122f25f5f8fb09dd9dfc66de05db21b829b (diff)
parent93b09ca0673dd59f3f7d42d8edf24c48bb75e841 (diff)
downloadrust-5fae65dd28b450a437ebc800a410164c3af1d516.tar.gz
rust-5fae65dd28b450a437ebc800a410164c3af1d516.zip
Merge #11639
11639: internal: Re-arrange ide_db modules r=Veykril a=Veykril

Thins out the `helpers` module by giving some items more appropriate places to live
bors r+

Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
-rw-r--r--crates/hir/src/attrs.rs1
-rw-r--r--crates/ide/src/expand_macro.rs2
-rwxr-xr-xcrates/ide/src/folding_ranges.rs2
-rw-r--r--crates/ide/src/highlight_related.rs5
-rw-r--r--crates/ide/src/hover.rs3
-rw-r--r--crates/ide/src/hover/render.rs6
-rw-r--r--crates/ide/src/inlay_hints.rs2
-rw-r--r--crates/ide/src/join_lines.rs2
-rw-r--r--crates/ide/src/syntax_highlighting/format.rs2
-rw-r--r--crates/ide/src/syntax_highlighting/highlight.rs2
-rw-r--r--crates/ide/src/syntax_highlighting/inject.rs3
-rw-r--r--crates/ide_assists/src/assist_config.rs2
-rw-r--r--crates/ide_assists/src/assist_context.rs2
-rw-r--r--crates/ide_assists/src/handlers/add_explicit_type.rs2
-rw-r--r--crates/ide_assists/src/handlers/add_missing_impl_members.rs4
-rw-r--r--crates/ide_assists/src/handlers/add_missing_match_arms.rs2
-rw-r--r--crates/ide_assists/src/handlers/auto_import.rs10
-rw-r--r--crates/ide_assists/src/handlers/convert_bool_then.rs7
-rw-r--r--crates/ide_assists/src/handlers/convert_into_to_from.rs5
-rw-r--r--crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs2
-rw-r--r--crates/ide_assists/src/handlers/convert_to_guarded_return.rs2
-rw-r--r--crates/ide_assists/src/handlers/convert_while_to_loop.rs2
-rw-r--r--crates/ide_assists/src/handlers/extract_function.rs10
-rw-r--r--crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs6
-rw-r--r--crates/ide_assists/src/handlers/extract_type_alias.rs2
-rw-r--r--crates/ide_assists/src/handlers/generate_default_from_enum_variant.rs2
-rw-r--r--crates/ide_assists/src/handlers/generate_default_from_new.rs2
-rw-r--r--crates/ide_assists/src/handlers/generate_deref.rs2
-rw-r--r--crates/ide_assists/src/handlers/generate_from_impl_for_enum.rs3
-rw-r--r--crates/ide_assists/src/handlers/generate_function.rs5
-rw-r--r--crates/ide_assists/src/handlers/generate_getter.rs2
-rw-r--r--crates/ide_assists/src/handlers/inline_call.rs3
-rw-r--r--crates/ide_assists/src/handlers/invert_if.rs2
-rw-r--r--crates/ide_assists/src/handlers/merge_imports.rs2
-rw-r--r--crates/ide_assists/src/handlers/promote_local_to_const.rs2
-rw-r--r--crates/ide_assists/src/handlers/qualify_method_call.rs2
-rw-r--r--crates/ide_assists/src/handlers/qualify_path.rs8
-rw-r--r--crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs6
-rw-r--r--crates/ide_assists/src/handlers/replace_if_let_with_match.rs2
-rw-r--r--crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs6
-rw-r--r--crates/ide_assists/src/handlers/unwrap_result_return_type.rs5
-rw-r--r--crates/ide_assists/src/handlers/wrap_return_type_in_result.rs5
-rw-r--r--crates/ide_assists/src/tests.rs7
-rw-r--r--crates/ide_assists/src/utils.rs4
-rw-r--r--crates/ide_completion/src/completions/attribute.rs8
-rw-r--r--crates/ide_completion/src/completions/attribute/derive.rs2
-rw-r--r--crates/ide_completion/src/completions/attribute/lint.rs2
-rw-r--r--crates/ide_completion/src/completions/flyimport.rs2
-rw-r--r--crates/ide_completion/src/completions/format_string.rs2
-rw-r--r--crates/ide_completion/src/completions/postfix.rs5
-rw-r--r--crates/ide_completion/src/completions/postfix/format_like.rs2
-rw-r--r--crates/ide_completion/src/completions/snippet.rs2
-rw-r--r--crates/ide_completion/src/config.rs2
-rw-r--r--crates/ide_completion/src/context.rs2
-rw-r--r--crates/ide_completion/src/item.rs6
-rw-r--r--crates/ide_completion/src/lib.rs4
-rw-r--r--crates/ide_completion/src/render.rs5
-rw-r--r--crates/ide_completion/src/render/pattern.rs2
-rw-r--r--crates/ide_completion/src/render/struct_literal.rs2
-rw-r--r--crates/ide_completion/src/snippet.rs2
-rw-r--r--crates/ide_completion/src/tests.rs7
-rw-r--r--crates/ide_db/src/famous_defs.rs (renamed from crates/ide_db/src/helpers/famous_defs.rs)0
-rw-r--r--crates/ide_db/src/generated/lints.rs (renamed from crates/ide_db/src/helpers/generated_lints.rs)0
-rw-r--r--crates/ide_db/src/helpers.rs254
-rw-r--r--crates/ide_db/src/imports/import_assets.rs (renamed from crates/ide_db/src/helpers/import_assets.rs)3
-rw-r--r--crates/ide_db/src/imports/insert_use.rs (renamed from crates/ide_db/src/helpers/insert_use.rs)2
-rw-r--r--crates/ide_db/src/imports/insert_use/tests.rs (renamed from crates/ide_db/src/helpers/insert_use/tests.rs)0
-rw-r--r--crates/ide_db/src/imports/merge_imports.rs (renamed from crates/ide_db/src/helpers/merge_imports.rs)2
-rw-r--r--crates/ide_db/src/items_locator.rs2
-rw-r--r--crates/ide_db/src/lib.rs66
-rw-r--r--crates/ide_db/src/line_index.rs144
-rw-r--r--crates/ide_db/src/line_index/tests.rs133
-rw-r--r--crates/ide_db/src/rename.rs4
-rw-r--r--crates/ide_db/src/rust_doc.rs (renamed from crates/ide_db/src/helpers/rust_doc.rs)0
-rw-r--r--crates/ide_db/src/syntax_helpers/format_string.rs (renamed from crates/ide_db/src/helpers/format_string.rs)0
-rw-r--r--crates/ide_db/src/syntax_helpers/insert_whitespace_into_node.rs (renamed from crates/ide_db/src/helpers/insert_whitespace_into_node.rs)0
-rw-r--r--crates/ide_db/src/syntax_helpers/node_ext.rs (renamed from crates/ide_db/src/helpers/node_ext.rs)218
-rw-r--r--crates/ide_db/src/tests/sourcegen_lints.rs2
-rw-r--r--crates/ide_db/src/traits.rs145
-rw-r--r--crates/ide_db/src/traits/tests.rs141
-rw-r--r--crates/ide_diagnostics/src/handlers/missing_fields.rs2
-rw-r--r--crates/ide_diagnostics/src/handlers/missing_ok_or_some_in_tail_expr.rs4
-rw-r--r--crates/rust-analyzer/src/config.rs4
-rw-r--r--crates/rust-analyzer/src/integrated_benchmarks.rs4
-rw-r--r--crates/rust-analyzer/src/markdown.rs2
-rw-r--r--crates/rust-analyzer/tests/slow-tests/tidy.rs6
86 files changed, 670 insertions, 683 deletions
diff --git a/crates/hir/src/attrs.rs b/crates/hir/src/attrs.rs
index 7e83819a4f5..59603c61123 100644
--- a/crates/hir/src/attrs.rs
+++ b/crates/hir/src/attrs.rs
@@ -149,6 +149,7 @@ fn resolve_doc_path(
     };
 
     let modpath = {
+        // FIXME: this is not how we should get a mod path here
         let ast_path = ast::SourceFile::parse(&format!("type T = {};", link))
             .syntax_node()
             .descendants()
diff --git a/crates/ide/src/expand_macro.rs b/crates/ide/src/expand_macro.rs
index 7bb6b24a23d..14464426bfc 100644
--- a/crates/ide/src/expand_macro.rs
+++ b/crates/ide/src/expand_macro.rs
@@ -1,6 +1,6 @@
 use hir::Semantics;
 use ide_db::{
-    helpers::{insert_whitespace_into_node::insert_ws_into, pick_best_token},
+    helpers::pick_best_token, syntax_helpers::insert_whitespace_into_node::insert_ws_into,
     RootDatabase,
 };
 use syntax::{ast, ted, AstNode, NodeOrToken, SyntaxKind, SyntaxNode, T};
diff --git a/crates/ide/src/folding_ranges.rs b/crates/ide/src/folding_ranges.rs
index 66126c8d551..ba999524d63 100755
--- a/crates/ide/src/folding_ranges.rs
+++ b/crates/ide/src/folding_ranges.rs
@@ -1,4 +1,4 @@
-use ide_db::helpers::node_ext::vis_eq;
+use ide_db::syntax_helpers::node_ext::vis_eq;
 use rustc_hash::FxHashSet;
 
 use syntax::{
diff --git a/crates/ide/src/highlight_related.rs b/crates/ide/src/highlight_related.rs
index 5724090e636..baa015354f8 100644
--- a/crates/ide/src/highlight_related.rs
+++ b/crates/ide/src/highlight_related.rs
@@ -2,10 +2,9 @@ use hir::Semantics;
 use ide_db::{
     base_db::{FileId, FilePosition},
     defs::{Definition, IdentClass},
-    helpers::{
-        for_each_break_and_continue_expr, for_each_tail_expr, node_ext::walk_expr, pick_best_token,
-    },
+    helpers::pick_best_token,
     search::{FileReference, ReferenceCategory, SearchScope},
+    syntax_helpers::node_ext::{for_each_break_and_continue_expr, for_each_tail_expr, walk_expr},
     RootDatabase,
 };
 use rustc_hash::FxHashSet;
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index 30d0d343581..4a762ad1f85 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -10,7 +10,8 @@ use hir::{HasSource, Semantics};
 use ide_db::{
     base_db::FileRange,
     defs::{Definition, IdentClass},
-    helpers::{pick_best_token, FamousDefs},
+    famous_defs::FamousDefs,
+    helpers::pick_best_token,
     FxIndexSet, RootDatabase,
 };
 use itertools::Itertools;
diff --git a/crates/ide/src/hover/render.rs b/crates/ide/src/hover/render.rs
index f8ac43bbddb..c298065f4e0 100644
--- a/crates/ide/src/hover/render.rs
+++ b/crates/ide/src/hover/render.rs
@@ -6,10 +6,8 @@ use hir::{AsAssocItem, AttributeTemplate, HasAttrs, HasSource, HirDisplay, Seman
 use ide_db::{
     base_db::SourceDatabase,
     defs::Definition,
-    helpers::{
-        generated_lints::{CLIPPY_LINTS, DEFAULT_LINTS, FEATURES},
-        FamousDefs,
-    },
+    famous_defs::FamousDefs,
+    generated::lints::{CLIPPY_LINTS, DEFAULT_LINTS, FEATURES},
     RootDatabase,
 };
 use itertools::Itertools;
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs
index 2ca756cbe04..f77cae3e3cc 100644
--- a/crates/ide/src/inlay_hints.rs
+++ b/crates/ide/src/inlay_hints.rs
@@ -1,6 +1,6 @@
 use either::Either;
 use hir::{known, Callable, HasVisibility, HirDisplay, Semantics, TypeInfo};
-use ide_db::{base_db::FileRange, helpers::FamousDefs, RootDatabase};
+use ide_db::{base_db::FileRange, famous_defs::FamousDefs, RootDatabase};
 use itertools::Itertools;
 use stdx::to_lower_snake_case;
 use syntax::{
diff --git a/crates/ide/src/join_lines.rs b/crates/ide/src/join_lines.rs
index 54c0b5e7046..00ff9ed31b8 100644
--- a/crates/ide/src/join_lines.rs
+++ b/crates/ide/src/join_lines.rs
@@ -1,5 +1,5 @@
 use ide_assists::utils::extract_trivial_expression;
-use ide_db::helpers::node_ext::expr_as_name_ref;
+use ide_db::syntax_helpers::node_ext::expr_as_name_ref;
 use itertools::Itertools;
 use syntax::{
     ast::{self, AstNode, AstToken, IsString},
diff --git a/crates/ide/src/syntax_highlighting/format.rs b/crates/ide/src/syntax_highlighting/format.rs
index c74b9f56db6..2d5f5f00e16 100644
--- a/crates/ide/src/syntax_highlighting/format.rs
+++ b/crates/ide/src/syntax_highlighting/format.rs
@@ -1,6 +1,6 @@
 //! Syntax highlighting for format macro strings.
 use ide_db::{
-    helpers::format_string::{is_format_string, lex_format_specifiers, FormatSpecifier},
+    syntax_helpers::format_string::{is_format_string, lex_format_specifiers, FormatSpecifier},
     SymbolKind,
 };
 use syntax::{ast, TextRange};
diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs
index b98fa1ab392..a5b4ef50298 100644
--- a/crates/ide/src/syntax_highlighting/highlight.rs
+++ b/crates/ide/src/syntax_highlighting/highlight.rs
@@ -3,7 +3,7 @@
 use hir::{AsAssocItem, HasVisibility, Semantics};
 use ide_db::{
     defs::{Definition, IdentClass, NameClass, NameRefClass},
-    helpers::FamousDefs,
+    famous_defs::FamousDefs,
     RootDatabase, SymbolKind,
 };
 use rustc_hash::FxHashMap;
diff --git a/crates/ide/src/syntax_highlighting/inject.rs b/crates/ide/src/syntax_highlighting/inject.rs
index 774934a2498..7ac1200a4a3 100644
--- a/crates/ide/src/syntax_highlighting/inject.rs
+++ b/crates/ide/src/syntax_highlighting/inject.rs
@@ -5,8 +5,7 @@ use std::mem;
 use either::Either;
 use hir::{InFile, Semantics};
 use ide_db::{
-    active_parameter::ActiveParameter, defs::Definition, helpers::rust_doc::is_rust_fence,
-    SymbolKind,
+    active_parameter::ActiveParameter, defs::Definition, rust_doc::is_rust_fence, SymbolKind,
 };
 use syntax::{
     ast::{self, AstNode, IsString, QuoteOffsets},
diff --git a/crates/ide_assists/src/assist_config.rs b/crates/ide_assists/src/assist_config.rs
index 9cabf037c0e..d4d148c7745 100644
--- a/crates/ide_assists/src/assist_config.rs
+++ b/crates/ide_assists/src/assist_config.rs
@@ -4,7 +4,7 @@
 //! module, and we use to statically check that we only produce snippet
 //! assists if we are allowed to.
 
-use ide_db::helpers::{insert_use::InsertUseConfig, SnippetCap};
+use ide_db::{imports::insert_use::InsertUseConfig, SnippetCap};
 
 use crate::AssistKind;
 
diff --git a/crates/ide_assists/src/assist_context.rs b/crates/ide_assists/src/assist_context.rs
index 1181adb8d54..fd46aa24796 100644
--- a/crates/ide_assists/src/assist_context.rs
+++ b/crates/ide_assists/src/assist_context.rs
@@ -5,7 +5,7 @@ use std::mem;
 use hir::Semantics;
 use ide_db::{
     base_db::{AnchoredPathBuf, FileId, FileRange},
-    helpers::SnippetCap,
+    SnippetCap,
 };
 use ide_db::{
     label::Label,
diff --git a/crates/ide_assists/src/handlers/add_explicit_type.rs b/crates/ide_assists/src/handlers/add_explicit_type.rs
index 945edfd999b..11f12773e8e 100644
--- a/crates/ide_assists/src/handlers/add_explicit_type.rs
+++ b/crates/ide_assists/src/handlers/add_explicit_type.rs
@@ -1,5 +1,5 @@
 use hir::HirDisplay;
-use ide_db::helpers::node_ext::walk_ty;
+use ide_db::syntax_helpers::node_ext::walk_ty;
 use syntax::ast::{self, AstNode, LetStmt, Param};
 
 use crate::{AssistContext, AssistId, AssistKind, Assists};
diff --git a/crates/ide_assists/src/handlers/add_missing_impl_members.rs b/crates/ide_assists/src/handlers/add_missing_impl_members.rs
index 3105b289116..c82caa37043 100644
--- a/crates/ide_assists/src/handlers/add_missing_impl_members.rs
+++ b/crates/ide_assists/src/handlers/add_missing_impl_members.rs
@@ -1,5 +1,7 @@
 use hir::HasSource;
-use ide_db::{helpers::insert_whitespace_into_node::insert_ws_into, traits::resolve_target_trait};
+use ide_db::{
+    syntax_helpers::insert_whitespace_into_node::insert_ws_into, traits::resolve_target_trait,
+};
 use syntax::ast::{self, make, AstNode};
 
 use crate::{
diff --git a/crates/ide_assists/src/handlers/add_missing_match_arms.rs b/crates/ide_assists/src/handlers/add_missing_match_arms.rs
index ec8fbb49745..9b6a1ad169f 100644
--- a/crates/ide_assists/src/handlers/add_missing_match_arms.rs
+++ b/crates/ide_assists/src/handlers/add_missing_match_arms.rs
@@ -2,8 +2,8 @@ use std::iter::{self, Peekable};
 
 use either::Either;
 use hir::{Adt, Crate, HasAttrs, HasSource, ModuleDef, Semantics};
-use ide_db::helpers::{mod_path_to_ast, FamousDefs};
 use ide_db::RootDatabase;
+use ide_db::{famous_defs::FamousDefs, helpers::mod_path_to_ast};
 use itertools::Itertools;
 use syntax::ast::{self, make, AstNode, HasName, MatchArmList, MatchExpr, Pat};
 
diff --git a/crates/ide_assists/src/handlers/auto_import.rs b/crates/ide_assists/src/handlers/auto_import.rs
index 9c0233b028f..5a2809a1cf1 100644
--- a/crates/ide_assists/src/handlers/auto_import.rs
+++ b/crates/ide_assists/src/handlers/auto_import.rs
@@ -1,7 +1,9 @@
-use ide_db::helpers::{
-    import_assets::{ImportAssets, ImportCandidate},
-    insert_use::{insert_use, ImportScope},
-    mod_path_to_ast,
+use ide_db::{
+    helpers::mod_path_to_ast,
+    imports::{
+        import_assets::{ImportAssets, ImportCandidate},
+        insert_use::{insert_use, ImportScope},
+    },
 };
 use syntax::{ast, AstNode, NodeOrToken, SyntaxElement};
 
diff --git a/crates/ide_assists/src/handlers/convert_bool_then.rs b/crates/ide_assists/src/handlers/convert_bool_then.rs
index 274718e6ea9..daec28999ea 100644
--- a/crates/ide_assists/src/handlers/convert_bool_then.rs
+++ b/crates/ide_assists/src/handlers/convert_bool_then.rs
@@ -1,9 +1,8 @@
 use hir::{known, AsAssocItem, Semantics};
 use ide_db::{
-    helpers::{
-        for_each_tail_expr,
-        node_ext::{block_as_lone_tail, is_pattern_cond, preorder_expr},
-        FamousDefs,
+    famous_defs::FamousDefs,
+    syntax_helpers::node_ext::{
+        block_as_lone_tail, for_each_tail_expr, is_pattern_cond, preorder_expr,
     },
     RootDatabase,
 };
diff --git a/crates/ide_assists/src/handlers/convert_into_to_from.rs b/crates/ide_assists/src/handlers/convert_into_to_from.rs
index 7f27b507bab..9185501a629 100644
--- a/crates/ide_assists/src/handlers/convert_into_to_from.rs
+++ b/crates/ide_assists/src/handlers/convert_into_to_from.rs
@@ -1,7 +1,4 @@
-use ide_db::{
-    helpers::{mod_path_to_ast, FamousDefs},
-    traits::resolve_target_trait,
-};
+use ide_db::{famous_defs::FamousDefs, helpers::mod_path_to_ast, traits::resolve_target_trait};
 use syntax::ast::{self, AstNode, HasName};
 
 use crate::{AssistContext, AssistId, AssistKind, Assists};
diff --git a/crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs b/crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs
index 4a4ad984db1..bb75cb5c955 100644
--- a/crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs
+++ b/crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs
@@ -1,5 +1,5 @@
 use hir::known;
-use ide_db::helpers::FamousDefs;
+use ide_db::famous_defs::FamousDefs;
 use stdx::format_to;
 use syntax::{
     ast::{self, edit_in_place::Indent, make, HasArgList, HasLoopBody},
diff --git a/crates/ide_assists/src/handlers/convert_to_guarded_return.rs b/crates/ide_assists/src/handlers/convert_to_guarded_return.rs
index 193d1cdfb24..a7c43413d2c 100644
--- a/crates/ide_assists/src/handlers/convert_to_guarded_return.rs
+++ b/crates/ide_assists/src/handlers/convert_to_guarded_return.rs
@@ -1,6 +1,6 @@
 use std::iter::once;
 
-use ide_db::helpers::node_ext::{is_pattern_cond, single_let};
+use ide_db::syntax_helpers::node_ext::{is_pattern_cond, single_let};
 use syntax::{
     ast::{
         self,
diff --git a/crates/ide_assists/src/handlers/convert_while_to_loop.rs b/crates/ide_assists/src/handlers/convert_while_to_loop.rs
index 0fa2dcfbde1..345d0c2063f 100644
--- a/crates/ide_assists/src/handlers/convert_while_to_loop.rs
+++ b/crates/ide_assists/src/handlers/convert_while_to_loop.rs
@@ -1,6 +1,6 @@
 use std::iter::once;
 
-use ide_db::helpers::node_ext::is_pattern_cond;
+use ide_db::syntax_helpers::node_ext::is_pattern_cond;
 use syntax::{
     ast::{
         self,
diff --git a/crates/ide_assists/src/handlers/extract_function.rs b/crates/ide_assists/src/handlers/extract_function.rs
index e80dce0c455..5f86957ba2e 100644
--- a/crates/ide_assists/src/handlers/extract_function.rs
+++ b/crates/ide_assists/src/handlers/extract_function.rs
@@ -5,13 +5,11 @@ use either::Either;
 use hir::{HirDisplay, InFile, Local, ModuleDef, Semantics, TypeInfo};
 use ide_db::{
     defs::{Definition, NameRefClass},
-    helpers::{
-        insert_use::{insert_use, ImportScope},
-        mod_path_to_ast,
-        node_ext::{preorder_expr, walk_expr, walk_pat, walk_patterns_in_expr},
-        FamousDefs,
-    },
+    famous_defs::FamousDefs,
+    helpers::mod_path_to_ast,
+    imports::insert_use::{insert_use, ImportScope},
     search::{FileReference, ReferenceCategory, SearchScope},
+    syntax_helpers::node_ext::{preorder_expr, walk_expr, walk_pat, walk_patterns_in_expr},
     FxIndexSet, RootDatabase,
 };
 use itertools::Itertools;
diff --git a/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs b/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs
index 1cdd4187af4..4b597837aaf 100644
--- a/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs
+++ b/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs
@@ -4,10 +4,8 @@ use either::Either;
 use hir::{Module, ModuleDef, Name, Variant};
 use ide_db::{
     defs::Definition,
-    helpers::{
-        insert_use::{insert_use, ImportScope, InsertUseConfig},
-        mod_path_to_ast,
-    },
+    helpers::mod_path_to_ast,
+    imports::insert_use::{insert_use, ImportScope, InsertUseConfig},
     search::FileReference,
     RootDatabase,
 };
diff --git a/crates/ide_assists/src/handlers/extract_type_alias.rs b/crates/ide_assists/src/handlers/extract_type_alias.rs
index d7ad62782f8..f664aa6dbf9 100644
--- a/crates/ide_assists/src/handlers/extract_type_alias.rs
+++ b/crates/ide_assists/src/handlers/extract_type_alias.rs
@@ -1,5 +1,5 @@
 use either::Either;
-use ide_db::helpers::node_ext::walk_ty;
+use ide_db::syntax_helpers::node_ext::walk_ty;
 use itertools::Itertools;
 use syntax::{
     ast::{self, edit::IndentLevel, AstNode, HasGenericParams, HasName},
diff --git a/crates/ide_assists/src/handlers/generate_default_from_enum_variant.rs b/crates/ide_assists/src/handlers/generate_default_from_enum_variant.rs
index e67789a662d..4745ac24e9f 100644
--- a/crates/ide_assists/src/handlers/generate_default_from_enum_variant.rs
+++ b/crates/ide_assists/src/handlers/generate_default_from_enum_variant.rs
@@ -1,4 +1,4 @@
-use ide_db::{helpers::FamousDefs, RootDatabase};
+use ide_db::{famous_defs::FamousDefs, RootDatabase};
 use syntax::ast::{self, AstNode, HasName};
 
 use crate::{AssistContext, AssistId, AssistKind, Assists};
diff --git a/crates/ide_assists/src/handlers/generate_default_from_new.rs b/crates/ide_assists/src/handlers/generate_default_from_new.rs
index 6f158ceb993..669fb28d101 100644
--- a/crates/ide_assists/src/handlers/generate_default_from_new.rs
+++ b/crates/ide_assists/src/handlers/generate_default_from_new.rs
@@ -1,4 +1,4 @@
-use ide_db::helpers::FamousDefs;
+use ide_db::famous_defs::FamousDefs;
 use itertools::Itertools;
 use stdx::format_to;
 use syntax::{
diff --git a/crates/ide_assists/src/handlers/generate_deref.rs b/crates/ide_assists/src/handlers/generate_deref.rs
index 2208c23c15e..4328c54c098 100644
--- a/crates/ide_assists/src/handlers/generate_deref.rs
+++ b/crates/ide_assists/src/handlers/generate_deref.rs
@@ -1,6 +1,6 @@
 use std::fmt::Display;
 
-use ide_db::{helpers::FamousDefs, RootDatabase};
+use ide_db::{famous_defs::FamousDefs, RootDatabase};
 use syntax::{
     ast::{self, HasName},
     AstNode, SyntaxNode,
diff --git a/crates/ide_assists/src/handlers/generate_from_impl_for_enum.rs b/crates/ide_assists/src/handlers/generate_from_impl_for_enum.rs
index 96b751f0996..ee8de5a20e5 100644
--- a/crates/ide_assists/src/handlers/generate_from_impl_for_enum.rs
+++ b/crates/ide_assists/src/handlers/generate_from_impl_for_enum.rs
@@ -1,5 +1,4 @@
-use ide_db::helpers::FamousDefs;
-use ide_db::RootDatabase;
+use ide_db::{famous_defs::FamousDefs, RootDatabase};
 use syntax::ast::{self, AstNode, HasName};
 
 use crate::{utils::generate_trait_impl_text, AssistContext, AssistId, AssistKind, Assists};
diff --git a/crates/ide_assists/src/handlers/generate_function.rs b/crates/ide_assists/src/handlers/generate_function.rs
index ac33d56858c..c06498a4c96 100644
--- a/crates/ide_assists/src/handlers/generate_function.rs
+++ b/crates/ide_assists/src/handlers/generate_function.rs
@@ -1,12 +1,11 @@
 use rustc_hash::{FxHashMap, FxHashSet};
 
 use hir::{HasSource, HirDisplay, Module, Semantics, TypeInfo};
-use ide_db::helpers::FamousDefs;
 use ide_db::{
     base_db::FileId,
     defs::{Definition, NameRefClass},
-    helpers::SnippetCap,
-    RootDatabase,
+    famous_defs::FamousDefs,
+    RootDatabase, SnippetCap,
 };
 use stdx::to_lower_snake_case;
 use syntax::{
diff --git a/crates/ide_assists/src/handlers/generate_getter.rs b/crates/ide_assists/src/handlers/generate_getter.rs
index 653e448cbb0..c6e979c072c 100644
--- a/crates/ide_assists/src/handlers/generate_getter.rs
+++ b/crates/ide_assists/src/handlers/generate_getter.rs
@@ -1,4 +1,4 @@
-use ide_db::helpers::FamousDefs;
+use ide_db::famous_defs::FamousDefs;
 use stdx::{format_to, to_lower_snake_case};
 use syntax::ast::{self, AstNode, HasName, HasVisibility};
 
diff --git a/crates/ide_assists/src/handlers/inline_call.rs b/crates/ide_assists/src/handlers/inline_call.rs
index d88e3fdcd32..5e9f5618061 100644
--- a/crates/ide_assists/src/handlers/inline_call.rs
+++ b/crates/ide_assists/src/handlers/inline_call.rs
@@ -4,9 +4,10 @@ use hir::{db::HirDatabase, PathResolution, Semantics, TypeInfo};
 use ide_db::{
     base_db::{FileId, FileRange},
     defs::Definition,
-    helpers::{insert_use::remove_path_if_in_use_stmt, node_ext::expr_as_name_ref},
+    imports::insert_use::remove_path_if_in_use_stmt,
     path_transform::PathTransform,
     search::{FileReference, SearchScope},
+    syntax_helpers::node_ext::expr_as_name_ref,
     RootDatabase,
 };
 use itertools::{izip, Itertools};
diff --git a/crates/ide_assists/src/handlers/invert_if.rs b/crates/ide_assists/src/handlers/invert_if.rs
index 46f11f4af32..6eed59c9ea4 100644
--- a/crates/ide_assists/src/handlers/invert_if.rs
+++ b/crates/ide_assists/src/handlers/invert_if.rs
@@ -1,4 +1,4 @@
-use ide_db::helpers::node_ext::is_pattern_cond;
+use ide_db::syntax_helpers::node_ext::is_pattern_cond;
 use syntax::{
     ast::{self, AstNode},
     T,
diff --git a/crates/ide_assists/src/handlers/merge_imports.rs b/crates/ide_assists/src/handlers/merge_imports.rs
index 68aa741face..e35c962a3f3 100644
--- a/crates/ide_assists/src/handlers/merge_imports.rs
+++ b/crates/ide_assists/src/handlers/merge_imports.rs
@@ -1,4 +1,4 @@
-use ide_db::helpers::merge_imports::{try_merge_imports, try_merge_trees, MergeBehavior};
+use ide_db::imports::merge_imports::{try_merge_imports, try_merge_trees, MergeBehavior};
 use syntax::{algo::neighbor, ast, ted, AstNode};
 
 use crate::{
diff --git a/crates/ide_assists/src/handlers/promote_local_to_const.rs b/crates/ide_assists/src/handlers/promote_local_to_const.rs
index 879247d37ee..58cee8eafbf 100644
--- a/crates/ide_assists/src/handlers/promote_local_to_const.rs
+++ b/crates/ide_assists/src/handlers/promote_local_to_const.rs
@@ -2,7 +2,7 @@ use hir::{HirDisplay, ModuleDef, PathResolution, Semantics};
 use ide_db::{
     assists::{AssistId, AssistKind},
     defs::Definition,
-    helpers::node_ext::preorder_expr,
+    syntax_helpers::node_ext::preorder_expr,
     RootDatabase,
 };
 use stdx::to_upper_snake_case;
diff --git a/crates/ide_assists/src/handlers/qualify_method_call.rs b/crates/ide_assists/src/handlers/qualify_method_call.rs
index 43878879edf..61c16aa0445 100644
--- a/crates/ide_assists/src/handlers/qualify_method_call.rs
+++ b/crates/ide_assists/src/handlers/qualify_method_call.rs
@@ -1,7 +1,7 @@
 use hir::{ItemInNs, ModuleDef};
 use ide_db::{
     assists::{AssistId, AssistKind},
-    helpers::import_assets::item_for_path_search,
+    imports::import_assets::item_for_path_search,
 };
 use syntax::{ast, AstNode};
 
diff --git a/crates/ide_assists/src/handlers/qualify_path.rs b/crates/ide_assists/src/handlers/qualify_path.rs
index ae29068bd70..5deb60f57b1 100644
--- a/crates/ide_assists/src/handlers/qualify_path.rs
+++ b/crates/ide_assists/src/handlers/qualify_path.rs
@@ -1,11 +1,11 @@
 use std::iter;
 
 use hir::AsAssocItem;
-use ide_db::helpers::{
-    import_assets::{ImportCandidate, LocatedImport},
-    mod_path_to_ast,
-};
 use ide_db::RootDatabase;
+use ide_db::{
+    helpers::mod_path_to_ast,
+    imports::import_assets::{ImportCandidate, LocatedImport},
+};
 use syntax::{
     ast,
     ast::{make, HasArgList},
diff --git a/crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs b/crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs
index 27f2960c7ed..0d0bd7071f4 100644
--- a/crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs
+++ b/crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs
@@ -1,9 +1,7 @@
 use hir::{InFile, ModuleDef};
 use ide_db::{
-    helpers::{
-        import_assets::NameToImport, insert_whitespace_into_node::insert_ws_into, mod_path_to_ast,
-    },
-    items_locator,
+    helpers::mod_path_to_ast, imports::import_assets::NameToImport, items_locator,
+    syntax_helpers::insert_whitespace_into_node::insert_ws_into,
 };
 use itertools::Itertools;
 use syntax::{
diff --git a/crates/ide_assists/src/handlers/replace_if_let_with_match.rs b/crates/ide_assists/src/handlers/replace_if_let_with_match.rs
index b594c64c412..1c403eafe30 100644
--- a/crates/ide_assists/src/handlers/replace_if_let_with_match.rs
+++ b/crates/ide_assists/src/handlers/replace_if_let_with_match.rs
@@ -3,7 +3,7 @@ use std::iter::{self, successors};
 use either::Either;
 use ide_db::{
     defs::NameClass,
-    helpers::node_ext::{is_pattern_cond, single_let},
+    syntax_helpers::node_ext::{is_pattern_cond, single_let},
     ty_filter::TryEnum,
     RootDatabase,
 };
diff --git a/crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs b/crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs
index 71c674a8dd7..50134db8a1c 100644
--- a/crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs
+++ b/crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs
@@ -1,7 +1,7 @@
 use hir::AsAssocItem;
-use ide_db::helpers::{
-    insert_use::{insert_use, ImportScope},
-    mod_path_to_ast,
+use ide_db::{
+    helpers::mod_path_to_ast,
+    imports::insert_use::{insert_use, ImportScope},
 };
 use syntax::{
     ast::{self, make},
diff --git a/crates/ide_assists/src/handlers/unwrap_result_return_type.rs b/crates/ide_assists/src/handlers/unwrap_result_return_type.rs
index 82499d77c3e..b890462389f 100644
--- a/crates/ide_assists/src/handlers/unwrap_result_return_type.rs
+++ b/crates/ide_assists/src/handlers/unwrap_result_return_type.rs
@@ -1,4 +1,7 @@
-use ide_db::helpers::{for_each_tail_expr, node_ext::walk_expr, FamousDefs};
+use ide_db::{
+    famous_defs::FamousDefs,
+    syntax_helpers::node_ext::{for_each_tail_expr, walk_expr},
+};
 use itertools::Itertools;
 use syntax::{
     ast::{self, Expr},
diff --git a/crates/ide_assists/src/handlers/wrap_return_type_in_result.rs b/crates/ide_assists/src/handlers/wrap_return_type_in_result.rs
index c510a5f9654..972d4765bb3 100644
--- a/crates/ide_assists/src/handlers/wrap_return_type_in_result.rs
+++ b/crates/ide_assists/src/handlers/wrap_return_type_in_result.rs
@@ -1,6 +1,9 @@
 use std::iter;
 
-use ide_db::helpers::{for_each_tail_expr, node_ext::walk_expr, FamousDefs};
+use ide_db::{
+    famous_defs::FamousDefs,
+    syntax_helpers::node_ext::{for_each_tail_expr, walk_expr},
+};
 use syntax::{
     ast::{self, make, Expr},
     match_ast, AstNode,
diff --git a/crates/ide_assists/src/tests.rs b/crates/ide_assists/src/tests.rs
index 08947e4ecd8..09260c12ed9 100644
--- a/crates/ide_assists/src/tests.rs
+++ b/crates/ide_assists/src/tests.rs
@@ -5,12 +5,9 @@ use expect_test::expect;
 use hir::{db::DefDatabase, Semantics};
 use ide_db::{
     base_db::{fixture::WithFixture, FileId, FileRange, SourceDatabaseExt},
-    helpers::{
-        insert_use::{ImportGranularity, InsertUseConfig},
-        SnippetCap,
-    },
+    imports::insert_use::{ImportGranularity, InsertUseConfig},
     source_change::FileSystemEdit,
-    RootDatabase,
+    RootDatabase, SnippetCap,
 };
 use stdx::{format_to, trim_indent};
 use syntax::TextRange;
diff --git a/crates/ide_assists/src/utils.rs b/crates/ide_assists/src/utils.rs
index 116f150ef2d..42317ea4dab 100644
--- a/crates/ide_assists/src/utils.rs
+++ b/crates/ide_assists/src/utils.rs
@@ -6,9 +6,7 @@ use itertools::Itertools;
 
 pub(crate) use gen_trait_fn_body::gen_trait_fn_body;
 use hir::{db::HirDatabase, HirDisplay, Semantics};
-use ide_db::{
-    helpers::FamousDefs, helpers::SnippetCap, path_transform::PathTransform, RootDatabase,
-};
+use ide_db::{famous_defs::FamousDefs, path_transform::PathTransform, RootDatabase, SnippetCap};
 use stdx::format_to;
 use syntax::{
     ast::{
diff --git a/crates/ide_completion/src/completions/attribute.rs b/crates/ide_completion/src/completions/attribute.rs
index cb45d9de03f..eb287847be8 100644
--- a/crates/ide_completion/src/completions/attribute.rs
+++ b/crates/ide_completion/src/completions/attribute.rs
@@ -3,12 +3,10 @@
 //! This module uses a bit of static metadata to provide completions for builtin-in attributes and lints.
 
 use ide_db::{
-    helpers::{
-        generated_lints::{
-            Lint, CLIPPY_LINTS, CLIPPY_LINT_GROUPS, DEFAULT_LINTS, FEATURES, RUSTDOC_LINTS,
-        },
-        parse_tt_as_comma_sep_paths,
+    generated::lints::{
+        Lint, CLIPPY_LINTS, CLIPPY_LINT_GROUPS, DEFAULT_LINTS, FEATURES, RUSTDOC_LINTS,
     },
+    syntax_helpers::node_ext::parse_tt_as_comma_sep_paths,
     SymbolKind,
 };
 use itertools::Itertools;
diff --git a/crates/ide_completion/src/completions/attribute/derive.rs b/crates/ide_completion/src/completions/attribute/derive.rs
index 29fe096e135..cbd00500855 100644
--- a/crates/ide_completion/src/completions/attribute/derive.rs
+++ b/crates/ide_completion/src/completions/attribute/derive.rs
@@ -1,7 +1,7 @@
 //! Completion for derives
 use hir::{HasAttrs, MacroDef, MacroKind};
 use ide_db::{
-    helpers::{import_assets::ImportAssets, insert_use::ImportScope},
+    imports::{import_assets::ImportAssets, insert_use::ImportScope},
     SymbolKind,
 };
 use itertools::Itertools;
diff --git a/crates/ide_completion/src/completions/attribute/lint.rs b/crates/ide_completion/src/completions/attribute/lint.rs
index e2477423a2d..8991d657e85 100644
--- a/crates/ide_completion/src/completions/attribute/lint.rs
+++ b/crates/ide_completion/src/completions/attribute/lint.rs
@@ -1,5 +1,5 @@
 //! Completion for lints
-use ide_db::{helpers::generated_lints::Lint, SymbolKind};
+use ide_db::{generated::lints::Lint, SymbolKind};
 use syntax::{ast, T};
 
 use crate::{context::CompletionContext, item::CompletionItem, Completions};
diff --git a/crates/ide_completion/src/completions/flyimport.rs b/crates/ide_completion/src/completions/flyimport.rs
index 723abd62aef..0a06e09bac7 100644
--- a/crates/ide_completion/src/completions/flyimport.rs
+++ b/crates/ide_completion/src/completions/flyimport.rs
@@ -1,6 +1,6 @@
 //! See [`import_on_the_fly`].
 use hir::ItemInNs;
-use ide_db::helpers::{
+use ide_db::imports::{
     import_assets::{ImportAssets, ImportCandidate, LocatedImport},
     insert_use::ImportScope,
 };
diff --git a/crates/ide_completion/src/completions/format_string.rs b/crates/ide_completion/src/completions/format_string.rs
index 87052d020a4..f0c994f6b66 100644
--- a/crates/ide_completion/src/completions/format_string.rs
+++ b/crates/ide_completion/src/completions/format_string.rs
@@ -1,6 +1,6 @@
 //! Completes identifiers in format string literals.
 
-use ide_db::helpers::format_string::is_format_string;
+use ide_db::syntax_helpers::format_string::is_format_string;
 use itertools::Itertools;
 use syntax::{ast, AstToken, TextRange, TextSize};
 
diff --git a/crates/ide_completion/src/completions/postfix.rs b/crates/ide_completion/src/completions/postfix.rs
index e8e0c7ea9f1..23d4310aa9c 100644
--- a/crates/ide_completion/src/completions/postfix.rs
+++ b/crates/ide_completion/src/completions/postfix.rs
@@ -3,10 +3,7 @@
 mod format_like;
 
 use hir::{Documentation, HasAttrs};
-use ide_db::{
-    helpers::{insert_use::ImportScope, SnippetCap},
-    ty_filter::TryEnum,
-};
+use ide_db::{imports::insert_use::ImportScope, ty_filter::TryEnum, SnippetCap};
 use syntax::{
     ast::{self, AstNode, AstToken},
     SyntaxKind::{EXPR_STMT, STMT_LIST},
diff --git a/crates/ide_completion/src/completions/postfix/format_like.rs b/crates/ide_completion/src/completions/postfix/format_like.rs
index 8098045b1e5..b5ef87b8812 100644
--- a/crates/ide_completion/src/completions/postfix/format_like.rs
+++ b/crates/ide_completion/src/completions/postfix/format_like.rs
@@ -16,7 +16,7 @@
 //
 // image::https://user-images.githubusercontent.com/48062697/113020656-b560f500-917a-11eb-87de-02991f61beb8.gif[]
 
-use ide_db::helpers::SnippetCap;
+use ide_db::SnippetCap;
 use syntax::ast::{self, AstToken};
 
 use crate::{
diff --git a/crates/ide_completion/src/completions/snippet.rs b/crates/ide_completion/src/completions/snippet.rs
index 9a2b9c2fa40..e4c4899477e 100644
--- a/crates/ide_completion/src/completions/snippet.rs
+++ b/crates/ide_completion/src/completions/snippet.rs
@@ -1,7 +1,7 @@
 //! This file provides snippet completions, like `pd` => `eprintln!(...)`.
 
 use hir::Documentation;
-use ide_db::helpers::{insert_use::ImportScope, SnippetCap};
+use ide_db::{imports::insert_use::ImportScope, SnippetCap};
 use syntax::T;
 
 use crate::{
diff --git a/crates/ide_completion/src/config.rs b/crates/ide_completion/src/config.rs
index c4e91e72830..302836dd1e1 100644
--- a/crates/ide_completion/src/config.rs
+++ b/crates/ide_completion/src/config.rs
@@ -4,7 +4,7 @@
 //! module, and we use to statically check that we only produce snippet
 //! completions if we are allowed to.
 
-use ide_db::helpers::{insert_use::InsertUseConfig, SnippetCap};
+use ide_db::{imports::insert_use::InsertUseConfig, SnippetCap};
 
 use crate::snippet::Snippet;
 
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs
index c4e145ffcb5..da80224dd8c 100644
--- a/crates/ide_completion/src/context.rs
+++ b/crates/ide_completion/src/context.rs
@@ -9,7 +9,7 @@ use hir::{
 use ide_db::{
     active_parameter::ActiveParameter,
     base_db::{FilePosition, SourceDatabase},
-    helpers::FamousDefs,
+    famous_defs::FamousDefs,
     RootDatabase,
 };
 use syntax::{
diff --git a/crates/ide_completion/src/item.rs b/crates/ide_completion/src/item.rs
index 32b14764a10..4b9f7d17c31 100644
--- a/crates/ide_completion/src/item.rs
+++ b/crates/ide_completion/src/item.rs
@@ -4,12 +4,12 @@ use std::fmt;
 
 use hir::{Documentation, Mutability};
 use ide_db::{
-    helpers::{
+    helpers::mod_path_to_ast,
+    imports::{
         import_assets::LocatedImport,
         insert_use::{self, ImportScope, InsertUseConfig},
-        mod_path_to_ast, SnippetCap,
     },
-    SymbolKind,
+    SnippetCap, SymbolKind,
 };
 use smallvec::SmallVec;
 use stdx::{impl_from, never};
diff --git a/crates/ide_completion/src/lib.rs b/crates/ide_completion/src/lib.rs
index 9f6f6592de5..3225a0bc9f4 100644
--- a/crates/ide_completion/src/lib.rs
+++ b/crates/ide_completion/src/lib.rs
@@ -14,10 +14,10 @@ mod snippet;
 use completions::flyimport::position_for_import;
 use ide_db::{
     base_db::FilePosition,
-    helpers::{
+    helpers::mod_path_to_ast,
+    imports::{
         import_assets::NameToImport,
         insert_use::{self, ImportScope},
-        mod_path_to_ast,
     },
     items_locator, RootDatabase,
 };
diff --git a/crates/ide_completion/src/render.rs b/crates/ide_completion/src/render.rs
index d5618f14743..1836f80bfb5 100644
--- a/crates/ide_completion/src/render.rs
+++ b/crates/ide_completion/src/render.rs
@@ -12,10 +12,7 @@ pub(crate) mod struct_literal;
 mod builder_ext;
 
 use hir::{AsAssocItem, HasAttrs, HirDisplay, ScopeDef};
-use ide_db::{
-    helpers::{item_name, SnippetCap},
-    RootDatabase, SymbolKind,
-};
+use ide_db::{helpers::item_name, RootDatabase, SnippetCap, SymbolKind};
 use syntax::{SmolStr, SyntaxKind, TextRange};
 
 use crate::{
diff --git a/crates/ide_completion/src/render/pattern.rs b/crates/ide_completion/src/render/pattern.rs
index 68e29246d74..c2d51b1252c 100644
--- a/crates/ide_completion/src/render/pattern.rs
+++ b/crates/ide_completion/src/render/pattern.rs
@@ -1,7 +1,7 @@
 //! Renderer for patterns.
 
 use hir::{db::HirDatabase, HasAttrs, HasVisibility, Name, StructKind};
-use ide_db::helpers::SnippetCap;
+use ide_db::SnippetCap;
 use itertools::Itertools;
 use syntax::SmolStr;
 
diff --git a/crates/ide_completion/src/render/struct_literal.rs b/crates/ide_completion/src/render/struct_literal.rs
index a3d4bcf29e9..3bc94fa782a 100644
--- a/crates/ide_completion/src/render/struct_literal.rs
+++ b/crates/ide_completion/src/render/struct_literal.rs
@@ -1,7 +1,7 @@
 //! Renderer for `struct` literal.
 
 use hir::{db::HirDatabase, HasAttrs, HasVisibility, Name, StructKind};
-use ide_db::helpers::SnippetCap;
+use ide_db::SnippetCap;
 use itertools::Itertools;
 use syntax::SmolStr;
 
diff --git a/crates/ide_completion/src/snippet.rs b/crates/ide_completion/src/snippet.rs
index 3a4f713333b..05b066a0a91 100644
--- a/crates/ide_completion/src/snippet.rs
+++ b/crates/ide_completion/src/snippet.rs
@@ -102,7 +102,7 @@ use std::ops::Deref;
 // }
 // ----
 
-use ide_db::helpers::{import_assets::LocatedImport, insert_use::ImportScope};
+use ide_db::imports::{import_assets::LocatedImport, insert_use::ImportScope};
 use itertools::Itertools;
 use syntax::{ast, AstNode, GreenNode, SyntaxNode};
 
diff --git a/crates/ide_completion/src/tests.rs b/crates/ide_completion/src/tests.rs
index 45c7c58dc03..eedc37e2a6f 100644
--- a/crates/ide_completion/src/tests.rs
+++ b/crates/ide_completion/src/tests.rs
@@ -27,11 +27,8 @@ use std::mem;
 use hir::{db::DefDatabase, PrefixKind, Semantics};
 use ide_db::{
     base_db::{fixture::ChangeFixture, FileLoader, FilePosition},
-    helpers::{
-        insert_use::{ImportGranularity, InsertUseConfig},
-        SnippetCap,
-    },
-    RootDatabase,
+    imports::insert_use::{ImportGranularity, InsertUseConfig},
+    RootDatabase, SnippetCap,
 };
 use itertools::Itertools;
 use stdx::{format_to, trim_indent};
diff --git a/crates/ide_db/src/helpers/famous_defs.rs b/crates/ide_db/src/famous_defs.rs
index ee7bf9540bc..ee7bf9540bc 100644
--- a/crates/ide_db/src/helpers/famous_defs.rs
+++ b/crates/ide_db/src/famous_defs.rs
diff --git a/crates/ide_db/src/helpers/generated_lints.rs b/crates/ide_db/src/generated/lints.rs
index 64dd2bb5f2d..64dd2bb5f2d 100644
--- a/crates/ide_db/src/helpers/generated_lints.rs
+++ b/crates/ide_db/src/generated/lints.rs
diff --git a/crates/ide_db/src/helpers.rs b/crates/ide_db/src/helpers.rs
index 4a14a7f849b..1e3d68b3218 100644
--- a/crates/ide_db/src/helpers.rs
+++ b/crates/ide_db/src/helpers.rs
@@ -1,28 +1,15 @@
-//! A module with ide helpers for high-level ide features.
-pub mod famous_defs;
-pub mod generated_lints;
-pub mod import_assets;
-pub mod insert_use;
-pub mod merge_imports;
-pub mod insert_whitespace_into_node;
-pub mod node_ext;
-pub mod rust_doc;
-pub mod format_string;
+//! Random assortment of ide helpers for high-level ide features that don't fit in any other module.
 
 use std::collections::VecDeque;
 
 use base_db::FileId;
 use hir::{ItemInNs, MacroDef, ModuleDef, Name, Semantics};
-use itertools::Itertools;
 use syntax::{
-    ast::{self, make, HasLoopBody},
-    AstNode, AstToken, Preorder, RustLanguage, SyntaxKind, SyntaxToken, TokenAtOffset, WalkEvent,
-    T,
+    ast::{self, make},
+    AstToken, SyntaxKind, SyntaxToken, TokenAtOffset,
 };
 
-use crate::{defs::Definition, RootDatabase};
-
-pub use self::famous_defs::FamousDefs;
+use crate::{defs::Definition, generated, RootDatabase};
 
 pub fn item_name(db: &RootDatabase, item: ItemInNs) -> Option<Name> {
     match item {
@@ -91,216 +78,16 @@ pub fn visit_file_defs(
     module.impl_defs(db).into_iter().for_each(|impl_| cb(impl_.into()));
 }
 
-#[derive(Clone, Copy, Debug, PartialEq, Eq)]
-pub struct SnippetCap {
-    _private: (),
-}
-
-impl SnippetCap {
-    pub const fn new(allow_snippets: bool) -> Option<SnippetCap> {
-        if allow_snippets {
-            Some(SnippetCap { _private: () })
-        } else {
-            None
-        }
-    }
-}
-
-/// Calls `cb` on each expression inside `expr` that is at "tail position".
-/// Does not walk into `break` or `return` expressions.
-/// Note that modifying the tree while iterating it will cause undefined iteration which might
-/// potentially results in an out of bounds panic.
-pub fn for_each_tail_expr(expr: &ast::Expr, cb: &mut dyn FnMut(&ast::Expr)) {
-    match expr {
-        ast::Expr::BlockExpr(b) => {
-            match b.modifier() {
-                Some(
-                    ast::BlockModifier::Async(_)
-                    | ast::BlockModifier::Try(_)
-                    | ast::BlockModifier::Const(_),
-                ) => return cb(expr),
-
-                Some(ast::BlockModifier::Label(label)) => {
-                    for_each_break_expr(Some(label), b.stmt_list(), &mut |b| {
-                        cb(&ast::Expr::BreakExpr(b))
-                    });
-                }
-                Some(ast::BlockModifier::Unsafe(_)) => (),
-                None => (),
-            }
-            if let Some(stmt_list) = b.stmt_list() {
-                if let Some(e) = stmt_list.tail_expr() {
-                    for_each_tail_expr(&e, cb);
-                }
-            }
-        }
-        ast::Expr::IfExpr(if_) => {
-            let mut if_ = if_.clone();
-            loop {
-                if let Some(block) = if_.then_branch() {
-                    for_each_tail_expr(&ast::Expr::BlockExpr(block), cb);
-                }
-                match if_.else_branch() {
-                    Some(ast::ElseBranch::IfExpr(it)) => if_ = it,
-                    Some(ast::ElseBranch::Block(block)) => {
-                        for_each_tail_expr(&ast::Expr::BlockExpr(block), cb);
-                        break;
-                    }
-                    None => break,
-                }
-            }
-        }
-        ast::Expr::LoopExpr(l) => {
-            for_each_break_expr(l.label(), l.loop_body().and_then(|it| it.stmt_list()), &mut |b| {
-                cb(&ast::Expr::BreakExpr(b))
-            })
-        }
-        ast::Expr::MatchExpr(m) => {
-            if let Some(arms) = m.match_arm_list() {
-                arms.arms().filter_map(|arm| arm.expr()).for_each(|e| for_each_tail_expr(&e, cb));
-            }
-        }
-        ast::Expr::ArrayExpr(_)
-        | ast::Expr::AwaitExpr(_)
-        | ast::Expr::BinExpr(_)
-        | ast::Expr::BoxExpr(_)
-        | ast::Expr::BreakExpr(_)
-        | ast::Expr::CallExpr(_)
-        | ast::Expr::CastExpr(_)
-        | ast::Expr::ClosureExpr(_)
-        | ast::Expr::ContinueExpr(_)
-        | ast::Expr::FieldExpr(_)
-        | ast::Expr::ForExpr(_)
-        | ast::Expr::IndexExpr(_)
-        | ast::Expr::Literal(_)
-        | ast::Expr::MacroCall(_)
-        | ast::Expr::MacroStmts(_)
-        | ast::Expr::MethodCallExpr(_)
-        | ast::Expr::ParenExpr(_)
-        | ast::Expr::PathExpr(_)
-        | ast::Expr::PrefixExpr(_)
-        | ast::Expr::RangeExpr(_)
-        | ast::Expr::RecordExpr(_)
-        | ast::Expr::RefExpr(_)
-        | ast::Expr::ReturnExpr(_)
-        | ast::Expr::TryExpr(_)
-        | ast::Expr::TupleExpr(_)
-        | ast::Expr::WhileExpr(_)
-        | ast::Expr::LetExpr(_)
-        | ast::Expr::UnderscoreExpr(_)
-        | ast::Expr::YieldExpr(_) => cb(expr),
-    }
-}
-
-pub fn for_each_break_and_continue_expr(
-    label: Option<ast::Label>,
-    body: Option<ast::StmtList>,
-    cb: &mut dyn FnMut(ast::Expr),
-) {
-    let label = label.and_then(|lbl| lbl.lifetime());
-    if let Some(b) = body {
-        let tree_depth_iterator = TreeWithDepthIterator::new(b);
-        for (expr, depth) in tree_depth_iterator {
-            match expr {
-                ast::Expr::BreakExpr(b)
-                    if (depth == 0 && b.lifetime().is_none())
-                        || eq_label_lt(&label, &b.lifetime()) =>
-                {
-                    cb(ast::Expr::BreakExpr(b));
-                }
-                ast::Expr::ContinueExpr(c)
-                    if (depth == 0 && c.lifetime().is_none())
-                        || eq_label_lt(&label, &c.lifetime()) =>
-                {
-                    cb(ast::Expr::ContinueExpr(c));
-                }
-                _ => (),
-            }
-        }
-    }
-}
-
-fn for_each_break_expr(
-    label: Option<ast::Label>,
-    body: Option<ast::StmtList>,
-    cb: &mut dyn FnMut(ast::BreakExpr),
-) {
-    let label = label.and_then(|lbl| lbl.lifetime());
-    if let Some(b) = body {
-        let tree_depth_iterator = TreeWithDepthIterator::new(b);
-        for (expr, depth) in tree_depth_iterator {
-            match expr {
-                ast::Expr::BreakExpr(b)
-                    if (depth == 0 && b.lifetime().is_none())
-                        || eq_label_lt(&label, &b.lifetime()) =>
-                {
-                    cb(b);
-                }
-                _ => (),
-            }
-        }
-    }
-}
-
-fn eq_label_lt(lt1: &Option<ast::Lifetime>, lt2: &Option<ast::Lifetime>) -> bool {
-    lt1.as_ref().zip(lt2.as_ref()).map_or(false, |(lt, lbl)| lt.text() == lbl.text())
-}
-
-struct TreeWithDepthIterator {
-    preorder: Preorder<RustLanguage>,
-    depth: u32,
-}
-
-impl TreeWithDepthIterator {
-    fn new(body: ast::StmtList) -> Self {
-        let preorder = body.syntax().preorder();
-        Self { preorder, depth: 0 }
-    }
-}
-
-impl<'a> Iterator for TreeWithDepthIterator {
-    type Item = (ast::Expr, u32);
-
-    fn next(&mut self) -> Option<Self::Item> {
-        while let Some(event) = self.preorder.find_map(|ev| match ev {
-            WalkEvent::Enter(it) => ast::Expr::cast(it).map(WalkEvent::Enter),
-            WalkEvent::Leave(it) => ast::Expr::cast(it).map(WalkEvent::Leave),
-        }) {
-            match event {
-                WalkEvent::Enter(
-                    ast::Expr::LoopExpr(_) | ast::Expr::WhileExpr(_) | ast::Expr::ForExpr(_),
-                ) => {
-                    self.depth += 1;
-                }
-                WalkEvent::Leave(
-                    ast::Expr::LoopExpr(_) | ast::Expr::WhileExpr(_) | ast::Expr::ForExpr(_),
-                ) => {
-                    self.depth -= 1;
-                }
-                WalkEvent::Enter(ast::Expr::BlockExpr(e)) if e.label().is_some() => {
-                    self.depth += 1;
-                }
-                WalkEvent::Leave(ast::Expr::BlockExpr(e)) if e.label().is_some() => {
-                    self.depth -= 1;
-                }
-                WalkEvent::Enter(expr) => return Some((expr, self.depth)),
-                _ => (),
-            }
-        }
-        None
-    }
-}
-
 /// Checks if the given lint is equal or is contained by the other lint which may or may not be a group.
 pub fn lint_eq_or_in_group(lint: &str, lint_is: &str) -> bool {
     if lint == lint_is {
         return true;
     }
 
-    if let Some(group) = generated_lints::DEFAULT_LINT_GROUPS
+    if let Some(group) = generated::lints::DEFAULT_LINT_GROUPS
         .iter()
-        .chain(generated_lints::CLIPPY_LINT_GROUPS.iter())
-        .chain(generated_lints::RUSTDOC_LINT_GROUPS.iter())
+        .chain(generated::lints::CLIPPY_LINT_GROUPS.iter())
+        .chain(generated::lints::RUSTDOC_LINT_GROUPS.iter())
         .find(|&check| check.lint.label == lint_is)
     {
         group.children.contains(&lint)
@@ -308,30 +95,3 @@ pub fn lint_eq_or_in_group(lint: &str, lint_is: &str) -> bool {
         false
     }
 }
-
-/// Parses the input token tree as comma separated plain paths.
-pub fn parse_tt_as_comma_sep_paths(input: ast::TokenTree) -> Option<Vec<ast::Path>> {
-    let r_paren = input.r_paren_token();
-    let tokens =
-        input.syntax().children_with_tokens().skip(1).map_while(|it| match it.into_token() {
-            // seeing a keyword means the attribute is unclosed so stop parsing here
-            Some(tok) if tok.kind().is_keyword() => None,
-            // don't include the right token tree parenthesis if it exists
-            tok @ Some(_) if tok == r_paren => None,
-            // only nodes that we can find are other TokenTrees, those are unexpected in this parse though
-            None => None,
-            Some(tok) => Some(tok),
-        });
-    let input_expressions = tokens.into_iter().group_by(|tok| tok.kind() == T![,]);
-    let paths = input_expressions
-        .into_iter()
-        .filter_map(|(is_sep, group)| (!is_sep).then(|| group))
-        .filter_map(|mut tokens| {
-            syntax::hacks::parse_expr_from_str(&tokens.join("")).and_then(|expr| match expr {
-                ast::Expr::PathExpr(it) => it.path(),
-                _ => None,
-            })
-        })
-        .collect();
-    Some(paths)
-}
diff --git a/crates/ide_db/src/helpers/import_assets.rs b/crates/ide_db/src/imports/import_assets.rs
index d91627e0a92..3c63f65fce6 100644
--- a/crates/ide_db/src/helpers/import_assets.rs
+++ b/crates/ide_db/src/imports/import_assets.rs
@@ -12,12 +12,11 @@ use syntax::{
 };
 
 use crate::{
+    helpers::item_name,
     items_locator::{self, AssocItemSearch, DEFAULT_QUERY_SEARCH_LIMIT},
     RootDatabase,
 };
 
-use super::item_name;
-
 /// A candidate for import, derived during various IDE activities:
 /// * completion with imports on the fly proposals
 /// * completion edit resolve requests
diff --git a/crates/ide_db/src/helpers/insert_use.rs b/crates/ide_db/src/imports/insert_use.rs
index efb704b253d..9e39c26b45b 100644
--- a/crates/ide_db/src/helpers/insert_use.rs
+++ b/crates/ide_db/src/imports/insert_use.rs
@@ -12,7 +12,7 @@ use syntax::{
 };
 
 use crate::{
-    helpers::merge_imports::{
+    imports::merge_imports::{
         common_prefix, eq_attrs, eq_visibility, try_merge_imports, use_tree_path_cmp, MergeBehavior,
     },
     RootDatabase,
diff --git a/crates/ide_db/src/helpers/insert_use/tests.rs b/crates/ide_db/src/imports/insert_use/tests.rs
index 4219358a07f..4219358a07f 100644
--- a/crates/ide_db/src/helpers/insert_use/tests.rs
+++ b/crates/ide_db/src/imports/insert_use/tests.rs
diff --git a/crates/ide_db/src/helpers/merge_imports.rs b/crates/ide_db/src/imports/merge_imports.rs
index dfaf578cb15..71859b7fc7d 100644
--- a/crates/ide_db/src/helpers/merge_imports.rs
+++ b/crates/ide_db/src/imports/merge_imports.rs
@@ -7,7 +7,7 @@ use syntax::{
     ted,
 };
 
-use crate::helpers::node_ext::vis_eq;
+use crate::syntax_helpers::node_ext::vis_eq;
 
 /// What type of merges are allowed.
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
diff --git a/crates/ide_db/src/items_locator.rs b/crates/ide_db/src/items_locator.rs
index db38a487830..891b7c8e920 100644
--- a/crates/ide_db/src/items_locator.rs
+++ b/crates/ide_db/src/items_locator.rs
@@ -13,7 +13,7 @@ use syntax::{ast, AstNode, SyntaxKind::NAME};
 
 use crate::{
     defs::{Definition, NameClass},
-    helpers::import_assets::NameToImport,
+    imports::import_assets::NameToImport,
     symbol_index, RootDatabase,
 };
 
diff --git a/crates/ide_db/src/lib.rs b/crates/ide_db/src/lib.rs
index 3f64c0a1243..b11b70d1276 100644
--- a/crates/ide_db/src/lib.rs
+++ b/crates/ide_db/src/lib.rs
@@ -4,21 +4,38 @@
 
 mod apply_change;
 
+pub mod active_parameter;
 pub mod assists;
-pub mod label;
-pub mod line_index;
-pub mod symbol_index;
 pub mod defs;
+pub mod famous_defs;
+pub mod helpers;
 pub mod items_locator;
+pub mod label;
+pub mod line_index;
+pub mod path_transform;
+pub mod rename;
+pub mod rust_doc;
+pub mod search;
 pub mod source_change;
-pub mod ty_filter;
+pub mod symbol_index;
 pub mod traits;
-pub mod helpers;
-pub mod path_transform;
+pub mod ty_filter;
 
-pub mod search;
-pub mod rename;
-pub mod active_parameter;
+pub mod imports {
+    pub mod import_assets;
+    pub mod insert_use;
+    pub mod merge_imports;
+}
+
+pub mod generated {
+    pub mod lints;
+}
+
+pub mod syntax_helpers {
+    pub mod node_ext;
+    pub mod insert_whitespace_into_node;
+    pub mod format_string;
+}
 
 use std::{fmt, mem::ManuallyDrop, sync::Arc};
 
@@ -42,14 +59,14 @@ pub type FxIndexMap<K, V> =
     indexmap::IndexMap<K, V, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
 
 #[salsa::database(
-    base_db::SourceDatabaseStorage,
     base_db::SourceDatabaseExtStorage,
-    LineIndexDatabaseStorage,
-    symbol_index::SymbolsDatabaseStorage,
-    hir::db::InternDatabaseStorage,
+    base_db::SourceDatabaseStorage,
     hir::db::AstDatabaseStorage,
     hir::db::DefDatabaseStorage,
-    hir::db::HirDatabaseStorage
+    hir::db::HirDatabaseStorage,
+    hir::db::InternDatabaseStorage,
+    LineIndexDatabaseStorage,
+    symbol_index::SymbolsDatabaseStorage
 )]
 pub struct RootDatabase {
     // We use `ManuallyDrop` here because every codegen unit that contains a
@@ -61,9 +78,7 @@ pub struct RootDatabase {
 
 impl Drop for RootDatabase {
     fn drop(&mut self) {
-        unsafe {
-            ManuallyDrop::drop(&mut self.storage);
-        }
+        unsafe { ManuallyDrop::drop(&mut self.storage) };
     }
 }
 
@@ -117,7 +132,7 @@ impl RootDatabase {
         db.set_crate_graph_with_durability(Default::default(), Durability::HIGH);
         db.set_local_roots_with_durability(Default::default(), Durability::HIGH);
         db.set_library_roots_with_durability(Default::default(), Durability::HIGH);
-        db.set_enable_proc_attr_macros(Default::default());
+        db.set_enable_proc_attr_macros(false);
         db.update_lru_capacity(lru_capacity);
         db
     }
@@ -204,6 +219,21 @@ impl From<FileSymbolKind> for SymbolKind {
     }
 }
 
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub struct SnippetCap {
+    _private: (),
+}
+
+impl SnippetCap {
+    pub const fn new(allow_snippets: bool) -> Option<SnippetCap> {
+        if allow_snippets {
+            Some(SnippetCap { _private: () })
+        } else {
+            None
+        }
+    }
+}
+
 #[cfg(test)]
 mod tests {
     mod sourcegen_lints;
diff --git a/crates/ide_db/src/line_index.rs b/crates/ide_db/src/line_index.rs
index 35e1757eaec..68ad07ee83f 100644
--- a/crates/ide_db/src/line_index.rs
+++ b/crates/ide_db/src/line_index.rs
@@ -1,6 +1,6 @@
 //! `LineIndex` maps flat `TextSize` offsets into `(Line, Column)`
 //! representation.
-use std::iter;
+use std::{iter, mem};
 
 use rustc_hash::FxHashMap;
 use syntax::{TextRange, TextSize};
@@ -59,8 +59,7 @@ impl LineIndex {
         let mut utf16_chars = Vec::new();
 
         let mut newlines = vec![0.into()];
-        let mut curr_row = 0.into();
-        let mut curr_col = 0.into();
+        let mut curr_row @ mut curr_col = 0.into();
         let mut line = 0;
         for c in text.chars() {
             let c_len = TextSize::of(c);
@@ -70,8 +69,7 @@ impl LineIndex {
 
                 // Save any utf-16 characters seen in the previous line
                 if !utf16_chars.is_empty() {
-                    utf16_lines.insert(line, utf16_chars);
-                    utf16_chars = Vec::new();
+                    utf16_lines.insert(line, mem::take(&mut utf16_chars));
                 }
 
                 // Prepare for processing the next line
@@ -165,4 +163,138 @@ impl LineIndex {
 }
 
 #[cfg(test)]
-mod tests;
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_line_index() {
+        let text = "hello\nworld";
+        let table = [
+            (00, 0, 0),
+            (01, 0, 1),
+            (05, 0, 5),
+            (06, 1, 0),
+            (07, 1, 1),
+            (08, 1, 2),
+            (10, 1, 4),
+            (11, 1, 5),
+            (12, 1, 6),
+        ];
+
+        let index = LineIndex::new(text);
+        for &(offset, line, col) in &table {
+            assert_eq!(index.line_col(offset.into()), LineCol { line, col });
+        }
+
+        let text = "\nhello\nworld";
+        let table = [(0, 0, 0), (1, 1, 0), (2, 1, 1), (6, 1, 5), (7, 2, 0)];
+        let index = LineIndex::new(text);
+        for &(offset, line, col) in &table {
+            assert_eq!(index.line_col(offset.into()), LineCol { line, col });
+        }
+    }
+
+    #[test]
+    fn test_char_len() {
+        assert_eq!('メ'.len_utf8(), 3);
+        assert_eq!('メ'.len_utf16(), 1);
+    }
+
+    #[test]
+    fn test_empty_index() {
+        let col_index = LineIndex::new(
+            "
+const C: char = 'x';
+",
+        );
+        assert_eq!(col_index.utf16_lines.len(), 0);
+    }
+
+    #[test]
+    fn test_single_char() {
+        let col_index = LineIndex::new(
+            "
+const C: char = 'メ';
+",
+        );
+
+        assert_eq!(col_index.utf16_lines.len(), 1);
+        assert_eq!(col_index.utf16_lines[&1].len(), 1);
+        assert_eq!(col_index.utf16_lines[&1][0], Utf16Char { start: 17.into(), end: 20.into() });
+
+        // UTF-8 to UTF-16, no changes
+        assert_eq!(col_index.utf8_to_utf16_col(1, 15.into()), 15);
+
+        // UTF-8 to UTF-16
+        assert_eq!(col_index.utf8_to_utf16_col(1, 22.into()), 20);
+
+        // UTF-16 to UTF-8, no changes
+        assert_eq!(col_index.utf16_to_utf8_col(1, 15), TextSize::from(15));
+
+        // UTF-16 to UTF-8
+        assert_eq!(col_index.utf16_to_utf8_col(1, 19), TextSize::from(21));
+
+        let col_index = LineIndex::new("a𐐏b");
+        assert_eq!(col_index.utf16_to_utf8_col(0, 3), TextSize::from(5));
+    }
+
+    #[test]
+    fn test_string() {
+        let col_index = LineIndex::new(
+            "
+const C: char = \"メ メ\";
+",
+        );
+
+        assert_eq!(col_index.utf16_lines.len(), 1);
+        assert_eq!(col_index.utf16_lines[&1].len(), 2);
+        assert_eq!(col_index.utf16_lines[&1][0], Utf16Char { start: 17.into(), end: 20.into() });
+        assert_eq!(col_index.utf16_lines[&1][1], Utf16Char { start: 21.into(), end: 24.into() });
+
+        // UTF-8 to UTF-16
+        assert_eq!(col_index.utf8_to_utf16_col(1, 15.into()), 15);
+
+        assert_eq!(col_index.utf8_to_utf16_col(1, 21.into()), 19);
+        assert_eq!(col_index.utf8_to_utf16_col(1, 25.into()), 21);
+
+        assert!(col_index.utf8_to_utf16_col(2, 15.into()) == 15);
+
+        // UTF-16 to UTF-8
+        assert_eq!(col_index.utf16_to_utf8_col(1, 15), TextSize::from(15));
+
+        // メ UTF-8: 0xE3 0x83 0xA1, UTF-16: 0x30E1
+        assert_eq!(col_index.utf16_to_utf8_col(1, 17), TextSize::from(17)); // first メ at 17..20
+        assert_eq!(col_index.utf16_to_utf8_col(1, 18), TextSize::from(20)); // space
+        assert_eq!(col_index.utf16_to_utf8_col(1, 19), TextSize::from(21)); // second メ at 21..24
+
+        assert_eq!(col_index.utf16_to_utf8_col(2, 15), TextSize::from(15));
+    }
+
+    #[test]
+    fn test_splitlines() {
+        fn r(lo: u32, hi: u32) -> TextRange {
+            TextRange::new(lo.into(), hi.into())
+        }
+
+        let text = "a\nbb\nccc\n";
+        let line_index = LineIndex::new(text);
+
+        let actual = line_index.lines(r(0, 9)).collect::<Vec<_>>();
+        let expected = vec![r(0, 2), r(2, 5), r(5, 9)];
+        assert_eq!(actual, expected);
+
+        let text = "";
+        let line_index = LineIndex::new(text);
+
+        let actual = line_index.lines(r(0, 0)).collect::<Vec<_>>();
+        let expected = vec![];
+        assert_eq!(actual, expected);
+
+        let text = "\n";
+        let line_index = LineIndex::new(text);
+
+        let actual = line_index.lines(r(0, 1)).collect::<Vec<_>>();
+        let expected = vec![r(0, 1)];
+        assert_eq!(actual, expected)
+    }
+}
diff --git a/crates/ide_db/src/line_index/tests.rs b/crates/ide_db/src/line_index/tests.rs
deleted file mode 100644
index 09f3bca626c..00000000000
--- a/crates/ide_db/src/line_index/tests.rs
+++ /dev/null
@@ -1,133 +0,0 @@
-use super::*;
-
-#[test]
-fn test_line_index() {
-    let text = "hello\nworld";
-    let table = [
-        (00, 0, 0),
-        (01, 0, 1),
-        (05, 0, 5),
-        (06, 1, 0),
-        (07, 1, 1),
-        (08, 1, 2),
-        (10, 1, 4),
-        (11, 1, 5),
-        (12, 1, 6),
-    ];
-
-    let index = LineIndex::new(text);
-    for &(offset, line, col) in &table {
-        assert_eq!(index.line_col(offset.into()), LineCol { line, col });
-    }
-
-    let text = "\nhello\nworld";
-    let table = [(0, 0, 0), (1, 1, 0), (2, 1, 1), (6, 1, 5), (7, 2, 0)];
-    let index = LineIndex::new(text);
-    for &(offset, line, col) in &table {
-        assert_eq!(index.line_col(offset.into()), LineCol { line, col });
-    }
-}
-
-#[test]
-fn test_char_len() {
-    assert_eq!('メ'.len_utf8(), 3);
-    assert_eq!('メ'.len_utf16(), 1);
-}
-
-#[test]
-fn test_empty_index() {
-    let col_index = LineIndex::new(
-        "
-const C: char = 'x';
-",
-    );
-    assert_eq!(col_index.utf16_lines.len(), 0);
-}
-
-#[test]
-fn test_single_char() {
-    let col_index = LineIndex::new(
-        "
-const C: char = 'メ';
-",
-    );
-
-    assert_eq!(col_index.utf16_lines.len(), 1);
-    assert_eq!(col_index.utf16_lines[&1].len(), 1);
-    assert_eq!(col_index.utf16_lines[&1][0], Utf16Char { start: 17.into(), end: 20.into() });
-
-    // UTF-8 to UTF-16, no changes
-    assert_eq!(col_index.utf8_to_utf16_col(1, 15.into()), 15);
-
-    // UTF-8 to UTF-16
-    assert_eq!(col_index.utf8_to_utf16_col(1, 22.into()), 20);
-
-    // UTF-16 to UTF-8, no changes
-    assert_eq!(col_index.utf16_to_utf8_col(1, 15), TextSize::from(15));
-
-    // UTF-16 to UTF-8
-    assert_eq!(col_index.utf16_to_utf8_col(1, 19), TextSize::from(21));
-
-    let col_index = LineIndex::new("a𐐏b");
-    assert_eq!(col_index.utf16_to_utf8_col(0, 3), TextSize::from(5));
-}
-
-#[test]
-fn test_string() {
-    let col_index = LineIndex::new(
-        "
-const C: char = \"メ メ\";
-",
-    );
-
-    assert_eq!(col_index.utf16_lines.len(), 1);
-    assert_eq!(col_index.utf16_lines[&1].len(), 2);
-    assert_eq!(col_index.utf16_lines[&1][0], Utf16Char { start: 17.into(), end: 20.into() });
-    assert_eq!(col_index.utf16_lines[&1][1], Utf16Char { start: 21.into(), end: 24.into() });
-
-    // UTF-8 to UTF-16
-    assert_eq!(col_index.utf8_to_utf16_col(1, 15.into()), 15);
-
-    assert_eq!(col_index.utf8_to_utf16_col(1, 21.into()), 19);
-    assert_eq!(col_index.utf8_to_utf16_col(1, 25.into()), 21);
-
-    assert!(col_index.utf8_to_utf16_col(2, 15.into()) == 15);
-
-    // UTF-16 to UTF-8
-    assert_eq!(col_index.utf16_to_utf8_col(1, 15), TextSize::from(15));
-
-    // メ UTF-8: 0xE3 0x83 0xA1, UTF-16: 0x30E1
-    assert_eq!(col_index.utf16_to_utf8_col(1, 17), TextSize::from(17)); // first メ at 17..20
-    assert_eq!(col_index.utf16_to_utf8_col(1, 18), TextSize::from(20)); // space
-    assert_eq!(col_index.utf16_to_utf8_col(1, 19), TextSize::from(21)); // second メ at 21..24
-
-    assert_eq!(col_index.utf16_to_utf8_col(2, 15), TextSize::from(15));
-}
-
-#[test]
-fn test_splitlines() {
-    fn r(lo: u32, hi: u32) -> TextRange {
-        TextRange::new(lo.into(), hi.into())
-    }
-
-    let text = "a\nbb\nccc\n";
-    let line_index = LineIndex::new(text);
-
-    let actual = line_index.lines(r(0, 9)).collect::<Vec<_>>();
-    let expected = vec![r(0, 2), r(2, 5), r(5, 9)];
-    assert_eq!(actual, expected);
-
-    let text = "";
-    let line_index = LineIndex::new(text);
-
-    let actual = line_index.lines(r(0, 0)).collect::<Vec<_>>();
-    let expected = vec![];
-    assert_eq!(actual, expected);
-
-    let text = "\n";
-    let line_index = LineIndex::new(text);
-
-    let actual = line_index.lines(r(0, 1)).collect::<Vec<_>>();
-    let expected = vec![r(0, 1)];
-    assert_eq!(actual, expected)
-}
diff --git a/crates/ide_db/src/rename.rs b/crates/ide_db/src/rename.rs
index a44fe04e748..13234a817b2 100644
--- a/crates/ide_db/src/rename.rs
+++ b/crates/ide_db/src/rename.rs
@@ -10,7 +10,7 @@
 //!
 //! Another can of worms are macros:
 //!
-//! ```
+//! ```ignore
 //! macro_rules! m { () => { fn f() {} } }
 //! m!();
 //! fn main() {
@@ -34,9 +34,9 @@ use text_edit::{TextEdit, TextEditBuilder};
 
 use crate::{
     defs::Definition,
-    helpers::node_ext::expr_as_name_ref,
     search::FileReference,
     source_change::{FileSystemEdit, SourceChange},
+    syntax_helpers::node_ext::expr_as_name_ref,
     RootDatabase,
 };
 
diff --git a/crates/ide_db/src/helpers/rust_doc.rs b/crates/ide_db/src/rust_doc.rs
index e27e23867a8..e27e23867a8 100644
--- a/crates/ide_db/src/helpers/rust_doc.rs
+++ b/crates/ide_db/src/rust_doc.rs
diff --git a/crates/ide_db/src/helpers/format_string.rs b/crates/ide_db/src/syntax_helpers/format_string.rs
index 3c584a6cbc9..3c584a6cbc9 100644
--- a/crates/ide_db/src/helpers/format_string.rs
+++ b/crates/ide_db/src/syntax_helpers/format_string.rs
diff --git a/crates/ide_db/src/helpers/insert_whitespace_into_node.rs b/crates/ide_db/src/syntax_helpers/insert_whitespace_into_node.rs
index d59f13b9a1c..d59f13b9a1c 100644
--- a/crates/ide_db/src/helpers/insert_whitespace_into_node.rs
+++ b/crates/ide_db/src/syntax_helpers/insert_whitespace_into_node.rs
diff --git a/crates/ide_db/src/helpers/node_ext.rs b/crates/ide_db/src/syntax_helpers/node_ext.rs
index 5df3ed1366f..115d83c6e25 100644
--- a/crates/ide_db/src/helpers/node_ext.rs
+++ b/crates/ide_db/src/syntax_helpers/node_ext.rs
@@ -1,7 +1,9 @@
 //! Various helper functions to work with SyntaxNodes.
+use itertools::Itertools;
+use parser::T;
 use syntax::{
-    ast::{self, PathSegmentKind, VisibilityKind},
-    AstNode, WalkEvent,
+    ast::{self, HasLoopBody, PathSegmentKind, VisibilityKind},
+    AstNode, Preorder, RustLanguage, WalkEvent,
 };
 
 pub fn expr_as_name_ref(expr: &ast::Expr) -> Option<ast::NameRef> {
@@ -242,3 +244,215 @@ pub fn is_pattern_cond(expr: ast::Expr) -> bool {
         _ => false,
     }
 }
+
+/// Calls `cb` on each expression inside `expr` that is at "tail position".
+/// Does not walk into `break` or `return` expressions.
+/// Note that modifying the tree while iterating it will cause undefined iteration which might
+/// potentially results in an out of bounds panic.
+pub fn for_each_tail_expr(expr: &ast::Expr, cb: &mut dyn FnMut(&ast::Expr)) {
+    match expr {
+        ast::Expr::BlockExpr(b) => {
+            match b.modifier() {
+                Some(
+                    ast::BlockModifier::Async(_)
+                    | ast::BlockModifier::Try(_)
+                    | ast::BlockModifier::Const(_),
+                ) => return cb(expr),
+
+                Some(ast::BlockModifier::Label(label)) => {
+                    for_each_break_expr(Some(label), b.stmt_list(), &mut |b| {
+                        cb(&ast::Expr::BreakExpr(b))
+                    });
+                }
+                Some(ast::BlockModifier::Unsafe(_)) => (),
+                None => (),
+            }
+            if let Some(stmt_list) = b.stmt_list() {
+                if let Some(e) = stmt_list.tail_expr() {
+                    for_each_tail_expr(&e, cb);
+                }
+            }
+        }
+        ast::Expr::IfExpr(if_) => {
+            let mut if_ = if_.clone();
+            loop {
+                if let Some(block) = if_.then_branch() {
+                    for_each_tail_expr(&ast::Expr::BlockExpr(block), cb);
+                }
+                match if_.else_branch() {
+                    Some(ast::ElseBranch::IfExpr(it)) => if_ = it,
+                    Some(ast::ElseBranch::Block(block)) => {
+                        for_each_tail_expr(&ast::Expr::BlockExpr(block), cb);
+                        break;
+                    }
+                    None => break,
+                }
+            }
+        }
+        ast::Expr::LoopExpr(l) => {
+            for_each_break_expr(l.label(), l.loop_body().and_then(|it| it.stmt_list()), &mut |b| {
+                cb(&ast::Expr::BreakExpr(b))
+            })
+        }
+        ast::Expr::MatchExpr(m) => {
+            if let Some(arms) = m.match_arm_list() {
+                arms.arms().filter_map(|arm| arm.expr()).for_each(|e| for_each_tail_expr(&e, cb));
+            }
+        }
+        ast::Expr::ArrayExpr(_)
+        | ast::Expr::AwaitExpr(_)
+        | ast::Expr::BinExpr(_)
+        | ast::Expr::BoxExpr(_)
+        | ast::Expr::BreakExpr(_)
+        | ast::Expr::CallExpr(_)
+        | ast::Expr::CastExpr(_)
+        | ast::Expr::ClosureExpr(_)
+        | ast::Expr::ContinueExpr(_)
+        | ast::Expr::FieldExpr(_)
+        | ast::Expr::ForExpr(_)
+        | ast::Expr::IndexExpr(_)
+        | ast::Expr::Literal(_)
+        | ast::Expr::MacroCall(_)
+        | ast::Expr::MacroStmts(_)
+        | ast::Expr::MethodCallExpr(_)
+        | ast::Expr::ParenExpr(_)
+        | ast::Expr::PathExpr(_)
+        | ast::Expr::PrefixExpr(_)
+        | ast::Expr::RangeExpr(_)
+        | ast::Expr::RecordExpr(_)
+        | ast::Expr::RefExpr(_)
+        | ast::Expr::ReturnExpr(_)
+        | ast::Expr::TryExpr(_)
+        | ast::Expr::TupleExpr(_)
+        | ast::Expr::WhileExpr(_)
+        | ast::Expr::LetExpr(_)
+        | ast::Expr::UnderscoreExpr(_)
+        | ast::Expr::YieldExpr(_) => cb(expr),
+    }
+}
+
+pub fn for_each_break_and_continue_expr(
+    label: Option<ast::Label>,
+    body: Option<ast::StmtList>,
+    cb: &mut dyn FnMut(ast::Expr),
+) {
+    let label = label.and_then(|lbl| lbl.lifetime());
+    if let Some(b) = body {
+        let tree_depth_iterator = TreeWithDepthIterator::new(b);
+        for (expr, depth) in tree_depth_iterator {
+            match expr {
+                ast::Expr::BreakExpr(b)
+                    if (depth == 0 && b.lifetime().is_none())
+                        || eq_label_lt(&label, &b.lifetime()) =>
+                {
+                    cb(ast::Expr::BreakExpr(b));
+                }
+                ast::Expr::ContinueExpr(c)
+                    if (depth == 0 && c.lifetime().is_none())
+                        || eq_label_lt(&label, &c.lifetime()) =>
+                {
+                    cb(ast::Expr::ContinueExpr(c));
+                }
+                _ => (),
+            }
+        }
+    }
+}
+
+fn for_each_break_expr(
+    label: Option<ast::Label>,
+    body: Option<ast::StmtList>,
+    cb: &mut dyn FnMut(ast::BreakExpr),
+) {
+    let label = label.and_then(|lbl| lbl.lifetime());
+    if let Some(b) = body {
+        let tree_depth_iterator = TreeWithDepthIterator::new(b);
+        for (expr, depth) in tree_depth_iterator {
+            match expr {
+                ast::Expr::BreakExpr(b)
+                    if (depth == 0 && b.lifetime().is_none())
+                        || eq_label_lt(&label, &b.lifetime()) =>
+                {
+                    cb(b);
+                }
+                _ => (),
+            }
+        }
+    }
+}
+
+fn eq_label_lt(lt1: &Option<ast::Lifetime>, lt2: &Option<ast::Lifetime>) -> bool {
+    lt1.as_ref().zip(lt2.as_ref()).map_or(false, |(lt, lbl)| lt.text() == lbl.text())
+}
+
+struct TreeWithDepthIterator {
+    preorder: Preorder<RustLanguage>,
+    depth: u32,
+}
+
+impl TreeWithDepthIterator {
+    fn new(body: ast::StmtList) -> Self {
+        let preorder = body.syntax().preorder();
+        Self { preorder, depth: 0 }
+    }
+}
+
+impl<'a> Iterator for TreeWithDepthIterator {
+    type Item = (ast::Expr, u32);
+
+    fn next(&mut self) -> Option<Self::Item> {
+        while let Some(event) = self.preorder.find_map(|ev| match ev {
+            WalkEvent::Enter(it) => ast::Expr::cast(it).map(WalkEvent::Enter),
+            WalkEvent::Leave(it) => ast::Expr::cast(it).map(WalkEvent::Leave),
+        }) {
+            match event {
+                WalkEvent::Enter(
+                    ast::Expr::LoopExpr(_) | ast::Expr::WhileExpr(_) | ast::Expr::ForExpr(_),
+                ) => {
+                    self.depth += 1;
+                }
+                WalkEvent::Leave(
+                    ast::Expr::LoopExpr(_) | ast::Expr::WhileExpr(_) | ast::Expr::ForExpr(_),
+                ) => {
+                    self.depth -= 1;
+                }
+                WalkEvent::Enter(ast::Expr::BlockExpr(e)) if e.label().is_some() => {
+                    self.depth += 1;
+                }
+                WalkEvent::Leave(ast::Expr::BlockExpr(e)) if e.label().is_some() => {
+                    self.depth -= 1;
+                }
+                WalkEvent::Enter(expr) => return Some((expr, self.depth)),
+                _ => (),
+            }
+        }
+        None
+    }
+}
+
+/// Parses the input token tree as comma separated plain paths.
+pub fn parse_tt_as_comma_sep_paths(input: ast::TokenTree) -> Option<Vec<ast::Path>> {
+    let r_paren = input.r_paren_token();
+    let tokens =
+        input.syntax().children_with_tokens().skip(1).map_while(|it| match it.into_token() {
+            // seeing a keyword means the attribute is unclosed so stop parsing here
+            Some(tok) if tok.kind().is_keyword() => None,
+            // don't include the right token tree parenthesis if it exists
+            tok @ Some(_) if tok == r_paren => None,
+            // only nodes that we can find are other TokenTrees, those are unexpected in this parse though
+            None => None,
+            Some(tok) => Some(tok),
+        });
+    let input_expressions = tokens.into_iter().group_by(|tok| tok.kind() == T![,]);
+    let paths = input_expressions
+        .into_iter()
+        .filter_map(|(is_sep, group)| (!is_sep).then(|| group))
+        .filter_map(|mut tokens| {
+            syntax::hacks::parse_expr_from_str(&tokens.join("")).and_then(|expr| match expr {
+                ast::Expr::PathExpr(it) => it.path(),
+                _ => None,
+            })
+        })
+        .collect();
+    Some(paths)
+}
diff --git a/crates/ide_db/src/tests/sourcegen_lints.rs b/crates/ide_db/src/tests/sourcegen_lints.rs
index 9e2b8b96834..44f8f217951 100644
--- a/crates/ide_db/src/tests/sourcegen_lints.rs
+++ b/crates/ide_db/src/tests/sourcegen_lints.rs
@@ -44,7 +44,7 @@ pub struct LintGroup {
 
     let contents = sourcegen::add_preamble("sourcegen_lints", sourcegen::reformat(contents));
 
-    let destination = project_root().join("crates/ide_db/src/helpers/generated_lints.rs");
+    let destination = project_root().join("crates/ide_db/src/generated/lints.rs");
     sourcegen::ensure_file_contents(destination.as_path(), &contents);
 }
 
diff --git a/crates/ide_db/src/traits.rs b/crates/ide_db/src/traits.rs
index def7a8acaa7..c8cb1a26a87 100644
--- a/crates/ide_db/src/traits.rs
+++ b/crates/ide_db/src/traits.rs
@@ -77,4 +77,147 @@ pub fn get_missing_assoc_items(
 }
 
 #[cfg(test)]
-mod tests;
+mod tests {
+    use base_db::{fixture::ChangeFixture, FilePosition};
+    use expect_test::{expect, Expect};
+    use hir::Semantics;
+    use syntax::ast::{self, AstNode};
+
+    use crate::RootDatabase;
+
+    /// Creates analysis from a multi-file fixture, returns positions marked with $0.
+    pub(crate) fn position(ra_fixture: &str) -> (RootDatabase, FilePosition) {
+        let change_fixture = ChangeFixture::parse(ra_fixture);
+        let mut database = RootDatabase::default();
+        database.apply_change(change_fixture.change);
+        let (file_id, range_or_offset) =
+            change_fixture.file_position.expect("expected a marker ($0)");
+        let offset = range_or_offset.expect_offset();
+        (database, FilePosition { file_id, offset })
+    }
+
+    fn check_trait(ra_fixture: &str, expect: Expect) {
+        let (db, position) = position(ra_fixture);
+        let sema = Semantics::new(&db);
+        let file = sema.parse(position.file_id);
+        let impl_block: ast::Impl =
+            sema.find_node_at_offset_with_descend(file.syntax(), position.offset).unwrap();
+        let trait_ = crate::traits::resolve_target_trait(&sema, &impl_block);
+        let actual = match trait_ {
+            Some(trait_) => trait_.name(&db).to_string(),
+            None => String::new(),
+        };
+        expect.assert_eq(&actual);
+    }
+
+    fn check_missing_assoc(ra_fixture: &str, expect: Expect) {
+        let (db, position) = position(ra_fixture);
+        let sema = Semantics::new(&db);
+        let file = sema.parse(position.file_id);
+        let impl_block: ast::Impl =
+            sema.find_node_at_offset_with_descend(file.syntax(), position.offset).unwrap();
+        let items = crate::traits::get_missing_assoc_items(&sema, &impl_block);
+        let actual = items
+            .into_iter()
+            .map(|item| item.name(&db).unwrap().to_string())
+            .collect::<Vec<_>>()
+            .join("\n");
+        expect.assert_eq(&actual);
+    }
+
+    #[test]
+    fn resolve_trait() {
+        check_trait(
+            r#"
+pub trait Foo {
+    fn bar();
+}
+impl Foo for u8 {
+    $0
+}
+            "#,
+            expect![["Foo"]],
+        );
+        check_trait(
+            r#"
+pub trait Foo {
+    fn bar();
+}
+impl Foo for u8 {
+    fn bar() {
+        fn baz() {
+            $0
+        }
+        baz();
+    }
+}
+            "#,
+            expect![["Foo"]],
+        );
+        check_trait(
+            r#"
+pub trait Foo {
+    fn bar();
+}
+pub struct Bar;
+impl Bar {
+    $0
+}
+            "#,
+            expect![[""]],
+        );
+    }
+
+    #[test]
+    fn missing_assoc_items() {
+        check_missing_assoc(
+            r#"
+pub trait Foo {
+    const FOO: u8;
+    fn bar();
+}
+impl Foo for u8 {
+    $0
+}"#,
+            expect![[r#"
+                FOO
+                bar"#]],
+        );
+
+        check_missing_assoc(
+            r#"
+pub trait Foo {
+    const FOO: u8;
+    fn bar();
+}
+impl Foo for u8 {
+    const FOO: u8 = 10;
+    $0
+}"#,
+            expect![[r#"
+                bar"#]],
+        );
+
+        check_missing_assoc(
+            r#"
+pub trait Foo {
+    const FOO: u8;
+    fn bar();
+}
+impl Foo for u8 {
+    const FOO: u8 = 10;
+    fn bar() {$0}
+}"#,
+            expect![[r#""#]],
+        );
+
+        check_missing_assoc(
+            r#"
+pub struct Foo;
+impl Foo {
+    fn bar() {$0}
+}"#,
+            expect![[r#""#]],
+        );
+    }
+}
diff --git a/crates/ide_db/src/traits/tests.rs b/crates/ide_db/src/traits/tests.rs
deleted file mode 100644
index de994407c7c..00000000000
--- a/crates/ide_db/src/traits/tests.rs
+++ /dev/null
@@ -1,141 +0,0 @@
-use base_db::{fixture::ChangeFixture, FilePosition};
-use expect_test::{expect, Expect};
-use hir::Semantics;
-use syntax::ast::{self, AstNode};
-
-use crate::RootDatabase;
-
-/// Creates analysis from a multi-file fixture, returns positions marked with $0.
-pub(crate) fn position(ra_fixture: &str) -> (RootDatabase, FilePosition) {
-    let change_fixture = ChangeFixture::parse(ra_fixture);
-    let mut database = RootDatabase::default();
-    database.apply_change(change_fixture.change);
-    let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker ($0)");
-    let offset = range_or_offset.expect_offset();
-    (database, FilePosition { file_id, offset })
-}
-
-fn check_trait(ra_fixture: &str, expect: Expect) {
-    let (db, position) = position(ra_fixture);
-    let sema = Semantics::new(&db);
-    let file = sema.parse(position.file_id);
-    let impl_block: ast::Impl =
-        sema.find_node_at_offset_with_descend(file.syntax(), position.offset).unwrap();
-    let trait_ = crate::traits::resolve_target_trait(&sema, &impl_block);
-    let actual = match trait_ {
-        Some(trait_) => trait_.name(&db).to_string(),
-        None => String::new(),
-    };
-    expect.assert_eq(&actual);
-}
-
-fn check_missing_assoc(ra_fixture: &str, expect: Expect) {
-    let (db, position) = position(ra_fixture);
-    let sema = Semantics::new(&db);
-    let file = sema.parse(position.file_id);
-    let impl_block: ast::Impl =
-        sema.find_node_at_offset_with_descend(file.syntax(), position.offset).unwrap();
-    let items = crate::traits::get_missing_assoc_items(&sema, &impl_block);
-    let actual = items
-        .into_iter()
-        .map(|item| item.name(&db).unwrap().to_string())
-        .collect::<Vec<_>>()
-        .join("\n");
-    expect.assert_eq(&actual);
-}
-
-#[test]
-fn resolve_trait() {
-    check_trait(
-        r#"
-pub trait Foo {
-    fn bar();
-}
-impl Foo for u8 {
-    $0
-}
-            "#,
-        expect![["Foo"]],
-    );
-    check_trait(
-        r#"
-pub trait Foo {
-    fn bar();
-}
-impl Foo for u8 {
-    fn bar() {
-        fn baz() {
-            $0
-        }
-        baz();
-    }
-}
-            "#,
-        expect![["Foo"]],
-    );
-    check_trait(
-        r#"
-pub trait Foo {
-    fn bar();
-}
-pub struct Bar;
-impl Bar {
-    $0
-}
-            "#,
-        expect![[""]],
-    );
-}
-
-#[test]
-fn missing_assoc_items() {
-    check_missing_assoc(
-        r#"
-pub trait Foo {
-    const FOO: u8;
-    fn bar();
-}
-impl Foo for u8 {
-    $0
-}"#,
-        expect![[r#"
-                FOO
-                bar"#]],
-    );
-
-    check_missing_assoc(
-        r#"
-pub trait Foo {
-    const FOO: u8;
-    fn bar();
-}
-impl Foo for u8 {
-    const FOO: u8 = 10;
-    $0
-}"#,
-        expect![[r#"
-                bar"#]],
-    );
-
-    check_missing_assoc(
-        r#"
-pub trait Foo {
-    const FOO: u8;
-    fn bar();
-}
-impl Foo for u8 {
-    const FOO: u8 = 10;
-    fn bar() {$0}
-}"#,
-        expect![[r#""#]],
-    );
-
-    check_missing_assoc(
-        r#"
-pub struct Foo;
-impl Foo {
-    fn bar() {$0}
-}"#,
-        expect![[r#""#]],
-    );
-}
diff --git a/crates/ide_diagnostics/src/handlers/missing_fields.rs b/crates/ide_diagnostics/src/handlers/missing_fields.rs
index 186bfc3d584..8b3c22fffce 100644
--- a/crates/ide_diagnostics/src/handlers/missing_fields.rs
+++ b/crates/ide_diagnostics/src/handlers/missing_fields.rs
@@ -3,7 +3,7 @@ use hir::{
     db::{AstDatabase, HirDatabase},
     known, AssocItem, HirDisplay, InFile, Type,
 };
-use ide_db::{assists::Assist, helpers::FamousDefs, source_change::SourceChange};
+use ide_db::{assists::Assist, famous_defs::FamousDefs, source_change::SourceChange};
 use rustc_hash::FxHashMap;
 use stdx::format_to;
 use syntax::{
diff --git a/crates/ide_diagnostics/src/handlers/missing_ok_or_some_in_tail_expr.rs b/crates/ide_diagnostics/src/handlers/missing_ok_or_some_in_tail_expr.rs
index 74a72654646..d5635ba8baf 100644
--- a/crates/ide_diagnostics/src/handlers/missing_ok_or_some_in_tail_expr.rs
+++ b/crates/ide_diagnostics/src/handlers/missing_ok_or_some_in_tail_expr.rs
@@ -1,5 +1,7 @@
 use hir::{db::AstDatabase, TypeInfo};
-use ide_db::{assists::Assist, helpers::for_each_tail_expr, source_change::SourceChange};
+use ide_db::{
+    assists::Assist, source_change::SourceChange, syntax_helpers::node_ext::for_each_tail_expr,
+};
 use syntax::AstNode;
 use text_edit::TextEdit;
 
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index af779ee000d..1194fd9fafb 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -14,8 +14,8 @@ use ide::{
     AssistConfig, CompletionConfig, DiagnosticsConfig, ExprFillDefaultMode, HighlightRelatedConfig,
     HoverConfig, HoverDocFormat, InlayHintsConfig, JoinLinesConfig, Snippet, SnippetScope,
 };
-use ide_db::helpers::{
-    insert_use::{ImportGranularity, InsertUseConfig, PrefixKind},
+use ide_db::{
+    imports::insert_use::{ImportGranularity, InsertUseConfig, PrefixKind},
     SnippetCap,
 };
 use lsp_types::{ClientCapabilities, MarkupKind};
diff --git a/crates/rust-analyzer/src/integrated_benchmarks.rs b/crates/rust-analyzer/src/integrated_benchmarks.rs
index a910a910bb2..b1f8958e92a 100644
--- a/crates/rust-analyzer/src/integrated_benchmarks.rs
+++ b/crates/rust-analyzer/src/integrated_benchmarks.rs
@@ -13,8 +13,8 @@
 use std::sync::Arc;
 
 use ide::{Change, CompletionConfig, FilePosition, TextSize};
-use ide_db::helpers::{
-    insert_use::{ImportGranularity, InsertUseConfig},
+use ide_db::{
+    imports::insert_use::{ImportGranularity, InsertUseConfig},
     SnippetCap,
 };
 use project_model::CargoConfig;
diff --git a/crates/rust-analyzer/src/markdown.rs b/crates/rust-analyzer/src/markdown.rs
index 59c904f86e7..e1ff0f0178b 100644
--- a/crates/rust-analyzer/src/markdown.rs
+++ b/crates/rust-analyzer/src/markdown.rs
@@ -1,5 +1,5 @@
 //! Transforms markdown
-use ide_db::helpers::rust_doc::is_rust_fence;
+use ide_db::rust_doc::is_rust_fence;
 
 const RUSTDOC_FENCE: &str = "```";
 
diff --git a/crates/rust-analyzer/tests/slow-tests/tidy.rs b/crates/rust-analyzer/tests/slow-tests/tidy.rs
index 37be41754eb..2b51e7fecbb 100644
--- a/crates/rust-analyzer/tests/slow-tests/tidy.rs
+++ b/crates/rust-analyzer/tests/slow-tests/tidy.rs
@@ -188,7 +188,7 @@ https://github.blog/2015-06-08-how-to-undo-almost-anything-with-git/#redo-after-
 fn deny_clippy(path: &Path, text: &str) {
     let ignore = &[
         // The documentation in string literals may contain anything for its own purposes
-        "ide_db/src/helpers/generated_lints.rs",
+        "ide_db/src/generated/lints.rs",
         // The tests test clippy lint hovers
         "ide/src/hover/tests.rs",
         // The tests test clippy lint completions
@@ -279,7 +279,7 @@ fn check_todo(path: &Path, text: &str) {
         // `ast::make`.
         "ast/make.rs",
         // The documentation in string literals may contain anything for its own purposes
-        "ide_db/src/helpers/generated_lints.rs",
+        "ide_db/src/generated/lints.rs",
         "ide_assists/src/utils/gen_trait_fn_body.rs",
         "ide_assists/src/tests/generated.rs",
         // The tests for missing fields
@@ -315,7 +315,7 @@ fn check_dbg(path: &Path, text: &str) {
         "ide_completion/src/tests/proc_macros.rs",
         // The documentation in string literals may contain anything for its own purposes
         "ide_completion/src/lib.rs",
-        "ide_db/src/helpers/generated_lints.rs",
+        "ide_db/src/generated/lints.rs",
         // test for doc test for remove_dbg
         "src/tests/generated.rs",
     ];