fix: Allow public re-export of `extern crate` import
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs
index 91a8cba..dba11d4 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs
@@ -967,6 +967,11 @@
         self.expand_impl(None, &mut cb)
     }
 
+    /// The [`UseTreeKind`] of this `UseTree`.
+    pub fn kind(&self) -> &UseTreeKind {
+        &self.kind
+    }
+
     fn expand_impl(
         &self,
         prefix: Option<ModPath>,
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
index b9aec93..a37e3c7 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
@@ -31,7 +31,7 @@
     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 @@
         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);
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs
index 7b02a89..e1e30e5 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs
@@ -386,6 +386,52 @@
 }
 
 #[test]
+fn extern_crate_reexport() {
+    check(
+        r#"
+//- /main.rs crate:main deps:importer
+use importer::*;
+use importer::extern_crate1::exported::*;
+use importer::allowed_reexport::*;
+use importer::extern_crate2::*;
+use importer::not_allowed_reexport1;
+use importer::not_allowed_reexport2;
+
+//- /importer.rs crate:importer deps:extern_crate1,extern_crate2
+extern crate extern_crate1;
+extern crate extern_crate2;
+
+pub use extern_crate1;
+pub use extern_crate1 as allowed_reexport;
+
+pub use ::extern_crate;
+pub use self::extern_crate as not_allowed_reexport1;
+pub use crate::extern_crate as not_allowed_reexport2;
+
+//- /extern_crate1.rs crate:extern_crate1
+pub mod exported {
+    pub struct PublicItem;
+    struct PrivateItem;
+}
+
+pub struct Exported;
+
+//- /extern_crate2.rs crate:extern_crate2
+pub struct NotExported;
+"#,
+        expect![[r#"
+            crate
+            Exported: t v
+            PublicItem: t v
+            allowed_reexport: t
+            exported: t
+            not_allowed_reexport1: _
+            not_allowed_reexport2: _
+        "#]],
+    );
+}
+
+#[test]
 fn extern_crate_rename_2015_edition() {
     check(
         r#"