From 2633e23f2bf0649031b887309cda1fecae063084 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Mon, 22 Mar 2021 18:47:19 +0100 Subject: resolver: manually traverse nested block scopes --- crates/hir_def/src/nameres.rs | 17 +++++++++++++++++ crates/hir_def/src/nameres/path_resolution.rs | 2 +- crates/hir_def/src/resolver.rs | 18 ++++++++++++++---- crates/hir_ty/src/tests/regression.rs | 13 +++++++++++++ 4 files changed, 45 insertions(+), 5 deletions(-) diff --git a/crates/hir_def/src/nameres.rs b/crates/hir_def/src/nameres.rs index 0d3a0b54f..9e8e4e9ec 100644 --- a/crates/hir_def/src/nameres.rs +++ b/crates/hir_def/src/nameres.rs @@ -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) { + 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 diff --git a/crates/hir_def/src/nameres/path_resolution.rs b/crates/hir_def/src/nameres/path_resolution.rs index db459b1ed..60471937c 100644 --- a/crates/hir_def/src/nameres/path_resolution.rs +++ b/crates/hir_def/src/nameres/path_resolution.rs @@ -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, diff --git a/crates/hir_def/src/resolver.rs b/crates/hir_def/src/resolver.rs index 04ea9c5d7..a73585ee7 100644 --- a/crates/hir_def/src/resolver.rs +++ b/crates/hir_def/src/resolver.rs @@ -548,7 +548,7 @@ impl ModuleItemMap { path: &ModPath, ) -> Option { 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)> { 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 } } diff --git a/crates/hir_ty/src/tests/regression.rs b/crates/hir_ty/src/tests/regression.rs index 69314e245..b69f86050 100644 --- a/crates/hir_ty/src/tests/regression.rs +++ b/crates/hir_ty/src/tests/regression.rs @@ -961,3 +961,16 @@ fn issue_6852() { "#]], ); } + +#[test] +fn param_overrides_fn() { + check_types( + r#" + fn example(example: i32) { + fn f() {} + example; + //^^^^^^^ i32 + } + "#, + ) +} -- cgit v1.2.3