about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2024-05-22 13:49:56 +0200
committerLukas Wirth <lukastw97@gmail.com>2024-05-22 14:05:24 +0200
commit5992af6506088db3f907744b5a09e0ae99e83de4 (patch)
tree8e2c89bf97a428fb0ea741c41d972264aedd6637
parent9f4b6517208d77556a919789ed285e0c6f67bbb5 (diff)
downloadrust-5992af6506088db3f907744b5a09e0ae99e83de4.tar.gz
rust-5992af6506088db3f907744b5a09e0ae99e83de4.zip
fix: Fix general find-path inconsistencies
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/find_path.rs281
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/import_map.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/lib.rs23
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres.rs9
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/resolver.rs12
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/display.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/lib.rs9
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs15
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/lib.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs18
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs2
32 files changed, 242 insertions, 193 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs
index 4e57845a694..68e0a8bc693 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs
@@ -1,6 +1,9 @@
 //! An algorithm to find a path to refer to a certain item.
 
-use std::{cmp::Ordering, iter};
+use std::{
+    cmp::Ordering,
+    iter::{self, once},
+};
 
 use hir_expand::{
     name::{known, AsName, Name},
@@ -14,7 +17,7 @@ use crate::{
     nameres::DefMap,
     path::{ModPath, PathKind},
     visibility::{Visibility, VisibilityExplicitness},
-    CrateRootModuleId, ModuleDefId, ModuleId,
+    ModuleDefId, ModuleId,
 };
 
 /// Find a path that can be used to refer to a certain item. This can depend on
@@ -23,26 +26,20 @@ pub fn find_path(
     db: &dyn DefDatabase,
     item: ItemInNs,
     from: ModuleId,
-    prefer_no_std: bool,
-    prefer_prelude: bool,
-) -> Option<ModPath> {
-    let _p = tracing::span!(tracing::Level::INFO, "find_path").entered();
-    find_path_inner(FindPathCtx { db, prefixed: None, prefer_no_std, prefer_prelude }, item, from)
-}
-
-/// Find a path that can be used to refer to a certain item. This can depend on
-/// *from where* you're referring to the item, hence the `from` parameter.
-pub fn find_path_prefixed(
-    db: &dyn DefDatabase,
-    item: ItemInNs,
-    from: ModuleId,
     prefix_kind: PrefixKind,
+    ignore_local_imports: bool,
     prefer_no_std: bool,
     prefer_prelude: bool,
 ) -> Option<ModPath> {
-    let _p = tracing::span!(tracing::Level::INFO, "find_path_prefixed").entered();
+    let _p = tracing::span!(tracing::Level::INFO, "find_path").entered();
     find_path_inner(
-        FindPathCtx { db, prefixed: Some(prefix_kind), prefer_no_std, prefer_prelude },
+        FindPathCtx {
+            db,
+            prefix: prefix_kind,
+            prefer_no_std,
+            prefer_prelude,
+            ignore_local_imports,
+        },
         item,
         from,
     )
@@ -70,7 +67,7 @@ pub enum PrefixKind {
     /// This is the same as plain, just that paths will start with `self` prepended if the path
     /// starts with an identifier that is not a crate.
     BySelf,
-    /// Causes paths to ignore imports in the local module.
+    /// Causes paths to not use a self, super or crate prefix.
     Plain,
     /// Causes paths to start with `crate` where applicable, effectively forcing paths to be absolute.
     ByCrate,
@@ -78,37 +75,33 @@ pub enum PrefixKind {
 
 impl PrefixKind {
     #[inline]
-    fn prefix(self) -> PathKind {
+    fn path_kind(self) -> PathKind {
         match self {
             PrefixKind::BySelf => PathKind::Super(0),
             PrefixKind::Plain => PathKind::Plain,
             PrefixKind::ByCrate => PathKind::Crate,
         }
     }
-
-    #[inline]
-    fn is_absolute(&self) -> bool {
-        self == &PrefixKind::ByCrate
-    }
 }
 
 #[derive(Copy, Clone)]
 struct FindPathCtx<'db> {
     db: &'db dyn DefDatabase,
-    prefixed: Option<PrefixKind>,
+    prefix: PrefixKind,
     prefer_no_std: bool,
     prefer_prelude: bool,
+    ignore_local_imports: bool,
 }
 
 /// Attempts to find a path to refer to the given `item` visible from the `from` ModuleId
 fn find_path_inner(ctx: FindPathCtx<'_>, item: ItemInNs, from: ModuleId) -> Option<ModPath> {
     // - if the item is a builtin, it's in scope
     if let ItemInNs::Types(ModuleDefId::BuiltinType(builtin)) = item {
-        return Some(ModPath::from_segments(PathKind::Plain, Some(builtin.as_name())));
+        return Some(ModPath::from_segments(PathKind::Plain, once(builtin.as_name())));
     }
 
     let def_map = from.def_map(ctx.db);
-    let crate_root = def_map.crate_root();
+    let crate_root = from.derive_crate_root();
     // - if the item is a module, jump straight to module search
     if let ItemInNs::Types(ModuleDefId::ModuleId(module_id)) = item {
         let mut visited_modules = FxHashSet::default();
@@ -119,7 +112,6 @@ fn find_path_inner(ctx: FindPathCtx<'_>, item: ItemInNs, from: ModuleId) -> Opti
             },
             &def_map,
             &mut visited_modules,
-            crate_root,
             from,
             module_id,
             MAX_PATH_LEN,
@@ -127,11 +119,20 @@ fn find_path_inner(ctx: FindPathCtx<'_>, item: ItemInNs, from: ModuleId) -> Opti
         .map(|(item, _)| item);
     }
 
-    // - if the item is already in scope, return the name under which it is
-    let scope_name = find_in_scope(ctx.db, &def_map, from, item);
-    if ctx.prefixed.is_none() {
+    let prefix = if item.module(ctx.db).is_some_and(|it| it.is_within_block()) {
+        PrefixKind::Plain
+    } else {
+        ctx.prefix
+    };
+    let may_be_in_scope = match prefix {
+        PrefixKind::Plain | PrefixKind::BySelf => true,
+        PrefixKind::ByCrate => from.is_crate_root(),
+    };
+    if may_be_in_scope {
+        // - if the item is already in scope, return the name under which it is
+        let scope_name = find_in_scope(ctx.db, &def_map, from, item, ctx.ignore_local_imports);
         if let Some(scope_name) = scope_name {
-            return Some(ModPath::from_segments(PathKind::Plain, Some(scope_name)));
+            return Some(ModPath::from_segments(prefix.path_kind(), Some(scope_name)));
         }
     }
 
@@ -164,11 +165,9 @@ fn find_path_inner(ctx: FindPathCtx<'_>, item: ItemInNs, from: ModuleId) -> Opti
         },
         &def_map,
         &mut visited_modules,
-        crate_root,
         MAX_PATH_LEN,
         item,
         from,
-        scope_name,
     )
     .map(|(item, _)| item)
 }
@@ -178,7 +177,6 @@ fn find_path_for_module(
     ctx: FindPathCtx<'_>,
     def_map: &DefMap,
     visited_modules: &mut FxHashSet<ModuleId>,
-    crate_root: CrateRootModuleId,
     from: ModuleId,
     module_id: ModuleId,
     max_len: usize,
@@ -187,38 +185,25 @@ fn find_path_for_module(
         return None;
     }
 
-    // Base cases:
-    // - if the item is already in scope, return the name under which it is
-    let scope_name = find_in_scope(ctx.db, def_map, from, ItemInNs::Types(module_id.into()));
-    if ctx.prefixed.is_none() {
-        if let Some(scope_name) = scope_name {
-            return Some((ModPath::from_segments(PathKind::Plain, Some(scope_name)), Stable));
-        }
-    }
-
+    let is_crate_root = module_id.as_crate_root();
     // - if the item is the crate root, return `crate`
-    if module_id == crate_root {
+    if is_crate_root.is_some_and(|it| it == from.derive_crate_root()) {
         return Some((ModPath::from_segments(PathKind::Crate, None), Stable));
     }
 
-    // - if relative paths are fine, check if we are searching for a parent
-    if ctx.prefixed.filter(PrefixKind::is_absolute).is_none() {
-        if let modpath @ Some(_) = find_self_super(def_map, module_id, from) {
-            return modpath.zip(Some(Stable));
-        }
-    }
-
+    let root_def_map = from.derive_crate_root().def_map(ctx.db);
     // - if the item is the crate root of a dependency crate, return the name from the extern prelude
-    let root_def_map = crate_root.def_map(ctx.db);
-    for (name, (def_id, _extern_crate)) in root_def_map.extern_prelude() {
-        if module_id == def_id {
-            let name = scope_name.unwrap_or_else(|| name.clone());
-
+    if let Some(crate_root) = is_crate_root {
+        // rev here so we prefer looking at renamed extern decls first
+        for (name, (def_id, _extern_crate)) in root_def_map.extern_prelude().rev() {
+            if crate_root != def_id {
+                continue;
+            }
             let name_already_occupied_in_type_ns = def_map
                 .with_ancestor_maps(ctx.db, from.local_id, &mut |def_map, local_id| {
                     def_map[local_id]
                         .scope
-                        .type_(&name)
+                        .type_(name)
                         .filter(|&(id, _)| id != ModuleDefId::ModuleId(def_id.into()))
                 })
                 .is_some();
@@ -228,24 +213,48 @@ fn find_path_for_module(
             } else {
                 PathKind::Plain
             };
-            return Some((ModPath::from_segments(kind, Some(name)), Stable));
+            return Some((ModPath::from_segments(kind, once(name.clone())), Stable));
+        }
+    }
+    let prefix = if module_id.is_within_block() { PrefixKind::Plain } else { ctx.prefix };
+    let may_be_in_scope = match prefix {
+        PrefixKind::Plain | PrefixKind::BySelf => true,
+        PrefixKind::ByCrate => from.is_crate_root(),
+    };
+    if may_be_in_scope {
+        let scope_name = find_in_scope(
+            ctx.db,
+            def_map,
+            from,
+            ItemInNs::Types(module_id.into()),
+            ctx.ignore_local_imports,
+        );
+        if let Some(scope_name) = scope_name {
+            // - if the item is already in scope, return the name under which it is
+            return Some((ModPath::from_segments(prefix.path_kind(), once(scope_name)), Stable));
         }
     }
 
-    if let value @ Some(_) =
+    // - if the module can be referenced as self, super or crate, do that
+    if let Some(mod_path) = is_kw_kind_relative_to_from(def_map, module_id, from) {
+        if ctx.prefix != PrefixKind::ByCrate || mod_path.kind == PathKind::Crate {
+            return Some((mod_path, Stable));
+        }
+    }
+
+    // - if the module is in the prelude, return it by that path
+    if let Some(mod_path) =
         find_in_prelude(ctx.db, &root_def_map, def_map, ItemInNs::Types(module_id.into()), from)
     {
-        return value.zip(Some(Stable));
+        return Some((mod_path, Stable));
     }
     calculate_best_path(
         ctx,
         def_map,
         visited_modules,
-        crate_root,
         max_len,
         ItemInNs::Types(module_id.into()),
         from,
-        scope_name,
     )
 }
 
@@ -255,9 +264,13 @@ fn find_in_scope(
     def_map: &DefMap,
     from: ModuleId,
     item: ItemInNs,
+    ignore_local_imports: bool,
 ) -> Option<Name> {
+    // FIXME: We could have multiple applicable names here, but we currently only return the first
     def_map.with_ancestor_maps(db, from.local_id, &mut |def_map, local_id| {
-        def_map[local_id].scope.names_of(item, |name, _, _| Some(name.clone()))
+        def_map[local_id].scope.names_of(item, |name, _, declared| {
+            (declared || !ignore_local_imports).then(|| name.clone())
+        })
     })
 }
 
@@ -292,21 +305,32 @@ fn find_in_prelude(
         });
 
     if found_and_same_def.unwrap_or(true) {
-        Some(ModPath::from_segments(PathKind::Plain, Some(name.clone())))
+        Some(ModPath::from_segments(PathKind::Plain, once(name.clone())))
     } else {
         None
     }
 }
 
-fn find_self_super(def_map: &DefMap, item: ModuleId, from: ModuleId) -> Option<ModPath> {
+fn is_kw_kind_relative_to_from(
+    def_map: &DefMap,
+    item: ModuleId,
+    from: ModuleId,
+) -> Option<ModPath> {
+    if item.krate != from.krate || item.is_within_block() || from.is_within_block() {
+        return None;
+    }
+    let item = item.local_id;
+    let from = from.local_id;
     if item == from {
         // - if the item is the module we're in, use `self`
         Some(ModPath::from_segments(PathKind::Super(0), None))
-    } else if let Some(parent_id) = def_map[from.local_id].parent {
-        // - if the item is the parent module, use `super` (this is not used recursively, since `super::super` is ugly)
-        let parent_id = def_map.module_id(parent_id);
+    } else if let Some(parent_id) = def_map[from].parent {
         if item == parent_id {
-            Some(ModPath::from_segments(PathKind::Super(1), None))
+            // - if the item is the parent module, use `super` (this is not used recursively, since `super::super` is ugly)
+            Some(ModPath::from_segments(
+                if parent_id == DefMap::ROOT { PathKind::Crate } else { PathKind::Super(1) },
+                None,
+            ))
         } else {
             None
         }
@@ -320,11 +344,9 @@ fn calculate_best_path(
     ctx: FindPathCtx<'_>,
     def_map: &DefMap,
     visited_modules: &mut FxHashSet<ModuleId>,
-    crate_root: CrateRootModuleId,
     max_len: usize,
     item: ItemInNs,
     from: ModuleId,
-    scope_name: Option<Name>,
 ) -> Option<(ModPath, Stability)> {
     if max_len <= 1 {
         return None;
@@ -346,14 +368,12 @@ fn calculate_best_path(
         // dependency in this case.
         for (module_id, name) in find_local_import_locations(ctx.db, item, from) {
             if !visited_modules.insert(module_id) {
-                cov_mark::hit!(recursive_imports);
                 continue;
             }
             if let Some(mut path) = find_path_for_module(
                 ctx,
                 def_map,
                 visited_modules,
-                crate_root,
                 from,
                 module_id,
                 best_path_len - 1,
@@ -390,7 +410,6 @@ fn calculate_best_path(
                     ctx,
                     def_map,
                     visited_modules,
-                    crate_root,
                     from,
                     info.container,
                     max_len - 1,
@@ -418,19 +437,7 @@ fn calculate_best_path(
             }
         }
     }
-    let mut prefixed = ctx.prefixed;
-    if let Some(module) = item.module(ctx.db) {
-        if module.containing_block().is_some() && ctx.prefixed.is_some() {
-            cov_mark::hit!(prefixed_in_block_expression);
-            prefixed = Some(PrefixKind::Plain);
-        }
-    }
-    match prefixed.map(PrefixKind::prefix) {
-        Some(prefix) => best_path.or_else(|| {
-            scope_name.map(|scope_name| (ModPath::from_segments(prefix, Some(scope_name)), Stable))
-        }),
-        None => best_path,
-    }
+    best_path
 }
 
 /// Select the best (most relevant) path between two paths.
@@ -535,7 +542,6 @@ fn find_local_import_locations(
         if !seen.insert(module) {
             continue; // already processed this module
         }
-
         let ext_def_map;
         let data = if module.krate == from.krate {
             if module.block.is_some() {
@@ -571,7 +577,7 @@ fn find_local_import_locations(
                 // what the user wants; and if this module can import
                 // the item and we're a submodule of it, so can we.
                 // Also this keeps the cached data smaller.
-                if is_pub_or_explicit || declared {
+                if declared || is_pub_or_explicit {
                     locations.push((module, name.clone()));
                 }
             }
@@ -605,8 +611,9 @@ mod tests {
     fn check_found_path_(
         ra_fixture: &str,
         path: &str,
-        prefix_kind: Option<PrefixKind>,
+        prefix_kind: PrefixKind,
         prefer_prelude: bool,
+        ignore_local_imports: bool,
     ) {
         let (db, pos) = TestDB::with_position(ra_fixture);
         let module = db.module_at_position(pos);
@@ -628,43 +635,51 @@ mod tests {
                 crate::item_scope::BuiltinShadowMode::Module,
                 None,
             )
-            .0
+            .0;
+        let resolved = resolved
             .take_types()
-            .expect("path does not resolve to a type");
+            .map(ItemInNs::Types)
+            .or_else(|| resolved.take_values().map(ItemInNs::Values))
+            .expect("path does not resolve to a type or value");
 
         let found_path = find_path_inner(
-            FindPathCtx { prefer_no_std: false, db: &db, prefixed: prefix_kind, prefer_prelude },
-            ItemInNs::Types(resolved),
+            FindPathCtx {
+                prefer_no_std: false,
+                db: &db,
+                prefix: prefix_kind,
+                prefer_prelude,
+                ignore_local_imports,
+            },
+            resolved,
             module,
         );
-        assert_eq!(found_path, Some(mod_path), "on kind: {prefix_kind:?}");
+        assert_eq!(found_path, Some(mod_path), "on kind: {prefix_kind:?} ({ignore_local_imports})");
     }
 
-    #[track_caller]
     fn check_found_path(
         ra_fixture: &str,
-        unprefixed: &str,
-        prefixed: &str,
-        absolute: &str,
-        self_prefixed: &str,
+        plain_non_local: &str,
+        plain: &str,
+        by_crate: &str,
+        by_self: &str,
     ) {
-        check_found_path_(ra_fixture, unprefixed, None, false);
-        check_found_path_(ra_fixture, prefixed, Some(PrefixKind::Plain), false);
-        check_found_path_(ra_fixture, absolute, Some(PrefixKind::ByCrate), false);
-        check_found_path_(ra_fixture, self_prefixed, Some(PrefixKind::BySelf), false);
+        check_found_path_(ra_fixture, plain_non_local, PrefixKind::Plain, false, true);
+        check_found_path_(ra_fixture, plain, PrefixKind::Plain, false, false);
+        check_found_path_(ra_fixture, by_crate, PrefixKind::ByCrate, false, false);
+        check_found_path_(ra_fixture, by_self, PrefixKind::BySelf, false, false);
     }
 
     fn check_found_path_prelude(
         ra_fixture: &str,
-        unprefixed: &str,
-        prefixed: &str,
-        absolute: &str,
-        self_prefixed: &str,
+        plain_non_local: &str,
+        plain: &str,
+        by_crate: &str,
+        by_self: &str,
     ) {
-        check_found_path_(ra_fixture, unprefixed, None, true);
-        check_found_path_(ra_fixture, prefixed, Some(PrefixKind::Plain), true);
-        check_found_path_(ra_fixture, absolute, Some(PrefixKind::ByCrate), true);
-        check_found_path_(ra_fixture, self_prefixed, Some(PrefixKind::BySelf), true);
+        check_found_path_(ra_fixture, plain_non_local, PrefixKind::Plain, true, true);
+        check_found_path_(ra_fixture, plain, PrefixKind::Plain, true, false);
+        check_found_path_(ra_fixture, by_crate, PrefixKind::ByCrate, true, false);
+        check_found_path_(ra_fixture, by_self, PrefixKind::BySelf, true, false);
     }
 
     #[test]
@@ -831,10 +846,10 @@ pub mod ast {
     }
 }
         "#,
-            "ast::ModuleItem",
-            "syntax::ast::ModuleItem",
-            "syntax::ast::ModuleItem",
             "syntax::ast::ModuleItem",
+            "ast::ModuleItem",
+            "crate::ast::ModuleItem",
+            "self::ast::ModuleItem",
         );
 
         check_found_path(
@@ -965,8 +980,8 @@ pub mod prelude {
 "#,
             "S",
             "S",
-            "S",
-            "S",
+            "crate::S",
+            "self::S",
         );
     }
 
@@ -1271,12 +1286,11 @@ fn main() {
 
     #[test]
     fn inner_items_from_inner_module() {
-        cov_mark::check!(prefixed_in_block_expression);
         check_found_path(
             r#"
 fn main() {
     mod module {
-        struct Struct {}
+        pub struct Struct {}
     }
     {
         $0
@@ -1303,11 +1317,10 @@ fn main() {
     $0
 }
             "#,
-            // FIXME: these could use fewer/better prefixes
+            "module::CompleteMe",
             "module::CompleteMe",
             "crate::module::CompleteMe",
-            "crate::module::CompleteMe",
-            "crate::module::CompleteMe",
+            "self::module::CompleteMe",
         )
     }
 
@@ -1358,7 +1371,6 @@ mod bar {
 
     #[test]
     fn recursive_pub_mod_reexport() {
-        cov_mark::check!(recursive_imports);
         check_found_path(
             r#"
 fn main() {
@@ -1587,4 +1599,25 @@ pub mod prelude {
             "petgraph::graph::NodeIndex",
         );
     }
+
+    #[test]
+    fn regression_17271() {
+        check_found_path(
+            r#"
+//- /lib.rs crate:main
+mod foo;
+
+//- /foo.rs
+mod bar;
+
+pub fn b() {$0}
+//- /foo/bar.rs
+pub fn c() {}
+"#,
+            "bar::c",
+            "bar::c",
+            "crate::foo::bar::c",
+            "self::bar::c",
+        );
+    }
 }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs
index faa1eed15a4..6e40293dbf8 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs
@@ -1,13 +1,12 @@
 //! A map of all publicly exported items in a crate.
 
-use std::{fmt, hash::BuildHasherDefault};
+use std::fmt;
 
 use base_db::CrateId;
 use fst::{raw::IndexedValue, Automaton, Streamer};
 use hir_expand::name::Name;
-use indexmap::IndexMap;
 use itertools::Itertools;
-use rustc_hash::{FxHashSet, FxHasher};
+use rustc_hash::FxHashSet;
 use smallvec::SmallVec;
 use stdx::{format_to, TupleExt};
 use triomphe::Arc;
@@ -17,7 +16,7 @@ use crate::{
     item_scope::{ImportOrExternCrate, ItemInNs},
     nameres::DefMap,
     visibility::Visibility,
-    AssocItemId, ModuleDefId, ModuleId, TraitId,
+    AssocItemId, FxIndexMap, ModuleDefId, ModuleId, TraitId,
 };
 
 /// Item import details stored in the `ImportMap`.
@@ -58,7 +57,6 @@ enum IsTraitAssocItem {
     No,
 }
 
-type FxIndexMap<K, V> = IndexMap<K, V, BuildHasherDefault<FxHasher>>;
 type ImportMapIndex = FxIndexMap<ItemInNs, (SmallVec<[ImportInfo; 1]>, IsTraitAssocItem)>;
 
 impl ImportMap {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs
index 54cd57110ea..9c7dfa05b0e 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs
@@ -295,7 +295,7 @@ impl ItemScope {
     pub(crate) fn names_of<T>(
         &self,
         item: ItemInNs,
-        mut cb: impl FnMut(&Name, Visibility, bool) -> Option<T>,
+        mut cb: impl FnMut(&Name, Visibility, /*declared*/ bool) -> Option<T>,
     ) -> Option<T> {
         match item {
             ItemInNs::Macros(def) => self
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
index 88d4572196c..ca8cc1c3ead 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
@@ -106,6 +106,9 @@ use crate::{
     },
 };
 
+type FxIndexMap<K, V> =
+    indexmap::IndexMap<K, V, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
+
 #[derive(Debug)]
 pub struct ItemLoc<N: ItemTreeNode> {
     pub container: ModuleId,
@@ -455,6 +458,26 @@ impl ModuleId {
     pub fn is_block_module(self) -> bool {
         self.block.is_some() && self.local_id == DefMap::ROOT
     }
+
+    pub fn is_within_block(self) -> bool {
+        self.block.is_some()
+    }
+
+    pub fn as_crate_root(&self) -> Option<CrateRootModuleId> {
+        if self.local_id == DefMap::ROOT && self.block.is_none() {
+            Some(CrateRootModuleId { krate: self.krate })
+        } else {
+            None
+        }
+    }
+
+    pub fn derive_crate_root(&self) -> CrateRootModuleId {
+        CrateRootModuleId { krate: self.krate }
+    }
+
+    fn is_crate_root(&self) -> bool {
+        self.local_id == DefMap::ROOT && self.block.is_none()
+    }
 }
 
 impl PartialEq<CrateRootModuleId> for ModuleId {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs
index a528c4cc697..a66c0585a36 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs
@@ -81,7 +81,7 @@ use crate::{
     per_ns::PerNs,
     visibility::{Visibility, VisibilityExplicitness},
     AstId, BlockId, BlockLoc, CrateRootModuleId, EnumId, EnumVariantId, ExternCrateId, FunctionId,
-    LocalModuleId, Lookup, MacroExpander, MacroId, ModuleId, ProcMacroId, UseId,
+    FxIndexMap, LocalModuleId, Lookup, MacroExpander, MacroId, ModuleId, ProcMacroId, UseId,
 };
 
 /// Contains the results of (early) name resolution.
@@ -129,7 +129,7 @@ pub struct DefMap {
 #[derive(Clone, Debug, PartialEq, Eq)]
 struct DefMapCrateData {
     /// The extern prelude which contains all root modules of external crates that are in scope.
-    extern_prelude: FxHashMap<Name, (CrateRootModuleId, Option<ExternCrateId>)>,
+    extern_prelude: FxIndexMap<Name, (CrateRootModuleId, Option<ExternCrateId>)>,
 
     /// Side table for resolving derive helpers.
     exported_derives: FxHashMap<MacroDefId, Box<[Name]>>,
@@ -155,7 +155,7 @@ struct DefMapCrateData {
 impl DefMapCrateData {
     fn new(edition: Edition) -> Self {
         Self {
-            extern_prelude: FxHashMap::default(),
+            extern_prelude: FxIndexMap::default(),
             exported_derives: FxHashMap::default(),
             fn_proc_macro_mapping: FxHashMap::default(),
             proc_macro_loading_error: None,
@@ -578,7 +578,8 @@ impl DefMap {
 
     pub(crate) fn extern_prelude(
         &self,
-    ) -> impl Iterator<Item = (&Name, (CrateRootModuleId, Option<ExternCrateId>))> + '_ {
+    ) -> impl DoubleEndedIterator<Item = (&Name, (CrateRootModuleId, Option<ExternCrateId>))> + '_
+    {
         self.data.extern_prelude.iter().map(|(name, &def)| (name, def))
     }
 
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
index 1602b173858..9794963203b 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
@@ -1,12 +1,11 @@
 //! Name resolution façade.
-use std::{fmt, hash::BuildHasherDefault, iter, mem};
+use std::{fmt, iter, mem};
 
 use base_db::CrateId;
 use hir_expand::{
     name::{name, Name},
     MacroDefId,
 };
-use indexmap::IndexMap;
 use intern::Interned;
 use rustc_hash::FxHashSet;
 use smallvec::{smallvec, SmallVec};
@@ -27,10 +26,10 @@ use crate::{
     type_ref::LifetimeRef,
     visibility::{RawVisibility, Visibility},
     AdtId, ConstId, ConstParamId, CrateRootModuleId, DefWithBodyId, EnumId, EnumVariantId,
-    ExternBlockId, ExternCrateId, FunctionId, GenericDefId, GenericParamId, HasModule, ImplId,
-    ItemContainerId, ItemTreeLoc, LifetimeParamId, LocalModuleId, Lookup, Macro2Id, MacroId,
-    MacroRulesId, ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, TraitAliasId, TraitId,
-    TypeAliasId, TypeOrConstParamId, TypeOwnerId, TypeParamId, UseId, VariantId,
+    ExternBlockId, ExternCrateId, FunctionId, FxIndexMap, GenericDefId, GenericParamId, HasModule,
+    ImplId, ItemContainerId, ItemTreeLoc, LifetimeParamId, LocalModuleId, Lookup, Macro2Id,
+    MacroId, MacroRulesId, ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, TraitAliasId,
+    TraitId, TypeAliasId, TypeOrConstParamId, TypeOwnerId, TypeParamId, UseId, VariantId,
 };
 
 #[derive(Debug, Clone)]
@@ -957,7 +956,6 @@ fn to_type_ns(per_ns: PerNs) -> Option<(TypeNs, Option<ImportOrExternCrate>)> {
     Some((res, import))
 }
 
-type FxIndexMap<K, V> = IndexMap<K, V, BuildHasherDefault<rustc_hash::FxHasher>>;
 #[derive(Default)]
 struct ScopeNames {
     map: FxIndexMap<Name, SmallVec<[ScopeDef; 1]>>,
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
index c010f5d22b6..82bbc28884e 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
@@ -13,7 +13,7 @@ use either::Either;
 use hir_def::{
     data::adt::VariantData,
     db::DefDatabase,
-    find_path,
+    find_path::{self, PrefixKind},
     generics::{TypeOrConstParamData, TypeParamProvenance},
     item_scope::ItemInNs,
     lang_item::{LangItem, LangItemTarget},
@@ -999,6 +999,8 @@ impl HirDisplay for Ty {
                             db.upcast(),
                             ItemInNs::Types((*def_id).into()),
                             module_id,
+                            PrefixKind::Plain,
+                            false,
                             false,
                             true,
                         ) {
diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs
index 85f33a10fcb..773ac01e0e3 100644
--- a/src/tools/rust-analyzer/crates/hir/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs
@@ -789,7 +789,7 @@ impl Module {
 
     /// Finds a path that can be used to refer to the given item from within
     /// this module, if possible.
-    pub fn find_use_path(
+    pub fn find_path(
         self,
         db: &dyn DefDatabase,
         item: impl Into<ItemInNs>,
@@ -800,6 +800,8 @@ impl Module {
             db,
             item.into().into(),
             self.into(),
+            PrefixKind::Plain,
+            false,
             prefer_no_std,
             prefer_prelude,
         )
@@ -807,7 +809,7 @@ impl Module {
 
     /// Finds a path that can be used to refer to the given item from within
     /// this module, if possible. This is used for returning import paths for use-statements.
-    pub fn find_use_path_prefixed(
+    pub fn find_use_path(
         self,
         db: &dyn DefDatabase,
         item: impl Into<ItemInNs>,
@@ -815,11 +817,12 @@ impl Module {
         prefer_no_std: bool,
         prefer_prelude: bool,
     ) -> Option<ModPath> {
-        hir_def::find_path::find_path_prefixed(
+        hir_def::find_path::find_path(
             db,
             item.into().into(),
             self.into(),
             prefix_kind,
+            true,
             prefer_no_std,
             prefer_prelude,
         )
diff --git a/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs b/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs
index 9f56a1ee55d..45c0dd8da75 100644
--- a/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs
@@ -33,16 +33,11 @@ fn mod_item_path(
     });
 
     let m = sema_scope.module();
-    match name_hit_count {
-        Some(0..=1) | None => m.find_use_path(db.upcast(), *def, prefer_no_std, prefer_prelude),
-        Some(_) => m.find_use_path_prefixed(
-            db.upcast(),
-            *def,
-            PrefixKind::ByCrate,
-            prefer_no_std,
-            prefer_prelude,
-        ),
-    }
+    let prefix = match name_hit_count {
+        Some(0..=1) | None => PrefixKind::Plain,
+        Some(_) => PrefixKind::ByCrate,
+    };
+    m.find_use_path(db.upcast(), *def, prefix, prefer_no_std, prefer_prelude)
 }
 
 /// Helper function to get path to `ModuleDef` as string
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs
index 5ef374506ec..8eddc562bef 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs
@@ -462,7 +462,7 @@ fn build_pat(
 ) -> Option<ast::Pat> {
     match var {
         ExtendedVariant::Variant(var) => {
-            let path = mod_path_to_ast(&module.find_use_path(
+            let path = mod_path_to_ast(&module.find_path(
                 db,
                 ModuleDef::from(var),
                 prefer_no_std,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs
index fd3a0506ab6..df87e2d0449 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs
@@ -341,7 +341,7 @@ fn augment_references_with_imports(
 
                 let import_scope = ImportScope::find_insert_use_container(name.syntax(), &ctx.sema);
                 let path = ref_module
-                    .find_use_path_prefixed(
+                    .find_use_path(
                         ctx.sema.db,
                         ModuleDef::Module(*target_module),
                         ctx.config.insert_use.prefix_kind,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs
index d649f13d6ee..e0e2ac75853 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs
@@ -50,7 +50,7 @@ pub(crate) fn convert_into_to_from(acc: &mut Assists, ctx: &AssistContext<'_>) -
             _ => return None,
         };
 
-        mod_path_to_ast(&module.find_use_path(
+        mod_path_to_ast(&module.find_path(
             ctx.db(),
             src_type_def,
             ctx.config.prefer_no_std,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs
index 41366658a74..367cf0bc8b9 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs
@@ -201,7 +201,7 @@ fn augment_references_with_imports(
                 let import_scope =
                     ImportScope::find_insert_use_container(new_name.syntax(), &ctx.sema);
                 let path = ref_module
-                    .find_use_path_prefixed(
+                    .find_use_path(
                         ctx.sema.db,
                         ModuleDef::Module(*target_module),
                         ctx.config.insert_use.prefix_kind,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs
index c1a3f930265..bdcefe0b4fd 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs
@@ -90,7 +90,7 @@ fn collect_data(ident_pat: ast::IdentPat, ctx: &AssistContext<'_>) -> Option<Str
     let module = ctx.sema.scope(ident_pat.syntax())?.module();
     let struct_def = hir::ModuleDef::from(struct_type);
     let kind = struct_type.kind(ctx.db());
-    let struct_def_path = module.find_use_path(
+    let struct_def_path = module.find_path(
         ctx.db(),
         struct_def,
         ctx.config.prefer_no_std,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs
index 2b8de3443b4..b4fd616f722 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs
@@ -209,7 +209,7 @@ pub(crate) fn extract_function(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
                     FamousDefs(&ctx.sema, module.krate()).core_ops_ControlFlow();
 
                 if let Some(control_flow_enum) = control_flow_enum {
-                    let mod_path = module.find_use_path_prefixed(
+                    let mod_path = module.find_use_path(
                         ctx.sema.db,
                         ModuleDef::from(control_flow_enum),
                         ctx.config.insert_use.prefix_kind,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs
index 81a639e0b9f..24bda139b2c 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs
@@ -386,7 +386,7 @@ fn process_references(
             let segment = builder.make_mut(segment);
             let scope_node = builder.make_syntax_mut(scope_node);
             if !visited_modules.contains(&module) {
-                let mod_path = module.find_use_path_prefixed(
+                let mod_path = module.find_use_path(
                     ctx.sema.db,
                     *enum_module_def,
                     ctx.config.insert_use.prefix_kind,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs
index 473c699b595..54c320a39b1 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs
@@ -58,7 +58,7 @@ fn generate_record_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<(
 
     let module = ctx.sema.to_def(&strukt)?.module(ctx.db());
     let trait_ = deref_type_to_generate.to_trait(&ctx.sema, module.krate())?;
-    let trait_path = module.find_use_path(
+    let trait_path = module.find_path(
         ctx.db(),
         ModuleDef::Trait(trait_),
         ctx.config.prefer_no_std,
@@ -103,7 +103,7 @@ fn generate_tuple_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()
 
     let module = ctx.sema.to_def(&strukt)?.module(ctx.db());
     let trait_ = deref_type_to_generate.to_trait(&ctx.sema, module.krate())?;
-    let trait_path = module.find_use_path(
+    let trait_path = module.find_path(
         ctx.db(),
         ModuleDef::Trait(trait_),
         ctx.config.prefer_no_std,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs
index 22c75cd5eef..50342b0284e 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs
@@ -58,7 +58,7 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option
 
                 let item_in_ns = hir::ItemInNs::from(hir::ModuleDef::from(ty.as_adt()?));
 
-                let type_path = current_module.find_use_path(
+                let type_path = current_module.find_path(
                     ctx.sema.db,
                     item_for_path_search(ctx.sema.db, item_in_ns)?,
                     ctx.config.prefer_no_std,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs
index ff65aac82e0..196b33e0f67 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs
@@ -44,7 +44,7 @@ pub(crate) fn qualify_method_call(acc: &mut Assists, ctx: &AssistContext<'_>) ->
     let current_module = ctx.sema.scope(call.syntax())?.module();
     let target_module_def = ModuleDef::from(resolved_call);
     let item_in_ns = ItemInNs::from(target_module_def);
-    let receiver_path = current_module.find_use_path(
+    let receiver_path = current_module.find_path(
         ctx.sema.db,
         item_for_path_search(ctx.sema.db, item_in_ns)?,
         ctx.config.prefer_no_std,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
index 3420d906dea..8cc7c883f4c 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
@@ -83,7 +83,7 @@ pub(crate) fn replace_derive_with_manual_impl(
     })
     .flat_map(|trait_| {
         current_module
-            .find_use_path(
+            .find_path(
                 ctx.sema.db,
                 hir::ModuleDef::Trait(trait_),
                 ctx.config.prefer_no_std,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs
index ba1c25fa5a7..cb9de32d9cd 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs
@@ -63,7 +63,7 @@ pub(crate) fn replace_qualified_name_with_use(
     );
     let path_to_qualifier = starts_with_name_ref
         .then(|| {
-            ctx.sema.scope(path.syntax())?.module().find_use_path_prefixed(
+            ctx.sema.scope(path.syntax())?.module().find_use_path(
                 ctx.sema.db,
                 module,
                 ctx.config.insert_use.prefix_kind,
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs
index 1ea7220960d..69b0289fc1d 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs
@@ -633,7 +633,7 @@ fn enum_variants_with_paths(
     }
 
     for variant in variants {
-        if let Some(path) = ctx.module.find_use_path(
+        if let Some(path) = ctx.module.find_path(
             ctx.db,
             hir::ModuleDef::from(variant),
             ctx.config.prefer_no_std,
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs
index 1e31d65fddf..f350c2743c7 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs
@@ -171,7 +171,7 @@ pub(crate) fn complete_expr_path(
                     hir::Adt::Struct(strukt) => {
                         let path = ctx
                             .module
-                            .find_use_path(
+                            .find_path(
                                 ctx.db,
                                 hir::ModuleDef::from(strukt),
                                 ctx.config.prefer_no_std,
@@ -194,7 +194,7 @@ pub(crate) fn complete_expr_path(
                     hir::Adt::Union(un) => {
                         let path = ctx
                             .module
-                            .find_use_path(
+                            .find_path(
                                 ctx.db,
                                 hir::ModuleDef::from(un),
                                 ctx.config.prefer_no_std,
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs
index c6e243b31a7..c14da34874b 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs
@@ -63,7 +63,7 @@ pub(crate) fn complete_postfix(
     if let Some(drop_trait) = ctx.famous_defs().core_ops_Drop() {
         if receiver_ty.impls_trait(ctx.db, drop_trait, &[]) {
             if let Some(drop_fn) = ctx.famous_defs().core_mem_drop() {
-                if let Some(path) = ctx.module.find_use_path(
+                if let Some(path) = ctx.module.find_path(
                     ctx.db,
                     ItemInNs::Values(drop_fn.into()),
                     ctx.config.prefer_no_std,
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs
index d89cfc8b6cb..4165dd48af4 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs
@@ -260,7 +260,7 @@ pub fn resolve_completion_edits(
         );
         let import = items_with_name
             .filter_map(|candidate| {
-                current_module.find_use_path_prefixed(
+                current_module.find_use_path(
                     db,
                     candidate,
                     config.insert_use.prefix_kind,
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs
index 7fa31e2757d..d7b27f8b3b3 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs
@@ -333,7 +333,7 @@ pub(crate) fn render_expr(
     });
     for trait_ in expr.traits_used(ctx.db) {
         let trait_item = hir::ItemInNs::from(hir::ModuleDef::from(trait_));
-        let Some(path) = ctx.module.find_use_path(
+        let Some(path) = ctx.module.find_path(
             ctx.db,
             trait_item,
             ctx.config.prefer_no_std,
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs b/src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs
index 7d710f1e130..37bb6cfef0a 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs
@@ -174,7 +174,7 @@ fn import_edits(ctx: &CompletionContext<'_>, requires: &[GreenNode]) -> Option<V
             hir::PathResolution::Def(def) => def.into(),
             _ => return None,
         };
-        let path = ctx.module.find_use_path_prefixed(
+        let path = ctx.module.find_use_path(
             ctx.db,
             item,
             ctx.config.insert_use.prefix_kind,
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs
index 766bfcf4d09..5e33b08e4a4 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs
@@ -637,17 +637,13 @@ fn get_mod_path(
     prefer_no_std: bool,
     prefer_prelude: bool,
 ) -> Option<ModPath> {
-    if let Some(prefix_kind) = prefixed {
-        module_with_candidate.find_use_path_prefixed(
-            db,
-            item_to_search,
-            prefix_kind,
-            prefer_no_std,
-            prefer_prelude,
-        )
-    } else {
-        module_with_candidate.find_use_path(db, item_to_search, prefer_no_std, prefer_prelude)
-    }
+    module_with_candidate.find_use_path(
+        db,
+        item_to_search,
+        prefixed.unwrap_or(PrefixKind::Plain),
+        prefer_no_std,
+        prefer_prelude,
+    )
 }
 
 impl ImportCandidate {
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs
index 7e1811b4cac..6f4f97e0b86 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs
@@ -308,7 +308,7 @@ impl Ctx<'_> {
                             parent.segment()?.name_ref()?,
                         )
                         .and_then(|trait_ref| {
-                            let found_path = self.target_module.find_use_path(
+                            let found_path = self.target_module.find_path(
                                 self.source_scope.db.upcast(),
                                 hir::ModuleDef::Trait(trait_ref),
                                 false,
@@ -347,7 +347,7 @@ impl Ctx<'_> {
                     }
                 }
 
-                let found_path = self.target_module.find_use_path(
+                let found_path = self.target_module.find_path(
                     self.source_scope.db.upcast(),
                     def,
                     false,
@@ -385,7 +385,7 @@ impl Ctx<'_> {
 
                 if let Some(adt) = ty.as_adt() {
                     if let ast::Type::PathType(path_ty) = &ast_ty {
-                        let found_path = self.target_module.find_use_path(
+                        let found_path = self.target_module.find_path(
                             self.source_scope.db.upcast(),
                             ModuleDef::from(adt),
                             false,
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs
index b3dde977b1c..71958bc8660 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs
@@ -144,7 +144,7 @@ pub(crate) fn json_in_items(
                         let current_module = semantics_scope.module();
                         if !scope_has("Serialize") {
                             if let Some(PathResolution::Def(it)) = serialize_resolved {
-                                if let Some(it) = current_module.find_use_path_prefixed(
+                                if let Some(it) = current_module.find_use_path(
                                     sema.db,
                                     it,
                                     config.insert_use.prefix_kind,
@@ -157,7 +157,7 @@ pub(crate) fn json_in_items(
                         }
                         if !scope_has("Deserialize") {
                             if let Some(PathResolution::Def(it)) = deserialize_resolved {
-                                if let Some(it) = current_module.find_use_path_prefixed(
+                                if let Some(it) = current_module.find_use_path(
                                     sema.db,
                                     it,
                                     config.insert_use.prefix_kind,
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs
index f92ba576d3a..ed9094f1f36 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs
@@ -122,7 +122,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields) -> Option<Vec<Ass
                     let expr = (|| -> Option<ast::Expr> {
                         let item_in_ns = hir::ItemInNs::from(hir::ModuleDef::from(ty.as_adt()?));
 
-                        let type_path = current_module?.find_use_path(
+                        let type_path = current_module?.find_path(
                             ctx.sema.db,
                             item_for_path_search(ctx.sema.db, item_in_ns)?,
                             ctx.config.prefer_no_std,
diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs
index cfda1c692ae..99df3f2563d 100644
--- a/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs
+++ b/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs
@@ -664,7 +664,7 @@ impl Match {
         for (path, resolved_path) in &template.resolved_paths {
             if let hir::PathResolution::Def(module_def) = resolved_path.resolution {
                 let mod_path =
-                    module.find_use_path(sema.db, module_def, false, true).ok_or_else(|| {
+                    module.find_path(sema.db, module_def, false, true).ok_or_else(|| {
                         match_error!("Failed to render template path `{}` at match location")
                     })?;
                 self.rendered_template_paths.insert(path.clone(), mod_path);