Skip to content

Commit

Permalink
move to check module in resolve_hir_path_qualifier
Browse files Browse the repository at this point in the history
Signed-off-by: Hayashi Mikihiro <[email protected]>
  • Loading branch information
Hmikihiro committed Feb 10, 2025
1 parent bbd1055 commit f9eebaf
Showing 1 changed file with 42 additions and 53 deletions.
95 changes: 42 additions & 53 deletions crates/hir/src/source_analyzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -849,7 +849,7 @@ impl SourceAnalyzer {
// trying to resolve foo::bar.
if let Some(use_tree) = parent().and_then(ast::UseTree::cast) {
if use_tree.coloncolon_token().is_some() {
return resolve_hir_path_qualifier(db, &self.resolver, &hir_path, &types_map)
return resolve_hir_path_qualifier(db, &self.resolver, &hir_path, &types_map, None)
.map(|it| (it, None));
}
}
Expand All @@ -872,9 +872,15 @@ impl SourceAnalyzer {
// Case where path is a qualifier of another path, e.g. foo::bar::Baz or foo::bar:: where we are
// trying to resolve foo::bar.
if path.parent_path().is_some() || is_last_token_colon2 {
let parent_hir_path =
let parent_path =
path.parent_path().and_then(|parent_path| Path::from_src(&mut ctx, parent_path));
return match resolve_hir_path_qualifier(db, &self.resolver, &hir_path, &types_map) {
return match resolve_hir_path_qualifier(
db,
&self.resolver,
&hir_path,
&types_map,
parent_path.as_ref(),
) {
None if meta_path.is_some() => path
.first_segment()
.and_then(|it| it.name_ref())
Expand All @@ -883,51 +889,6 @@ impl SourceAnalyzer {
.map(PathResolution::ToolModule)
})
.map(|it| (it, None)),
// Case the type name conflict with use module,
// e.g.
// ```
// use std::str;
// fn main() {
// str::from_utf8(); // as module std::str
// str::len(); // as primitive type str
// str::no_exist_item(); // as primitive type str
// }
// ```
Some(it)
if matches!(
it,
PathResolution::Def(ModuleDef::Adt(_) | ModuleDef::BuiltinType(_))
) =>
{
if let Some(mod_path) = hir_path.mod_path() {
if let Some(ModuleDefId::ModuleId(id)) = self
.resolver
.resolve_module_path_in_items(db.upcast(), mod_path)
.take_types()
{
let module = crate::Module { id };
let res = Some((PathResolution::Def(ModuleDef::Module(module)), None));
match it {
PathResolution::Def(ModuleDef::Adt(_)) => return res,
PathResolution::Def(ModuleDef::BuiltinType(_)) => {
if let Some(parent_hir_path) = parent_hir_path {
let parent_hir_name =
parent_hir_path.segments().get(1).map(|it| it.name);
if module
.scope(db, None)
.into_iter()
.any(|(name, _)| Some(&name) == parent_hir_name)
{
return res;
}
}
}
_ => (),
}
}
}
Some((it, None))
}
// FIXME: We do not show substitutions for parts of path, because this is really complex
// due to the interactions with associated items of `impl`s and associated items of associated
// types.
Expand Down Expand Up @@ -1003,7 +964,7 @@ impl SourceAnalyzer {
}
if parent().is_some_and(|it| ast::Visibility::can_cast(it.kind())) {
// No substitution because only modules can be inside visibilities, and those have no generics.
resolve_hir_path_qualifier(db, &self.resolver, &hir_path, &types_map)
resolve_hir_path_qualifier(db, &self.resolver, &hir_path, &types_map, None)
.map(|it| (it, None))
} else {
// Probably a type, no need to show substitutions for those.
Expand Down Expand Up @@ -1550,8 +1511,9 @@ fn resolve_hir_path_qualifier(
resolver: &Resolver,
path: &Path,
types_map: &TypesMap,
parent_path: Option<&Path>,
) -> Option<PathResolution> {
(|| {
let resolve_from_typens = (|| {
let (ty, unresolved) = match path.type_anchor() {
Some(type_ref) => {
let (_, res) = TyLoweringContext::new_maybe_unowned(
Expand Down Expand Up @@ -1617,13 +1579,40 @@ fn resolve_hir_path_qualifier(
.map(PathResolution::Def),
None => Some(res),
}
})()
.or_else(|| {
})();

let resolve_module = || {
resolver
.resolve_module_path_in_items(db.upcast(), path.mod_path()?)
.take_types()
.map(|it| PathResolution::Def(it.into()))
})
};

match resolve_from_typens {
Some(PathResolution::Def(module_def)) => {
let item = resolve_module();
if let Some(PathResolution::Def(ModuleDef::Module(module))) = item {
match module_def {
ModuleDef::BuiltinType(_) => {
if let Some(parent_path) = parent_path {
let parent_name = parent_path.segments().get(1).map(|it| it.name);
if module
.scope(db, None)
.into_iter()
.any(|(name, _)| Some(&name) == parent_name)
{
return item;
}
}
}
_ => return item,
}
}
resolve_from_typens
}
None => resolve_module(),
Some(_) => resolve_from_typens,
}
}

pub(crate) fn name_hygiene(db: &dyn HirDatabase, name: InFile<&SyntaxNode>) -> HygieneId {
Expand Down

0 comments on commit f9eebaf

Please sign in to comment.