diff options
-rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 3 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/path_resolution.rs | 38 | ||||
-rw-r--r-- | crates/hir_ty/src/tests/traits.rs | 30 |
3 files changed, 64 insertions, 7 deletions
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<'_> { | |||
478 | self.def_map.edition, | 478 | self.def_map.edition, |
479 | ); | 479 | ); |
480 | 480 | ||
481 | let res = self.def_map.resolve_name_in_extern_prelude(&extern_crate.name); | 481 | let res = self.def_map.resolve_name_in_extern_prelude(self.db, &extern_crate.name); |
482 | 482 | ||
483 | if let Some(ModuleDefId::ModuleId(m)) = res.take_types() { | 483 | if let Some(ModuleDefId::ModuleId(m)) = res.take_types() { |
484 | cov_mark::hit!(macro_rules_from_other_crates_are_visible_with_macro_use); | 484 | cov_mark::hit!(macro_rules_from_other_crates_are_visible_with_macro_use); |
@@ -534,6 +534,7 @@ impl DefCollector<'_> { | |||
534 | log::debug!("resolving import: {:?} ({:?})", import, self.def_map.edition); | 534 | log::debug!("resolving import: {:?} ({:?})", import, self.def_map.edition); |
535 | if import.is_extern_crate { | 535 | if import.is_extern_crate { |
536 | let res = self.def_map.resolve_name_in_extern_prelude( | 536 | let res = self.def_map.resolve_name_in_extern_prelude( |
537 | self.db, | ||
537 | &import | 538 | &import |
538 | .path | 539 | .path |
539 | .as_ident() | 540 | .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 { | |||
60 | } | 60 | } |
61 | 61 | ||
62 | impl DefMap { | 62 | impl DefMap { |
63 | pub(super) fn resolve_name_in_extern_prelude(&self, name: &Name) -> PerNs { | 63 | pub(super) fn resolve_name_in_extern_prelude( |
64 | &self, | ||
65 | db: &dyn DefDatabase, | ||
66 | name: &Name, | ||
67 | ) -> PerNs { | ||
64 | if name == &name!(self) { | 68 | if name == &name!(self) { |
65 | cov_mark::hit!(extern_crate_self_as); | 69 | cov_mark::hit!(extern_crate_self_as); |
66 | return PerNs::types(self.module_id(self.root).into(), Visibility::Public); | 70 | return PerNs::types(self.module_id(self.root).into(), Visibility::Public); |
67 | } | 71 | } |
68 | self.extern_prelude | 72 | |
73 | let arc; | ||
74 | let root = match self.block { | ||
75 | Some(_) => { | ||
76 | arc = self.crate_root(db).def_map(db); | ||
77 | &*arc | ||
78 | } | ||
79 | None => self, | ||
80 | }; | ||
81 | |||
82 | root.extern_prelude | ||
69 | .get(name) | 83 | .get(name) |
70 | .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public)) | 84 | .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public)) |
71 | } | 85 | } |
@@ -191,7 +205,7 @@ impl DefMap { | |||
191 | None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), | 205 | None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), |
192 | }; | 206 | }; |
193 | log::debug!("resolving {:?} in crate root (+ extern prelude)", segment); | 207 | log::debug!("resolving {:?} in crate root (+ extern prelude)", segment); |
194 | self.resolve_name_in_crate_root_or_extern_prelude(&segment) | 208 | self.resolve_name_in_crate_root_or_extern_prelude(db, &segment) |
195 | } | 209 | } |
196 | PathKind::Plain => { | 210 | PathKind::Plain => { |
197 | let (_, segment) = match segments.next() { | 211 | let (_, segment) = match segments.next() { |
@@ -394,9 +408,21 @@ impl DefMap { | |||
394 | from_legacy_macro.or(from_scope_or_builtin).or(from_extern_prelude).or(from_prelude) | 408 | from_legacy_macro.or(from_scope_or_builtin).or(from_extern_prelude).or(from_prelude) |
395 | } | 409 | } |
396 | 410 | ||
397 | fn resolve_name_in_crate_root_or_extern_prelude(&self, name: &Name) -> PerNs { | 411 | fn resolve_name_in_crate_root_or_extern_prelude( |
398 | let from_crate_root = self[self.root].scope.get(name); | 412 | &self, |
399 | let from_extern_prelude = self.resolve_name_in_extern_prelude(name); | 413 | db: &dyn DefDatabase, |
414 | name: &Name, | ||
415 | ) -> PerNs { | ||
416 | let arc; | ||
417 | let crate_def_map = match self.block { | ||
418 | Some(_) => { | ||
419 | arc = self.crate_root(db).def_map(db); | ||
420 | &arc | ||
421 | } | ||
422 | None => self, | ||
423 | }; | ||
424 | let from_crate_root = crate_def_map[crate_def_map.root].scope.get(name); | ||
425 | let from_extern_prelude = self.resolve_name_in_extern_prelude(db, name); | ||
400 | 426 | ||
401 | from_crate_root.or(from_extern_prelude) | 427 | from_crate_root.or(from_extern_prelude) |
402 | } | 428 | } |
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() { | |||
3413 | "#]], | 3413 | "#]], |
3414 | ); | 3414 | ); |
3415 | } | 3415 | } |
3416 | |||
3417 | #[test] | ||
3418 | fn renamed_extern_crate_in_block() { | ||
3419 | check_types( | ||
3420 | r#" | ||
3421 | //- /lib.rs crate:lib deps:serde | ||
3422 | use serde::Deserialize; | ||
3423 | |||
3424 | struct Foo {} | ||
3425 | |||
3426 | const _ : () = { | ||
3427 | extern crate serde as _serde; | ||
3428 | impl _serde::Deserialize for Foo { | ||
3429 | fn deserialize() -> u8 { 0 } | ||
3430 | } | ||
3431 | }; | ||
3432 | |||
3433 | fn foo() { | ||
3434 | Foo::deserialize(); | ||
3435 | //^^^^^^^^^^^^^^^^^^ u8 | ||
3436 | } | ||
3437 | |||
3438 | //- /serde.rs crate:serde | ||
3439 | |||
3440 | pub trait Deserialize { | ||
3441 | fn deserialize() -> u8; | ||
3442 | } | ||
3443 | "#, | ||
3444 | ); | ||
3445 | } | ||