Skip to content

Commit

Permalink
Auto merge of #17277 - Veykril:find-path-fixes, r=Veykril
Browse files Browse the repository at this point in the history
fix: Various find path fixes

Fixes rust-lang/rust-analyzer#17271
  • Loading branch information
bors committed May 22, 2024
2 parents d9dda8f + b1830a5 commit ad810a5
Show file tree
Hide file tree
Showing 33 changed files with 647 additions and 346 deletions.
834 changes: 565 additions & 269 deletions src/tools/rust-analyzer/crates/hir-def/src/find_path.rs

Large diffs are not rendered by default.

8 changes: 3 additions & 5 deletions src/tools/rust-analyzer/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 src/tools/rust-analyzer/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 src/tools/rust-analyzer/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 src/tools/rust-analyzer/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,
};

const PREDEFINED_TOOLS: &[SmolStr] = &[
Expand Down Expand Up @@ -137,7 +137,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 @@ -163,7 +163,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 @@ -586,7 +586,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 src/tools/rust-analyzer/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 src/tools/rust-analyzer/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 src/tools/rust-analyzer/crates/hir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -788,7 +788,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 @@ -799,26 +799,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 src/tools/rust-analyzer/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
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
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
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
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
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
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
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

0 comments on commit ad810a5

Please sign in to comment.