Skip to content

fix: Various find path fixes #17277

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
834 changes: 565 additions & 269 deletions crates/hir-def/src/find_path.rs

Large diffs are not rendered by default.

8 changes: 3 additions & 5 deletions crates/hir-def/src/import_map.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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`.
Expand Down Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion crates/hir-def/src/item_scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
23 changes: 23 additions & 0 deletions crates/hir-def/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 {
Expand Down
9 changes: 5 additions & 4 deletions crates/hir-def/src/nameres.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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]>>,
Expand All @@ -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,
Expand Down Expand Up @@ -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))
}

Expand Down
12 changes: 5 additions & 7 deletions crates/hir-def/src/resolver.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand All @@ -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)]
Expand Down Expand Up @@ -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]>>,
Expand Down
4 changes: 3 additions & 1 deletion crates/hir-ty/src/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -999,6 +999,8 @@ impl HirDisplay for Ty {
db.upcast(),
ItemInNs::Types((*def_id).into()),
module_id,
PrefixKind::Plain,
false,
false,
true,
) {
Expand Down
9 changes: 6 additions & 3 deletions crates/hir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,
Expand All @@ -800,26 +800,29 @@ impl Module {
db,
item.into().into(),
self.into(),
PrefixKind::Plain,
false,
prefer_no_std,
prefer_prelude,
)
}

/// 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>,
prefix_kind: PrefixKind,
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,
)
Expand Down
23 changes: 1 addition & 22 deletions crates/hir/src/term_search/expr.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//! Type tree for term search

use hir_def::find_path::PrefixKind;
use hir_expand::mod_path::ModPath;
use hir_ty::{
db::HirDatabase,
Expand All @@ -21,28 +20,8 @@ fn mod_item_path(
prefer_prelude: bool,
) -> Option<ModPath> {
let db = sema_scope.db;
// Account for locals shadowing items from module
let name_hit_count = def.name(db).map(|def_name| {
let mut name_hit_count = 0;
sema_scope.process_all_names(&mut |name, _| {
if name == def_name {
name_hit_count += 1;
}
});
name_hit_count
});

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,
),
}
m.find_path(db.upcast(), *def, prefer_no_std, prefer_prelude)
}

/// Helper function to get path to `ModuleDef` as string
Expand Down
2 changes: 1 addition & 1 deletion crates/ide-assists/src/handlers/add_missing_match_arms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 3 additions & 3 deletions crates/ide-assists/src/handlers/bool_to_enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -1521,7 +1521,7 @@ mod foo {
}
"#,
r#"
use crate::foo::Bool;
use foo::Bool;

fn main() {
use foo::FOO;
Expand Down Expand Up @@ -1602,7 +1602,7 @@ pub mod bar {
"#,
r#"
//- /main.rs
use crate::foo::bar::Bool;
use foo::bar::Bool;

mod foo;

Expand Down
2 changes: 1 addition & 1 deletion crates/ide-assists/src/handlers/convert_into_to_from.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -811,7 +811,7 @@ pub mod bar {
"#,
r#"
//- /main.rs
use crate::foo::bar::BarResult;
use foo::bar::BarResult;

mod foo;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion crates/ide-assists/src/handlers/extract_function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -881,7 +881,7 @@ fn another_fn() {
r#"use my_mod::my_other_mod::MyField;

mod my_mod {
use self::my_other_mod::MyField;
use my_other_mod::MyField;

fn another_fn() {
let m = my_other_mod::MyEnum::MyField(MyField(1, 1));
Expand Down
4 changes: 2 additions & 2 deletions crates/ide-assists/src/handlers/generate_deref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion crates/ide-assists/src/handlers/generate_new.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion crates/ide-assists/src/handlers/qualify_method_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Loading