Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/nameres/collector.rs')
| -rw-r--r-- | crates/hir-def/src/nameres/collector.rs | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs index b9aec93690..a37e3c70e2 100644 --- a/crates/hir-def/src/nameres/collector.rs +++ b/crates/hir-def/src/nameres/collector.rs @@ -31,7 +31,7 @@ use crate::{ item_scope::{ImportId, ImportOrExternCrate, ImportType, PerNsGlobImports}, item_tree::{ self, AttrOwner, FieldsShape, FileItemTreeId, ImportKind, ItemTree, ItemTreeId, - ItemTreeNode, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, TreeId, + ItemTreeNode, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, TreeId, UseTreeKind, }, macro_call_as_call_id, macro_call_as_call_id_with_eager, nameres::{ @@ -1058,8 +1058,33 @@ impl DefCollector<'_> { vis: Visibility, def_import_type: Option<ImportType>, ) -> bool { - if let Some((_, v, _)) = defs.types.as_mut() { - *v = v.min(vis, &self.def_map).unwrap_or(vis); + // `extern crate crate_name` things can be re-exported as `pub use crate_name`. + // But they cannot be re-exported as `pub use self::crate_name`, `pub use crate::crate_name` + // or `pub use ::crate_name`. + // + // This has been historically allowed, but may be not allowed in future + // https://github.com/rust-lang/rust/issues/127909 + if let Some((_, v, it)) = defs.types.as_mut() { + let is_extern_crate_reimport_without_prefix = || { + let Some(ImportOrExternCrate::ExternCrate(_)) = it else { + return false; + }; + let Some(ImportType::Import(id)) = def_import_type else { + return false; + }; + let use_id = id.import.lookup(self.db).id; + let item_tree = use_id.item_tree(self.db); + let use_kind = item_tree[use_id.value].use_tree.kind(); + let UseTreeKind::Single { path, .. } = use_kind else { + return false; + }; + path.segments().len() < 2 + }; + if is_extern_crate_reimport_without_prefix() { + *v = vis; + } else { + *v = v.min(vis, &self.def_map).unwrap_or(vis); + } } if let Some((_, v, _)) = defs.values.as_mut() { *v = v.min(vis, &self.def_map).unwrap_or(vis); |