From 75614b126b0fb7c0f1f7da4b4f37c32c56712fc7 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Fri, 9 Apr 2021 15:25:12 +0200 Subject: Resolve prelude and crate root names in the root DefMap --- crates/hir_def/src/nameres/collector.rs | 3 ++- crates/hir_def/src/nameres/path_resolution.rs | 38 ++++++++++++++++++++++----- crates/hir_ty/src/tests/traits.rs | 30 +++++++++++++++++++++ 3 files changed, 64 insertions(+), 7 deletions(-) (limited to 'crates') diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index d13d7be27..fb4ddff5e 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs @@ -478,7 +478,7 @@ impl DefCollector<'_> { self.def_map.edition, ); - let res = self.def_map.resolve_name_in_extern_prelude(&extern_crate.name); + let res = self.def_map.resolve_name_in_extern_prelude(self.db, &extern_crate.name); if let Some(ModuleDefId::ModuleId(m)) = res.take_types() { cov_mark::hit!(macro_rules_from_other_crates_are_visible_with_macro_use); @@ -534,6 +534,7 @@ impl DefCollector<'_> { log::debug!("resolving import: {:?} ({:?})", import, self.def_map.edition); if import.is_extern_crate { let res = self.def_map.resolve_name_in_extern_prelude( + self.db, &import .path .as_ident() diff --git a/crates/hir_def/src/nameres/path_resolution.rs b/crates/hir_def/src/nameres/path_resolution.rs index a9cf651d2..ccc9f22eb 100644 --- a/crates/hir_def/src/nameres/path_resolution.rs +++ b/crates/hir_def/src/nameres/path_resolution.rs @@ -60,12 +60,26 @@ impl ResolvePathResult { } impl DefMap { - pub(super) fn resolve_name_in_extern_prelude(&self, name: &Name) -> PerNs { + pub(super) fn resolve_name_in_extern_prelude( + &self, + db: &dyn DefDatabase, + name: &Name, + ) -> PerNs { if name == &name!(self) { cov_mark::hit!(extern_crate_self_as); return PerNs::types(self.module_id(self.root).into(), Visibility::Public); } - self.extern_prelude + + let arc; + let root = match self.block { + Some(_) => { + arc = self.crate_root(db).def_map(db); + &*arc + } + None => self, + }; + + root.extern_prelude .get(name) .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public)) } @@ -191,7 +205,7 @@ impl DefMap { None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), }; log::debug!("resolving {:?} in crate root (+ extern prelude)", segment); - self.resolve_name_in_crate_root_or_extern_prelude(&segment) + self.resolve_name_in_crate_root_or_extern_prelude(db, &segment) } PathKind::Plain => { let (_, segment) = match segments.next() { @@ -394,9 +408,21 @@ impl DefMap { from_legacy_macro.or(from_scope_or_builtin).or(from_extern_prelude).or(from_prelude) } - fn resolve_name_in_crate_root_or_extern_prelude(&self, name: &Name) -> PerNs { - let from_crate_root = self[self.root].scope.get(name); - let from_extern_prelude = self.resolve_name_in_extern_prelude(name); + fn resolve_name_in_crate_root_or_extern_prelude( + &self, + db: &dyn DefDatabase, + name: &Name, + ) -> PerNs { + let arc; + let crate_def_map = match self.block { + Some(_) => { + arc = self.crate_root(db).def_map(db); + &arc + } + None => self, + }; + let from_crate_root = crate_def_map[crate_def_map.root].scope.get(name); + let from_extern_prelude = self.resolve_name_in_extern_prelude(db, name); from_crate_root.or(from_extern_prelude) } diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs index 65b71fdfa..1c1aa491d 100644 --- a/crates/hir_ty/src/tests/traits.rs +++ b/crates/hir_ty/src/tests/traits.rs @@ -3413,3 +3413,33 @@ fn foo() { "#]], ); } + +#[test] +fn renamed_extern_crate_in_block() { + check_types( + r#" +//- /lib.rs crate:lib deps:serde +use serde::Deserialize; + +struct Foo {} + +const _ : () = { + extern crate serde as _serde; + impl _serde::Deserialize for Foo { + fn deserialize() -> u8 { 0 } + } +}; + +fn foo() { + Foo::deserialize(); + //^^^^^^^^^^^^^^^^^^ u8 +} + +//- /serde.rs crate:serde + +pub trait Deserialize { + fn deserialize() -> u8; +} + "#, + ); +} -- cgit v1.2.3