Repository: rust-lang/rust-analyzer (rust)

Issue:
Public re-exports do not appear in code completion
<!--
Troubleshooting guide: https://rust-analyzer.github.io/manual.html#troubleshooting
Forum for questions: https://users.rust-lang.org/c/ide/14

Before submitting, please make sure that you're not running into one of these known issues:

 1. on-the-fly diagnostics are mostly unimplemented (`cargo check` diagnostics will be shown when saving a file): #3107

Otherwise please try to provide information which will help us to fix the issue faster. Minimal reproducible examples with few dependencies are especially lovely <3.
-->

**rust-analyzer version**: v0.3.1916

**rustc version**: 1.76.0

**editor or extension**: VSCodium

**relevant settings**: None

**code snippet to reproduce**: 

crate-a/lib.rs
```rust
pub fn add(a:i32,b:i32)->i32{
    a+b
}
```

crate-b/lib.rs
```rust
pub use crate_a::add as my_add;
```

crate-b/some.rs
```rust
fn xxx(){
    // type my_add here and there is no completion or auto-import.
}
```

<!-- TRIAGEBOT_START -->

<!-- TRIAGEBOT_ASSIGN_START -->

<!-- TRIAGEBOT_ASSIGN_DATA_START$${"user":"dqkqd"}$$TRIAGEBOT_ASSIGN_DATA_END -->

<!-- TRIAGEBOT_ASSIGN_END -->
<!-- TRIAGEBOT_END -->

Pull request description:
fix: auto-complete import for aliased function and module
Close #17042 

Get the aliased name from `import_path` to use for import instead of name defined inside local module.

![image](https://github.com/user-attachments/assets/e69be963-3a78-4b62-b5ba-0990cd94c5e2)


Patch:
diff --git a/crates/ide-completion/src/render.rs b/crates/ide-completion/src/render.rs
index 4dd171142f..d146990c5a 100644
--- a/crates/ide-completion/src/render.rs
+++ b/crates/ide-completion/src/render.rs
@@ -281,8 +281,8 @@ pub(crate) fn render_resolution_with_import(
     import_edit: LocatedImport,
 ) -> Option<Builder> {
     let resolution = ScopeDef::from(import_edit.original_item);
-    let local_name = scope_def_to_name(resolution, &ctx, &import_edit)?;
-    //this now just renders the alias text, but we need to find the aliases earlier and call this with the alias instead
+    let local_name = get_import_name(resolution, &ctx, &import_edit)?;
+    // This now just renders the alias text, but we need to find the aliases earlier and call this with the alias instead.
     let doc_aliases = ctx.completion.doc_aliases_in_scope(resolution);
     let ctx = ctx.doc_aliases(doc_aliases);
     Some(render_resolution_path(ctx, path_ctx, local_name, Some(import_edit), resolution))
@@ -294,7 +294,7 @@ pub(crate) fn render_resolution_with_import_pat(
     import_edit: LocatedImport,
 ) -> Option<Builder> {
     let resolution = ScopeDef::from(import_edit.original_item);
-    let local_name = scope_def_to_name(resolution, &ctx, &import_edit)?;
+    let local_name = get_import_name(resolution, &ctx, &import_edit)?;
     Some(render_resolution_pat(ctx, pattern_ctx, local_name, Some(import_edit), resolution))
 }
 
@@ -357,6 +357,24 @@ pub(crate) fn render_expr(
     Some(item)
 }
 
+fn get_import_name(
+    resolution: ScopeDef,
+    ctx: &RenderContext<'_>,
+    import_edit: &LocatedImport,
+) -> Option<hir::Name> {
+    // FIXME: Temporary workaround for handling aliased import.
+    // This should be removed after we have proper support for importing alias.
+    // <https://github.com/rust-lang/rust-analyzer/issues/14079>
+
+    // If `item_to_import` matches `original_item`, we are importing the item itself (not its parent module).
+    // In this case, we can use the last segment of `import_path`, as it accounts for the aliased name.
+    if import_edit.item_to_import == import_edit.original_item {
+        import_edit.import_path.segments().last().cloned()
+    } else {
+        scope_def_to_name(resolution, ctx, import_edit)
+    }
+}
+
 fn scope_def_to_name(
     resolution: ScopeDef,
     ctx: &RenderContext<'_>,


Test patch:
diff --git a/crates/ide-completion/src/tests/flyimport.rs b/crates/ide-completion/src/tests/flyimport.rs
index 0b532064fb..4b949e0d65 100644
--- a/crates/ide-completion/src/tests/flyimport.rs
+++ b/crates/ide-completion/src/tests/flyimport.rs
@@ -1669,3 +1669,54 @@ mod module {
         "#]],
     );
 }
+
+#[test]
+fn re_export_aliased() {
+    check(
+        r#"
+mod outer {
+    mod inner {
+        pub struct BarStruct;
+        pub fn bar_fun() {}
+        pub mod bar {}
+    }
+    pub use inner::bar as foo;
+    pub use inner::bar_fun as foo_fun;
+    pub use inner::BarStruct as FooStruct;
+}
+fn function() {
+    foo$0
+}
+"#,
+        expect![[r#"
+            st FooStruct (use outer::FooStruct) BarStruct
+            md foo (use outer::foo)
+            fn foo_fun() (use outer::foo_fun) fn()
+        "#]],
+    );
+}
+
+#[test]
+fn re_export_aliased_pattern() {
+    check(
+        r#"
+mod outer {
+    mod inner {
+        pub struct BarStruct;
+        pub fn bar_fun() {}
+        pub mod bar {}
+    }
+    pub use inner::bar as foo;
+    pub use inner::bar_fun as foo_fun;
+    pub use inner::BarStruct as FooStruct;
+}
+fn function() {
+    let foo$0
+}
+"#,
+        expect![[r#"
+            st FooStruct (use outer::FooStruct)
+            md foo (use outer::foo)
+        "#]],
+    );
+}