Skip to content

Commit 2854ad9

Browse files
committed
fix: shadow type by module
Signed-off-by: Hayashi Mikihiro <34ttrweoewiwe28@gmail.com>
1 parent 0d64633 commit 2854ad9

File tree

4 files changed

+281
-72
lines changed

4 files changed

+281
-72
lines changed

crates/hir-def/src/resolver.rs

Lines changed: 74 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,12 @@ pub enum TypeNs {
107107
// ModuleId(ModuleId)
108108
}
109109

110+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
111+
pub enum ModuleOrTypeNs {
112+
ModuleNs(ModuleId),
113+
TypeNs(TypeNs),
114+
}
115+
110116
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
111117
pub enum ResolveValueResult {
112118
ValueNs(ValueNs, Option<ImportOrGlob>),
@@ -163,22 +169,33 @@ impl Resolver {
163169
self.resolve_module_path(db, path, BuiltinShadowMode::Module)
164170
}
165171

166-
pub fn resolve_path_in_type_ns(
167-
&self,
168-
db: &dyn DefDatabase,
169-
path: &Path,
170-
) -> Option<(TypeNs, Option<usize>, Option<ImportOrExternCrate>)> {
172+
pub fn resolve_path_in_type_ns<'a>(
173+
&'a self,
174+
db: &'a dyn DefDatabase,
175+
path: &'a Path,
176+
) -> impl Iterator<Item = (ModuleOrTypeNs, Option<usize>, Option<ImportOrExternCrate>)> + 'a
177+
{
171178
self.resolve_path_in_type_ns_with_prefix_info(db, path).map(
172-
|(resolution, remaining_segments, import, _)| (resolution, remaining_segments, import),
179+
move |(resolution, remaining_segments, import, _)| {
180+
(resolution, remaining_segments, import)
181+
},
173182
)
174183
}
175184

176-
pub fn resolve_path_in_type_ns_with_prefix_info(
177-
&self,
178-
db: &dyn DefDatabase,
179-
path: &Path,
180-
) -> Option<(TypeNs, Option<usize>, Option<ImportOrExternCrate>, ResolvePathResultPrefixInfo)>
181-
{
185+
pub fn resolve_path_in_type_ns_with_prefix_info<'a>(
186+
&'a self,
187+
db: &'a dyn DefDatabase,
188+
path: &'a Path,
189+
) -> Box<
190+
dyn Iterator<
191+
Item = (
192+
ModuleOrTypeNs,
193+
Option<usize>,
194+
Option<ImportOrExternCrate>,
195+
ResolvePathResultPrefixInfo,
196+
),
197+
> + 'a,
198+
> {
182199
let path = match path {
183200
Path::BarePath(mod_path) => mod_path,
184201
Path::Normal(it) => &it.mod_path,
@@ -192,75 +209,87 @@ impl Resolver {
192209
LangItemTarget::Trait(it) => TypeNs::TraitId(it),
193210
LangItemTarget::Function(_)
194211
| LangItemTarget::ImplDef(_)
195-
| LangItemTarget::Static(_) => return None,
212+
| LangItemTarget::Static(_) => return Box::new(iter::empty()),
196213
};
197-
return Some((
198-
type_ns,
214+
return Box::new(iter::once((
215+
ModuleOrTypeNs::TypeNs(type_ns),
199216
seg.as_ref().map(|_| 1),
200217
None,
201218
ResolvePathResultPrefixInfo::default(),
202-
));
219+
)));
203220
}
204221
};
205-
let first_name = path.segments().first()?;
222+
let Some(first_name) = path.segments().first() else { return Box::new(iter::empty()) };
206223
let skip_to_mod = path.kind != PathKind::Plain;
207224
if skip_to_mod {
208-
return self.module_scope.resolve_path_in_type_ns(db, path);
225+
return Box::new(self.module_scope.resolve_path_in_type_ns(db, path).into_iter());
209226
}
210227

211228
let remaining_idx = || {
212229
if path.segments().len() == 1 { None } else { Some(1) }
213230
};
214231

215-
for scope in self.scopes() {
216-
match scope {
217-
Scope::ExprScope(_) | Scope::MacroDefScope(_) => continue,
232+
let ns = self
233+
.scopes()
234+
.filter_map(move |scope| match scope {
235+
Scope::ExprScope(_) | Scope::MacroDefScope(_) => None,
218236
Scope::GenericParams { params, def } => {
219237
if let Some(id) = params.find_type_by_name(first_name, *def) {
220238
return Some((
221-
TypeNs::GenericParam(id),
239+
ModuleOrTypeNs::TypeNs(TypeNs::GenericParam(id)),
222240
remaining_idx(),
223241
None,
224242
ResolvePathResultPrefixInfo::default(),
225243
));
226244
}
245+
None
227246
}
228247
&Scope::ImplDefScope(impl_) => {
229248
if *first_name == sym::Self_.clone() {
230249
return Some((
231-
TypeNs::SelfType(impl_),
250+
ModuleOrTypeNs::TypeNs(TypeNs::SelfType(impl_)),
232251
remaining_idx(),
233252
None,
234253
ResolvePathResultPrefixInfo::default(),
235254
));
236255
}
256+
None
237257
}
238258
&Scope::AdtScope(adt) => {
239259
if *first_name == sym::Self_.clone() {
240260
return Some((
241-
TypeNs::AdtSelfType(adt),
261+
ModuleOrTypeNs::TypeNs(TypeNs::AdtSelfType(adt)),
242262
remaining_idx(),
243263
None,
244264
ResolvePathResultPrefixInfo::default(),
245265
));
246266
}
267+
None
247268
}
248269
Scope::BlockScope(m) => {
249270
if let Some(res) = m.resolve_path_in_type_ns(db, path) {
250271
return Some(res);
251272
}
273+
None
252274
}
253-
}
254-
}
255-
self.module_scope.resolve_path_in_type_ns(db, path)
275+
})
276+
.chain(self.module_scope.resolve_path_in_type_ns(db, path));
277+
278+
Box::new(ns)
256279
}
257280

258281
pub fn resolve_path_in_type_ns_fully(
259282
&self,
260283
db: &dyn DefDatabase,
261284
path: &Path,
262285
) -> Option<TypeNs> {
263-
let (res, unresolved, _) = self.resolve_path_in_type_ns(db, path)?;
286+
let (res, unresolved) = self
287+
.resolve_path_in_type_ns(db, path)
288+
.filter_map(|(res, unresolved, _)| match res {
289+
ModuleOrTypeNs::TypeNs(it) => Some((it, unresolved)),
290+
ModuleOrTypeNs::ModuleNs(_) => None,
291+
})
292+
.next()?;
264293
if unresolved.is_some() {
265294
return None;
266295
}
@@ -1158,16 +1187,20 @@ impl ModuleItemMap {
11581187
&self,
11591188
db: &dyn DefDatabase,
11601189
path: &ModPath,
1161-
) -> Option<(TypeNs, Option<usize>, Option<ImportOrExternCrate>, ResolvePathResultPrefixInfo)>
1162-
{
1190+
) -> Option<(
1191+
ModuleOrTypeNs,
1192+
Option<usize>,
1193+
Option<ImportOrExternCrate>,
1194+
ResolvePathResultPrefixInfo,
1195+
)> {
11631196
let (module_def, idx, prefix_info) = self.def_map.resolve_path_locally(
11641197
&self.local_def_map,
11651198
db,
11661199
self.module_id,
11671200
path,
11681201
BuiltinShadowMode::Other,
11691202
);
1170-
let (res, import) = to_type_ns(module_def)?;
1203+
let (res, import) = to_module_or_type_ns(module_def)?;
11711204
Some((res, idx, import, prefix_info))
11721205
}
11731206
}
@@ -1192,23 +1225,24 @@ fn to_value_ns(per_ns: PerNs) -> Option<(ValueNs, Option<ImportOrGlob>)> {
11921225
Some((res, import))
11931226
}
11941227

1195-
fn to_type_ns(per_ns: PerNs) -> Option<(TypeNs, Option<ImportOrExternCrate>)> {
1228+
fn to_module_or_type_ns(per_ns: PerNs) -> Option<(ModuleOrTypeNs, Option<ImportOrExternCrate>)> {
11961229
let def = per_ns.take_types_full()?;
11971230
let res = match def.def {
1198-
ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
1199-
ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it),
1231+
ModuleDefId::AdtId(it) => ModuleOrTypeNs::TypeNs(TypeNs::AdtId(it)),
1232+
ModuleDefId::EnumVariantId(it) => ModuleOrTypeNs::TypeNs(TypeNs::EnumVariantId(it)),
1233+
1234+
ModuleDefId::TypeAliasId(it) => ModuleOrTypeNs::TypeNs(TypeNs::TypeAliasId(it)),
1235+
ModuleDefId::BuiltinType(it) => ModuleOrTypeNs::TypeNs(TypeNs::BuiltinType(it)),
12001236

1201-
ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it),
1202-
ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it),
1237+
ModuleDefId::TraitId(it) => ModuleOrTypeNs::TypeNs(TypeNs::TraitId(it)),
1238+
ModuleDefId::TraitAliasId(it) => ModuleOrTypeNs::TypeNs(TypeNs::TraitAliasId(it)),
12031239

1204-
ModuleDefId::TraitId(it) => TypeNs::TraitId(it),
1205-
ModuleDefId::TraitAliasId(it) => TypeNs::TraitAliasId(it),
1240+
ModuleDefId::ModuleId(it) => ModuleOrTypeNs::ModuleNs(it),
12061241

12071242
ModuleDefId::FunctionId(_)
12081243
| ModuleDefId::ConstId(_)
12091244
| ModuleDefId::MacroId(_)
1210-
| ModuleDefId::StaticId(_)
1211-
| ModuleDefId::ModuleId(_) => return None,
1245+
| ModuleDefId::StaticId(_) => return None,
12121246
};
12131247
Some((res, def.import))
12141248
}

crates/hir-ty/src/lower/path.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use hir_def::{
1010
expr_store::HygieneId,
1111
generics::{TypeParamProvenance, WherePredicate, WherePredicateTypeTarget},
1212
path::{GenericArg, GenericArgs, GenericArgsParentheses, Path, PathSegment, PathSegments},
13-
resolver::{ResolveValueResult, TypeNs, ValueNs},
13+
resolver::{ModuleOrTypeNs, ResolveValueResult, TypeNs, ValueNs},
1414
type_ref::{TypeBound, TypeRef, TypesMap},
1515
};
1616
use smallvec::SmallVec;
@@ -333,10 +333,15 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
333333
}
334334

335335
pub(crate) fn resolve_path_in_type_ns(&mut self) -> Option<(TypeNs, Option<usize>)> {
336-
let (resolution, remaining_index, _, prefix_info) = self
336+
let (resolution, remaining_index, prefix_info) = self
337337
.ctx
338338
.resolver
339-
.resolve_path_in_type_ns_with_prefix_info(self.ctx.db.upcast(), self.path)?;
339+
.resolve_path_in_type_ns_with_prefix_info(self.ctx.db.upcast(), self.path)
340+
.filter_map(|(res, remaining_index, _, prefix_info)| match res {
341+
ModuleOrTypeNs::TypeNs(type_ns) => Some((type_ns, remaining_index, prefix_info)),
342+
ModuleOrTypeNs::ModuleNs(_) => None,
343+
})
344+
.next()?;
340345

341346
let segments = self.segments;
342347
if segments.is_empty() || matches!(self.path, Path::LangItem(..)) {

crates/hir/src/source_analyzer.rs

Lines changed: 55 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use hir_def::{
2525
lower::LowerCtx,
2626
nameres::MacroSubNs,
2727
path::{ModPath, Path, PathKind},
28-
resolver::{Resolver, TypeNs, ValueNs, resolver_for_scope},
28+
resolver::{ModuleOrTypeNs, Resolver, TypeNs, ValueNs, resolver_for_scope},
2929
type_ref::{Mutability, TypesMap, TypesSourceMap},
3030
};
3131
use hir_expand::{
@@ -1365,6 +1365,23 @@ pub(crate) fn resolve_hir_path_as_attr_macro(
13651365
.map(Into::into)
13661366
}
13671367

1368+
fn resolve_path_in_module_or_type_ns(
1369+
db: &dyn HirDatabase,
1370+
resolver: &Resolver,
1371+
path: &Path,
1372+
) -> Option<(ModuleOrTypeNs, Option<usize>)> {
1373+
let mut types = resolver
1374+
.resolve_path_in_type_ns(db.upcast(), path)
1375+
.map(|(ty, remaining_idx, _)| (ty, remaining_idx))
1376+
.peekable();
1377+
let (ty, _) = types.peek()?;
1378+
match ty {
1379+
ModuleOrTypeNs::ModuleNs(_) => types
1380+
.find_or_first(|(ty, _)| matches!(ty, ModuleOrTypeNs::TypeNs(TypeNs::BuiltinType(_)))),
1381+
ModuleOrTypeNs::TypeNs(_) => types.next(),
1382+
}
1383+
}
1384+
13681385
fn resolve_hir_path_(
13691386
db: &dyn HirDatabase,
13701387
resolver: &Resolver,
@@ -1384,10 +1401,10 @@ fn resolve_hir_path_(
13841401
resolver.type_owner(),
13851402
)
13861403
.lower_ty_ext(type_ref);
1387-
res.map(|ty_ns| (ty_ns, path.segments().first()))
1404+
res.map(|ty_ns| (ModuleOrTypeNs::TypeNs(ty_ns), path.segments().first()))
13881405
}
13891406
None => {
1390-
let (ty, remaining_idx, _) = resolver.resolve_path_in_type_ns(db.upcast(), path)?;
1407+
let (ty, remaining_idx) = resolve_path_in_module_or_type_ns(db, resolver, path)?;
13911408
match remaining_idx {
13921409
Some(remaining_idx) => {
13931410
if remaining_idx + 1 == path.segments().len() {
@@ -1403,25 +1420,30 @@ fn resolve_hir_path_(
14031420

14041421
// If we are in a TypeNs for a Trait, and we have an unresolved name, try to resolve it as a type
14051422
// within the trait's associated types.
1406-
if let (Some(unresolved), &TypeNs::TraitId(trait_id)) = (&unresolved, &ty) {
1423+
if let (Some(unresolved), ModuleOrTypeNs::TypeNs(TypeNs::TraitId(trait_id))) =
1424+
(&unresolved, &ty)
1425+
{
14071426
if let Some(type_alias_id) =
1408-
db.trait_items(trait_id).associated_type_by_name(unresolved.name)
1427+
db.trait_items(*trait_id).associated_type_by_name(unresolved.name)
14091428
{
14101429
return Some(PathResolution::Def(ModuleDefId::from(type_alias_id).into()));
14111430
}
14121431
}
14131432

14141433
let res = match ty {
1415-
TypeNs::SelfType(it) => PathResolution::SelfType(it.into()),
1416-
TypeNs::GenericParam(id) => PathResolution::TypeParam(id.into()),
1417-
TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => {
1418-
PathResolution::Def(Adt::from(it).into())
1419-
}
1420-
TypeNs::EnumVariantId(it) => PathResolution::Def(Variant::from(it).into()),
1421-
TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()),
1422-
TypeNs::BuiltinType(it) => PathResolution::Def(BuiltinType::from(it).into()),
1423-
TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()),
1424-
TypeNs::TraitAliasId(it) => PathResolution::Def(TraitAlias::from(it).into()),
1434+
ModuleOrTypeNs::TypeNs(ty) => match ty {
1435+
TypeNs::SelfType(it) => PathResolution::SelfType(it.into()),
1436+
TypeNs::GenericParam(id) => PathResolution::TypeParam(id.into()),
1437+
TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => {
1438+
PathResolution::Def(Adt::from(it).into())
1439+
}
1440+
TypeNs::EnumVariantId(it) => PathResolution::Def(Variant::from(it).into()),
1441+
TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()),
1442+
TypeNs::BuiltinType(it) => PathResolution::Def(BuiltinType::from(it).into()),
1443+
TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()),
1444+
TypeNs::TraitAliasId(it) => PathResolution::Def(TraitAlias::from(it).into()),
1445+
},
1446+
ModuleOrTypeNs::ModuleNs(it) => PathResolution::Def(ModuleDef::Module(it.into())),
14251447
};
14261448
match unresolved {
14271449
Some(unresolved) => resolver
@@ -1517,10 +1539,10 @@ fn resolve_hir_path_qualifier(
15171539
resolver.type_owner(),
15181540
)
15191541
.lower_ty_ext(type_ref);
1520-
res.map(|ty_ns| (ty_ns, path.segments().first()))
1542+
res.map(|ty_ns| (ModuleOrTypeNs::TypeNs(ty_ns), path.segments().first()))
15211543
}
15221544
None => {
1523-
let (ty, remaining_idx, _) = resolver.resolve_path_in_type_ns(db.upcast(), path)?;
1545+
let (ty, remaining_idx) = resolve_path_in_module_or_type_ns(db, resolver, path)?;
15241546
match remaining_idx {
15251547
Some(remaining_idx) => {
15261548
if remaining_idx + 1 == path.segments().len() {
@@ -1536,25 +1558,29 @@ fn resolve_hir_path_qualifier(
15361558

15371559
// If we are in a TypeNs for a Trait, and we have an unresolved name, try to resolve it as a type
15381560
// within the trait's associated types.
1539-
if let (Some(unresolved), &TypeNs::TraitId(trait_id)) = (&unresolved, &ty) {
1561+
if let (Some(unresolved), &ModuleOrTypeNs::TypeNs(TypeNs::TraitId(trait_id))) =
1562+
(&unresolved, &ty)
1563+
{
15401564
if let Some(type_alias_id) =
15411565
db.trait_items(trait_id).associated_type_by_name(unresolved.name)
15421566
{
15431567
return Some(PathResolution::Def(ModuleDefId::from(type_alias_id).into()));
15441568
}
15451569
}
1546-
15471570
let res = match ty {
1548-
TypeNs::SelfType(it) => PathResolution::SelfType(it.into()),
1549-
TypeNs::GenericParam(id) => PathResolution::TypeParam(id.into()),
1550-
TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => {
1551-
PathResolution::Def(Adt::from(it).into())
1552-
}
1553-
TypeNs::EnumVariantId(it) => PathResolution::Def(Variant::from(it).into()),
1554-
TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()),
1555-
TypeNs::BuiltinType(it) => PathResolution::Def(BuiltinType::from(it).into()),
1556-
TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()),
1557-
TypeNs::TraitAliasId(it) => PathResolution::Def(TraitAlias::from(it).into()),
1571+
ModuleOrTypeNs::TypeNs(ty) => match ty {
1572+
TypeNs::SelfType(it) => PathResolution::SelfType(it.into()),
1573+
TypeNs::GenericParam(id) => PathResolution::TypeParam(id.into()),
1574+
TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => {
1575+
PathResolution::Def(Adt::from(it).into())
1576+
}
1577+
TypeNs::EnumVariantId(it) => PathResolution::Def(Variant::from(it).into()),
1578+
TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()),
1579+
TypeNs::BuiltinType(it) => PathResolution::Def(BuiltinType::from(it).into()),
1580+
TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()),
1581+
TypeNs::TraitAliasId(it) => PathResolution::Def(TraitAlias::from(it).into()),
1582+
},
1583+
ModuleOrTypeNs::ModuleNs(it) => PathResolution::Def(ModuleDef::Module(it.into())),
15581584
};
15591585
match unresolved {
15601586
Some(unresolved) => resolver

0 commit comments

Comments
 (0)