mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-13 21:54:42 +00:00
fix: Fix general find-path inconsistencies
This commit is contained in:
parent
21ec8f5238
commit
c88b421853
32 changed files with 242 additions and 193 deletions
|
@ -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,
|
||||
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").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,
|
||||
prefer_no_std: bool,
|
||||
prefer_prelude: bool,
|
||||
) -> Option<ModPath> {
|
||||
let _p = tracing::span!(tracing::Level::INFO, "find_path_prefixed").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 {
|
|||
}
|
||||
}
|
||||
"#,
|
||||
"syntax::ast::ModuleItem",
|
||||
"ast::ModuleItem",
|
||||
"syntax::ast::ModuleItem",
|
||||
"syntax::ast::ModuleItem",
|
||||
"syntax::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",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
||||
|
|
|
@ -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]>>,
|
||||
|
|
|
@ -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,
|
||||
) {
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue