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.rs49
1 files changed, 41 insertions, 8 deletions
diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs
index 22b9c2b4e3..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::{
@@ -985,12 +985,8 @@ impl DefCollector<'_> {
for (name, res) in resolutions {
match name {
Some(name) => {
- changed |= self.push_res_and_update_glob_vis(
- module_id,
- name,
- res.with_visibility(vis),
- import,
- );
+ changed |=
+ self.push_res_and_update_glob_vis(module_id, name, *res, vis, import);
}
None => {
let tr = match res.take_types() {
@@ -1043,10 +1039,11 @@ impl DefCollector<'_> {
.collect::<Vec<_>>();
for (glob_importing_module, glob_import_vis, use_) in glob_imports {
+ let vis = glob_import_vis.min(vis, &self.def_map).unwrap_or(glob_import_vis);
self.update_recursive(
glob_importing_module,
resolutions,
- glob_import_vis,
+ vis,
Some(ImportType::Glob(use_)),
depth + 1,
);
@@ -1058,8 +1055,44 @@ impl DefCollector<'_> {
module_id: LocalModuleId,
name: &Name,
mut defs: PerNs,
+ vis: Visibility,
def_import_type: Option<ImportType>,
) -> bool {
+ // `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);
+ }
+ if let Some((_, v, _)) = defs.macros.as_mut() {
+ *v = v.min(vis, &self.def_map).unwrap_or(vis);
+ }
+
let mut changed = false;
if let Some(ImportType::Glob(_)) = def_import_type {