Repository: intellij-rust/intellij-rust
Issue: Non-imported enums are not suggested in autocompletion list

Follow-up for #2721. Importing structs works like a charm now, but importing enums is not possible this way. For example:
```rust
mod a {
    pub struct MyAbc;
    pub enum MyDef {
        MyDefVar1,
        MyDefVar2,
    }
}
mod c {
    use crate::a::MyDef::MyDefVar1;

    fn x() {
        [cursor here]

    }
}
```
At the cursor position, the plugin suggests `MyDefVar1` and `MyDefVar2`, so I can import the variant by choosing the suggested item. But most often I want to import the enum itself, and `MyDef` is absent in the suggestion list. `MyAbc` is suggested and can be imported properly.



Changed files:
src/main/kotlin/org/rust/lang/core/completion/RsCommonCompletionProvider.kt
src/test/kotlin/org/rust/lang/core/completion/RsPathCompletionFromIndexProviderTest.kt
src/main/kotlin/org/rust/ide/inspections/import/AutoImportFix.kt

diff --git a/src/main/kotlin/org/rust/ide/inspections/import/AutoImportFix.kt b/src/main/kotlin/org/rust/ide/inspections/import/AutoImportFix.kt
index 1fd1c1457..dc659cf47 100644
--- a/src/main/kotlin/org/rust/ide/inspections/import/AutoImportFix.kt
+++ b/src/main/kotlin/org/rust/ide/inspections/import/AutoImportFix.kt
@@ -101,7 +101,7 @@ class AutoImportFix(element: RsElement) : LocalQuickFixOnPsiElement(element), Hi
                 return Context(basePath, emptyList())
             }
 
-            val candidates = getImportCandidates(ImportContext.from(project, path), basePath.referenceName, path.text) {
+            val candidates = getImportCandidates(ImportContext.from(project, path, false), basePath.referenceName, path.text) {
                 path != basePath || !(it.item is RsMod || it.item is RsModDeclItem || it.item.parent is RsMembers)
             }.toList()
 
@@ -397,7 +397,7 @@ sealed class ImportInfo {
 
 data class ImportCandidate(val qualifiedNamedItem: QualifiedNamedItem, val info: ImportInfo)
 
-private val RsPath.namespaceFilter: (RsQualifiedNamedElement) -> Boolean get() = when (context) {
+private fun RsPath.namespaceFilter(isCompletion: Boolean): (RsQualifiedNamedElement) -> Boolean = when (context) {
     is RsTypeElement -> { e ->
         when (e) {
             is RsEnumItem,
@@ -409,6 +409,7 @@ private val RsPath.namespaceFilter: (RsQualifiedNamedElement) -> Boolean get() =
     }
     is RsPathExpr -> { e ->
         when (e) {
+            is RsEnumItem -> isCompletion
             // TODO: take into account fields type
             is RsFieldsOwner,
             is RsConstant,
@@ -515,14 +516,14 @@ data class ImportContext private constructor(
     val namespaceFilter: (RsQualifiedNamedElement) -> Boolean
 ) {
     companion object {
-        fun from(project: Project, path: RsPath): ImportContext = ImportContext(
+        fun from(project: Project, path: RsPath, isCompletion: Boolean): ImportContext = ImportContext(
             project = project,
             mod = path.containingMod,
             superMods = LinkedHashSet(path.containingMod.superMods),
             scope = RsCargoProjectScope(project.cargoProjects, GlobalSearchScope.allScope(project)),
             ns = path.pathNamespace,
             attributes = path.stdlibAttributes,
-            namespaceFilter = path.namespaceFilter
+            namespaceFilter = path.namespaceFilter(isCompletion)
         )
     }
 }
diff --git a/src/main/kotlin/org/rust/lang/core/completion/RsCommonCompletionProvider.kt b/src/main/kotlin/org/rust/lang/core/completion/RsCommonCompletionProvider.kt
index 0af1e9099..9cd8fc16e 100644
--- a/src/main/kotlin/org/rust/lang/core/completion/RsCommonCompletionProvider.kt
+++ b/src/main/kotlin/org/rust/lang/core/completion/RsCommonCompletionProvider.kt
@@ -122,7 +122,7 @@ object RsCommonCompletionProvider : CompletionProvider<CompletionParameters>() {
         Testmarks.pathCompletionFromIndex.hit()
 
         val project = parameters.originalFile.project
-        val importContext = ImportContext.from(project, path)
+        val importContext = ImportContext.from(project, path, true)
         val pathMod = path.containingMod
 
         val keys = hashSetOf<String>().apply {
diff --git a/src/test/kotlin/org/rust/lang/core/completion/RsPathCompletionFromIndexProviderTest.kt b/src/test/kotlin/org/rust/lang/core/completion/RsPathCompletionFromIndexTest.kt
similarity index 62%
rename from src/test/kotlin/org/rust/lang/core/completion/RsPathCompletionFromIndexProviderTest.kt
rename to src/test/kotlin/org/rust/lang/core/completion/RsPathCompletionFromIndexTest.kt
index 6df9d68e6..7b614603c 100644
--- a/src/test/kotlin/org/rust/lang/core/completion/RsPathCompletionFromIndexProviderTest.kt
+++ b/src/test/kotlin/org/rust/lang/core/completion/RsPathCompletionFromIndexTest.kt
@@ -6,20 +6,26 @@
 package org.rust.lang.core.completion
 
 import org.intellij.lang.annotations.Language
-import org.rust.ProjectDescriptor
-import org.rust.WithStdlibRustProjectDescriptor
 import org.rust.hasCaretMarker
 import org.rust.lang.core.completion.RsCommonCompletionProvider.Testmarks
 import org.rust.openapiext.Testmark
 
-@ProjectDescriptor(WithStdlibRustProjectDescriptor::class)
-class RsPathCompletionFromIndexProviderTest : RsCompletionTestBase() {
+class RsPathCompletionFromIndexTest : RsCompletionTestBase() {
+
     fun `test suggest an non-imported symbol from index and add proper import`() = doSingleCompletion("""
+        mod collections {
+            pub struct BTreeMap;
+        }
+
         fn main() {
             let _ = BTreeM/*caret*/
         }
     """, """
-        use std::collections::BTreeMap;
+        use collections::BTreeMap;
+
+        mod collections {
+            pub struct BTreeMap;
+        }
 
         fn main() {
             let _ = BTreeMap/*caret*/
@@ -27,13 +33,21 @@ class RsPathCompletionFromIndexProviderTest : RsCompletionTestBase() {
     """)
 
     fun `test doesn't suggest a symbol that already in scope`() = doSingleCompletion("""
-        use std::collections::BTreeMap;
+        use collections::BTreeMap;
+
+        mod collections {
+            pub struct BTreeMap;
+        }
 
         fn main() {
             let _ = BTreeM/*caret*/
         }
     """, """
-        use std::collections::BTreeMap;
+        use collections::BTreeMap;
+
+        mod collections {
+            pub struct BTreeMap;
+        }
 
         fn main() {
             let _ = BTreeMap/*caret*/
@@ -43,12 +57,20 @@ class RsPathCompletionFromIndexProviderTest : RsCompletionTestBase() {
     fun `test doesn't suggest a symbol that leads to name collision`() = doSingleCompletion("""
         struct BTreeMap;
 
+        mod collections {
+            pub struct BTreeMap;
+        }
+
         fn main() {
             let _ = BTreeM/*caret*/
         }
     """, """
         struct BTreeMap;
 
+        mod collections {
+            pub struct BTreeMap;
+        }
+
         fn main() {
             let _ = BTreeMap/*caret*/
         }
@@ -61,6 +83,30 @@ class RsPathCompletionFromIndexProviderTest : RsCompletionTestBase() {
         }
     """, Testmarks.pathCompletionFromIndex)
 
+    fun `test enum completion`() = doSingleCompletion("""
+        mod a {
+            pub enum Enum {
+                V1, V2
+            }
+        }
+
+        fn main() {
+            let a = Enu/*caret*/
+        }
+    """, """
+        use a::Enum;
+
+        mod a {
+            pub enum Enum {
+                V1, V2
+            }
+        }
+
+        fn main() {
+            let a = Enum/*caret*/
+        }
+    """)
+
     private fun doTest(@Language("Rust") text: String, testmark: Testmark) {
         check(hasCaretMarker(text)) {
             "Please add `/*caret*/` marker"