diff --git a/crates/hir_def/src/nameres/path_resolution.rs b/crates/hir_def/src/nameres/path_resolution.rs index 8258dcffbc6..db459b1ed84 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 { } } - pub(super) fn resolve_path_fp_with_macro_single( + fn resolve_path_fp_with_macro_single( &self, db: &dyn DefDatabase, mode: ResolveMode, @@ -384,10 +384,16 @@ impl DefMap { } } }; - let from_extern_prelude = self - .extern_prelude - .get(name) - .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public)); + // Give precedence to names in outer `DefMap`s over the extern prelude; only check prelude + // from the crate DefMap. + let from_extern_prelude = match self.block { + Some(_) => PerNs::none(), + None => self + .extern_prelude + .get(name) + .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public)), + }; + let from_prelude = self.resolve_in_prelude(db, name); from_legacy_macro.or(from_scope_or_builtin).or(from_extern_prelude).or(from_prelude) diff --git a/crates/hir_ty/src/diagnostics.rs b/crates/hir_ty/src/diagnostics.rs index 6bca7aa0dbb..86f937e1d3a 100644 --- a/crates/hir_ty/src/diagnostics.rs +++ b/crates/hir_ty/src/diagnostics.rs @@ -705,6 +705,35 @@ fn x(a: S) { ) } + #[test] + fn import_extern_crate_clash_with_inner_item() { + // This is more of a resolver test, but doesn't really work with the hir_def testsuite. + + check_diagnostics( + r#" +//- /lib.rs crate:lib deps:jwt +mod permissions; + +use permissions::jwt; + +fn f() { + fn inner() {} + jwt::Claims {}; // should resolve to the local one with 0 fields, and not get a diagnostic +} + +//- /permissions.rs +pub mod jwt { + pub struct Claims {} +} + +//- /jwt/lib.rs crate:jwt +pub struct Claims { + field: u8, +} + "#, + ); + } + #[test] fn break_outside_of_loop() { check_diagnostics(