Repository: intellij-rust/intellij-rust
Issue: Nest use statements combines `pub` and non-`pub` erroneously

## Environment

* **IntelliJ Rust plugin version:** 0.2.113.2150-193
* **Rust toolchain version:** 1.40
* **IDE name and version:** Clion 2019.3
* **Operating system:** Linux

## Problem description
The "nest use statements" intention incorrectly combines pub and non-pub uses into one.

## Steps to reproduce
```rust
pub use std::fmt::Debug;

use std::fmt::Display;
use std::fmt::self;
```

Running the nest use statements on the lower two lines will result in all three being combined instead of just the bottom two.


Thanks!


Changed files:
src/main/kotlin/org/rust/ide/intentions/NestUseStatementsIntention.kt, src/test/kotlin/org/rust/ide/intentions/NestUseStatementsIntentionTest.kt

diff --git a/src/main/kotlin/org/rust/ide/intentions/NestUseStatementsIntention.kt b/src/main/kotlin/org/rust/ide/intentions/NestUseStatementsIntention.kt
index 27438fada..d8f85383b 100644
--- a/src/main/kotlin/org/rust/ide/intentions/NestUseStatementsIntention.kt
+++ b/src/main/kotlin/org/rust/ide/intentions/NestUseStatementsIntention.kt
@@ -93,7 +93,7 @@ class NestUseStatementsIntention : RsElementBaseIntentionAction<NestUseStatement
     }
 
     class PathInUseItem(
-        useItem: RsUseItem,
+        private val useItem: RsUseItem,
         useItems: List<RsUseItem>,
         override val basePath: String
     ) : Context {
@@ -103,11 +103,12 @@ class NestUseStatementsIntention : RsElementBaseIntentionAction<NestUseStatement
                 val useItemList = mutableListOf<RsUseItem>()
 
                 val basePath = useSpeck.path?.let { getBasePathFromPath(it) } ?: return null
+                val visibility = useItemOnCursor.visibility
                 useItemList += useItemOnCursor.leftSiblings.filterIsInstance<RsUseItem>()
-                    .filter { it.useSpeck?.path?.let { getBasePathFromPath(it) } == basePath }
+                    .filter { it.useSpeck?.path?.let { getBasePathFromPath(it) } == basePath && it.visibility == visibility }
                 useItemList.add(useItemOnCursor)
                 useItemList += useItemOnCursor.rightSiblings.filterIsInstance<RsUseItem>()
-                    .filter { it.useSpeck?.path?.let { getBasePathFromPath(it) } == basePath }
+                    .filter { it.useSpeck?.path?.let { getBasePathFromPath(it) } == basePath && it.visibility == visibility }
                 if (useItemList.size == 1) return null
 
                 return PathInUseItem(useItemOnCursor, useItemList, basePath)
@@ -115,7 +116,7 @@ class NestUseStatementsIntention : RsElementBaseIntentionAction<NestUseStatement
         }
 
         override fun createElement(path: String, project: Project): PsiElement {
-            return RsPsiFactory(project).createUseItem(path)
+            return RsPsiFactory(project).createUseItem(path, useItem.vis?.text ?: "")
         }
 
         override val useSpecks: List<RsUseSpeck> = useItems.mapNotNull { it.useSpeck }
diff --git a/src/test/kotlin/org/rust/ide/intentions/NestUseStatementsIntentionTest.kt b/src/test/kotlin/org/rust/ide/intentions/NestUseStatementsIntentionTest.kt
index 8f964a024..203bb76e9 100644
--- a/src/test/kotlin/org/rust/ide/intentions/NestUseStatementsIntentionTest.kt
+++ b/src/test/kotlin/org/rust/ide/intentions/NestUseStatementsIntentionTest.kt
@@ -264,4 +264,38 @@ class NestUseStatementsIntentionTest : RsIntentionTestBase(NestUseStatementsInte
         };
 
     """)
+
+    fun `test pub and non-pub on pub`() = doAvailableTest("""
+        pub use a::b1;
+        use a::b2;
+        pub use a::b3/*caret*/;
+        use a::b4;
+        pub use a::b5;
+    """, """
+        pub use a::{
+            b1,
+            b3,
+            b5
+        };
+        use a::b2;
+        use a::b4;
+
+    """)
+
+    fun `test pub and non-pub on non-pub`() = doAvailableTest("""
+        use a::b1;
+        pub use a::b2;
+        use a::b3/*caret*/;
+        pub use a::b4;
+        use a::b5;
+    """, """
+        use a::{
+            b1,
+            b3,
+            b5
+        };
+        pub use a::b2;
+        pub use a::b4;
+
+    """)
 }