Merge pull request #19461 from Hmikihiro/shadow_by_module

fix: shadow type by module
This commit is contained in:
Lukas Wirth 2025-04-10 12:20:14 +00:00 committed by GitHub
commit f880acd18c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 180 additions and 7 deletions

View file

@ -105,9 +105,8 @@ pub enum TypeNs {
BuiltinType(BuiltinType),
TraitId(TraitId),
TraitAliasId(TraitAliasId),
// Module belong to type ns, but the resolver is used when all module paths
// are fully resolved.
// ModuleId(ModuleId)
ModuleId(ModuleId),
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@ -249,6 +248,24 @@ impl Resolver {
}
Scope::BlockScope(m) => {
if let Some(res) = m.resolve_path_in_type_ns(db, path) {
let res = match res.0 {
TypeNs::ModuleId(_) if res.1.is_none() => {
if let Some(ModuleDefId::BuiltinType(builtin)) = BUILTIN_SCOPE
.get(first_name)
.and_then(|builtin| builtin.take_types())
{
(
TypeNs::BuiltinType(builtin),
remaining_idx(),
None,
ResolvePathResultPrefixInfo::default(),
)
} else {
res
}
}
_ => res,
};
return Some(res);
}
}
@ -1193,11 +1210,12 @@ fn to_type_ns(per_ns: PerNs) -> Option<(TypeNs, Option<ImportOrExternCrate>)> {
ModuleDefId::TraitId(it) => TypeNs::TraitId(it),
ModuleDefId::TraitAliasId(it) => TypeNs::TraitAliasId(it),
ModuleDefId::ModuleId(it) => TypeNs::ModuleId(it),
ModuleDefId::FunctionId(_)
| ModuleDefId::ConstId(_)
| ModuleDefId::MacroId(_)
| ModuleDefId::StaticId(_)
| ModuleDefId::ModuleId(_) => return None,
| ModuleDefId::StaticId(_) => return None,
};
Some((res, def.import))
}

View file

@ -1666,7 +1666,8 @@ impl<'a> InferenceContext<'a> {
TypeNs::AdtId(AdtId::EnumId(_))
| TypeNs::BuiltinType(_)
| TypeNs::TraitId(_)
| TypeNs::TraitAliasId(_) => {
| TypeNs::TraitAliasId(_)
| TypeNs::ModuleId(_) => {
// FIXME diagnostic
(self.err_ty(), None)
}

View file

@ -279,7 +279,9 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
TypeNs::BuiltinType(it) => self.lower_path_inner(it.into(), infer_args),
TypeNs::TypeAliasId(it) => self.lower_path_inner(it.into(), infer_args),
// FIXME: report error
TypeNs::EnumVariantId(_) => return (TyKind::Error.intern(Interner), None),
TypeNs::EnumVariantId(_) | TypeNs::ModuleId(_) => {
return (TyKind::Error.intern(Interner), None);
}
};
self.skip_resolved_segment();
@ -310,6 +312,9 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
TypeNs::BuiltinType(_) => {
prohibit_generics_on_resolved(GenericArgsProhibitedReason::PrimitiveTy)
}
TypeNs::ModuleId(_) => {
prohibit_generics_on_resolved(GenericArgsProhibitedReason::Module)
}
TypeNs::AdtId(_)
| TypeNs::EnumVariantId(_)
| TypeNs::TypeAliasId(_)

View file

@ -210,6 +210,9 @@ fn resolve_assoc_or_field(
// XXX: Do these get resolved?
return None;
}
TypeNs::ModuleId(_) => {
return None;
}
};
// Resolve inherent items first, then trait items, then fields.

View file

@ -1527,6 +1527,7 @@ fn resolve_hir_path_(
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()),
TypeNs::ModuleId(it) => PathResolution::Def(ModuleDef::Module(it.into())),
};
match unresolved {
Some(unresolved) => resolver
@ -1654,6 +1655,7 @@ fn resolve_hir_path_qualifier(
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()),
TypeNs::ModuleId(it) => PathResolution::Def(ModuleDef::Module(it.into())),
};
match unresolved {
Some(unresolved) => resolver

View file

@ -3330,6 +3330,150 @@ pub fn foo() {}
fn main() {
let s = st$0r::f();
}
"#,
);
}
#[test]
fn struct_shadow_by_module() {
check(
r#"
mod foo {
pub mod bar {
// ^^^
pub type baz = usize;
}
}
struct bar;
fn main() {
use foo::bar;
let x: ba$0r::baz = 5;
}
"#,
);
}
#[test]
fn type_alias_shadow_by_module() {
check(
r#"
mod foo {
pub mod bar {
// ^^^
pub fn baz() {}
}
}
trait Qux {}
fn item<bar: Qux>() {
use foo::bar;
ba$0r::baz();
}
}
"#,
);
check(
r#"
mod foo {
pub mod bar {
// ^^^
pub fn baz() {}
}
}
fn item<bar>(x: bar) {
use foo::bar;
let x: bar$0 = x;
}
"#,
);
}
#[test]
fn trait_shadow_by_module() {
check(
r#"
pub mod foo {
pub mod Bar {}
// ^^^
}
trait Bar {}
fn main() {
use foo::Bar;
fn f<Qux: B$0ar>() {}
}
"#,
);
}
#[test]
fn const_shadow_by_module() {
check(
r#"
pub mod foo {
pub struct u8 {}
pub mod bar {
pub mod u8 {}
}
}
fn main() {
use foo::u8;
{
use foo::bar::u8;
fn f1<const N: u$08>() {}
}
fn f2<const N: u8>() {}
}
"#,
);
check(
r#"
pub mod foo {
pub struct u8 {}
// ^^
pub mod bar {
pub mod u8 {}
}
}
fn main() {
use foo::u8;
{
use foo::bar::u8;
fn f1<const N: u8>() {}
}
fn f2<const N: u$08>() {}
}
"#,
);
check(
r#"
pub mod foo {
pub struct buz {}
pub mod bar {
pub mod buz {}
// ^^^
}
}
fn main() {
use foo::buz;
{
use foo::bar::buz;
fn f1<const N: buz$0>() {}
}
}
"#,
);
}