resolver: manually traverse nested block scopes

This commit is contained in:
Jonas Schievink 2021-03-22 18:47:19 +01:00
parent 94aa3a7b1a
commit 2633e23f2b
4 changed files with 45 additions and 5 deletions

View file

@ -322,6 +322,23 @@ impl DefMap {
(res.resolved_def, res.segment_index)
}
pub(crate) fn resolve_path_locally(
&self,
db: &dyn DefDatabase,
original_module: LocalModuleId,
path: &ModPath,
shadow: BuiltinShadowMode,
) -> (PerNs, Option<usize>) {
let res = self.resolve_path_fp_with_macro_single(
db,
ResolveMode::Other,
original_module,
path,
shadow,
);
(res.resolved_def, res.segment_index)
}
/// Ascends the `DefMap` hierarchy and calls `f` with every `DefMap` and containing module.
///
/// If `f` returns `Some(val)`, iteration is stopped and `Some(val)` is returned. If `f` returns

View file

@ -156,7 +156,7 @@ impl DefMap {
}
}
fn resolve_path_fp_with_macro_single(
pub(super) fn resolve_path_fp_with_macro_single(
&self,
db: &dyn DefDatabase,
mode: ResolveMode,

View file

@ -548,7 +548,7 @@ impl ModuleItemMap {
path: &ModPath,
) -> Option<ResolveValueResult> {
let (module_def, idx) =
self.def_map.resolve_path(db, self.module_id, &path, BuiltinShadowMode::Other);
self.def_map.resolve_path_locally(db, self.module_id, &path, BuiltinShadowMode::Other);
match idx {
None => {
let value = to_value_ns(module_def)?;
@ -578,7 +578,7 @@ impl ModuleItemMap {
path: &ModPath,
) -> Option<(TypeNs, Option<usize>)> {
let (module_def, idx) =
self.def_map.resolve_path(db, self.module_id, &path, BuiltinShadowMode::Other);
self.def_map.resolve_path_locally(db, self.module_id, &path, BuiltinShadowMode::Other);
let res = to_type_ns(module_def)?;
Some((res, idx))
}
@ -627,8 +627,18 @@ pub trait HasResolver: Copy {
impl HasResolver for ModuleId {
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
let def_map = self.def_map(db);
Resolver::default().push_module_scope(def_map, self.local_id)
let mut def_map = self.def_map(db);
let mut modules = Vec::new();
modules.push((def_map.clone(), self.local_id));
while let Some(parent) = def_map.parent() {
def_map = parent.def_map(db);
modules.push((def_map.clone(), parent.local_id));
}
let mut resolver = Resolver::default();
for (def_map, module) in modules.into_iter().rev() {
resolver = resolver.push_module_scope(def_map, module);
}
resolver
}
}

View file

@ -961,3 +961,16 @@ fn issue_6852() {
"#]],
);
}
#[test]
fn param_overrides_fn() {
check_types(
r#"
fn example(example: i32) {
fn f() {}
example;
//^^^^^^^ i32
}
"#,
)
}