mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-28 10:39:45 +00:00
fix: shadow type by module
Signed-off-by: Hayashi Mikihiro <34ttrweoewiwe28@gmail.com>
This commit is contained in:
parent
0d64633d31
commit
2854ad9a41
4 changed files with 281 additions and 72 deletions
|
|
@ -25,7 +25,7 @@ use hir_def::{
|
|||
lower::LowerCtx,
|
||||
nameres::MacroSubNs,
|
||||
path::{ModPath, Path, PathKind},
|
||||
resolver::{Resolver, TypeNs, ValueNs, resolver_for_scope},
|
||||
resolver::{ModuleOrTypeNs, Resolver, TypeNs, ValueNs, resolver_for_scope},
|
||||
type_ref::{Mutability, TypesMap, TypesSourceMap},
|
||||
};
|
||||
use hir_expand::{
|
||||
|
|
@ -1365,6 +1365,23 @@ pub(crate) fn resolve_hir_path_as_attr_macro(
|
|||
.map(Into::into)
|
||||
}
|
||||
|
||||
fn resolve_path_in_module_or_type_ns(
|
||||
db: &dyn HirDatabase,
|
||||
resolver: &Resolver,
|
||||
path: &Path,
|
||||
) -> Option<(ModuleOrTypeNs, Option<usize>)> {
|
||||
let mut types = resolver
|
||||
.resolve_path_in_type_ns(db.upcast(), path)
|
||||
.map(|(ty, remaining_idx, _)| (ty, remaining_idx))
|
||||
.peekable();
|
||||
let (ty, _) = types.peek()?;
|
||||
match ty {
|
||||
ModuleOrTypeNs::ModuleNs(_) => types
|
||||
.find_or_first(|(ty, _)| matches!(ty, ModuleOrTypeNs::TypeNs(TypeNs::BuiltinType(_)))),
|
||||
ModuleOrTypeNs::TypeNs(_) => types.next(),
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_hir_path_(
|
||||
db: &dyn HirDatabase,
|
||||
resolver: &Resolver,
|
||||
|
|
@ -1384,10 +1401,10 @@ fn resolve_hir_path_(
|
|||
resolver.type_owner(),
|
||||
)
|
||||
.lower_ty_ext(type_ref);
|
||||
res.map(|ty_ns| (ty_ns, path.segments().first()))
|
||||
res.map(|ty_ns| (ModuleOrTypeNs::TypeNs(ty_ns), path.segments().first()))
|
||||
}
|
||||
None => {
|
||||
let (ty, remaining_idx, _) = resolver.resolve_path_in_type_ns(db.upcast(), path)?;
|
||||
let (ty, remaining_idx) = resolve_path_in_module_or_type_ns(db, resolver, path)?;
|
||||
match remaining_idx {
|
||||
Some(remaining_idx) => {
|
||||
if remaining_idx + 1 == path.segments().len() {
|
||||
|
|
@ -1403,25 +1420,30 @@ fn resolve_hir_path_(
|
|||
|
||||
// If we are in a TypeNs for a Trait, and we have an unresolved name, try to resolve it as a type
|
||||
// within the trait's associated types.
|
||||
if let (Some(unresolved), &TypeNs::TraitId(trait_id)) = (&unresolved, &ty) {
|
||||
if let (Some(unresolved), ModuleOrTypeNs::TypeNs(TypeNs::TraitId(trait_id))) =
|
||||
(&unresolved, &ty)
|
||||
{
|
||||
if let Some(type_alias_id) =
|
||||
db.trait_items(trait_id).associated_type_by_name(unresolved.name)
|
||||
db.trait_items(*trait_id).associated_type_by_name(unresolved.name)
|
||||
{
|
||||
return Some(PathResolution::Def(ModuleDefId::from(type_alias_id).into()));
|
||||
}
|
||||
}
|
||||
|
||||
let res = match ty {
|
||||
TypeNs::SelfType(it) => PathResolution::SelfType(it.into()),
|
||||
TypeNs::GenericParam(id) => PathResolution::TypeParam(id.into()),
|
||||
TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => {
|
||||
PathResolution::Def(Adt::from(it).into())
|
||||
}
|
||||
TypeNs::EnumVariantId(it) => PathResolution::Def(Variant::from(it).into()),
|
||||
TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()),
|
||||
TypeNs::BuiltinType(it) => PathResolution::Def(BuiltinType::from(it).into()),
|
||||
TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()),
|
||||
TypeNs::TraitAliasId(it) => PathResolution::Def(TraitAlias::from(it).into()),
|
||||
ModuleOrTypeNs::TypeNs(ty) => match ty {
|
||||
TypeNs::SelfType(it) => PathResolution::SelfType(it.into()),
|
||||
TypeNs::GenericParam(id) => PathResolution::TypeParam(id.into()),
|
||||
TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => {
|
||||
PathResolution::Def(Adt::from(it).into())
|
||||
}
|
||||
TypeNs::EnumVariantId(it) => PathResolution::Def(Variant::from(it).into()),
|
||||
TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()),
|
||||
TypeNs::BuiltinType(it) => PathResolution::Def(BuiltinType::from(it).into()),
|
||||
TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()),
|
||||
TypeNs::TraitAliasId(it) => PathResolution::Def(TraitAlias::from(it).into()),
|
||||
},
|
||||
ModuleOrTypeNs::ModuleNs(it) => PathResolution::Def(ModuleDef::Module(it.into())),
|
||||
};
|
||||
match unresolved {
|
||||
Some(unresolved) => resolver
|
||||
|
|
@ -1517,10 +1539,10 @@ fn resolve_hir_path_qualifier(
|
|||
resolver.type_owner(),
|
||||
)
|
||||
.lower_ty_ext(type_ref);
|
||||
res.map(|ty_ns| (ty_ns, path.segments().first()))
|
||||
res.map(|ty_ns| (ModuleOrTypeNs::TypeNs(ty_ns), path.segments().first()))
|
||||
}
|
||||
None => {
|
||||
let (ty, remaining_idx, _) = resolver.resolve_path_in_type_ns(db.upcast(), path)?;
|
||||
let (ty, remaining_idx) = resolve_path_in_module_or_type_ns(db, resolver, path)?;
|
||||
match remaining_idx {
|
||||
Some(remaining_idx) => {
|
||||
if remaining_idx + 1 == path.segments().len() {
|
||||
|
|
@ -1536,25 +1558,29 @@ fn resolve_hir_path_qualifier(
|
|||
|
||||
// If we are in a TypeNs for a Trait, and we have an unresolved name, try to resolve it as a type
|
||||
// within the trait's associated types.
|
||||
if let (Some(unresolved), &TypeNs::TraitId(trait_id)) = (&unresolved, &ty) {
|
||||
if let (Some(unresolved), &ModuleOrTypeNs::TypeNs(TypeNs::TraitId(trait_id))) =
|
||||
(&unresolved, &ty)
|
||||
{
|
||||
if let Some(type_alias_id) =
|
||||
db.trait_items(trait_id).associated_type_by_name(unresolved.name)
|
||||
{
|
||||
return Some(PathResolution::Def(ModuleDefId::from(type_alias_id).into()));
|
||||
}
|
||||
}
|
||||
|
||||
let res = match ty {
|
||||
TypeNs::SelfType(it) => PathResolution::SelfType(it.into()),
|
||||
TypeNs::GenericParam(id) => PathResolution::TypeParam(id.into()),
|
||||
TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => {
|
||||
PathResolution::Def(Adt::from(it).into())
|
||||
}
|
||||
TypeNs::EnumVariantId(it) => PathResolution::Def(Variant::from(it).into()),
|
||||
TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()),
|
||||
TypeNs::BuiltinType(it) => PathResolution::Def(BuiltinType::from(it).into()),
|
||||
TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()),
|
||||
TypeNs::TraitAliasId(it) => PathResolution::Def(TraitAlias::from(it).into()),
|
||||
ModuleOrTypeNs::TypeNs(ty) => match ty {
|
||||
TypeNs::SelfType(it) => PathResolution::SelfType(it.into()),
|
||||
TypeNs::GenericParam(id) => PathResolution::TypeParam(id.into()),
|
||||
TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => {
|
||||
PathResolution::Def(Adt::from(it).into())
|
||||
}
|
||||
TypeNs::EnumVariantId(it) => PathResolution::Def(Variant::from(it).into()),
|
||||
TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()),
|
||||
TypeNs::BuiltinType(it) => PathResolution::Def(BuiltinType::from(it).into()),
|
||||
TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()),
|
||||
TypeNs::TraitAliasId(it) => PathResolution::Def(TraitAlias::from(it).into()),
|
||||
},
|
||||
ModuleOrTypeNs::ModuleNs(it) => PathResolution::Def(ModuleDef::Module(it.into())),
|
||||
};
|
||||
match unresolved {
|
||||
Some(unresolved) => resolver
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue