Repository: intellij-rust/intellij-rust
Issue: Exception in Move Statement Up/Down actions

## Environment

* **IntelliJ Rust plugin version:** 0.3.138.3572-203
* **Rust toolchain version:** 1.48.0 (7eac88abb 2020-11-16) x86_64-apple-darwin
* **IDE name and version:** CLion 2020.3 (CL-203.5981.166)
* **Operating system:** macOS 10.16
* **Macro expansion engine:** new
* **Name resolution engine:** new

## Problem description
Exception stack trace:
```
Cannot perform move

com.intellij.diagnostic.PluginException: Wrong move ranges requested by org.rust.ide.actions.mover.RsCommaListElementUpDownMover@1abe9785 1114:1187 vs 1086:1131 [Plugin: org.rust.lang]
	at com.intellij.ide.plugins.PluginManagerCore.createPluginException(PluginManagerCore.java:335)
	at com.intellij.diagnostic.PluginProblemReporterImpl.createPluginExceptionByClass(PluginProblemReporterImpl.java:12)
	at com.intellij.diagnostic.PluginException.createByClass(PluginException.java:59)
	at com.intellij.codeInsight.editorActions.moveUpDown.MoverWrapper.move(MoverWrapper.java:92)
	at com.intellij.codeInsight.editorActions.moveUpDown.BaseMoveHandler.executeWriteAction(BaseMoveHandler.java:57)
	at com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler$1.run(EditorWriteActionHandler.java:51)
```

## Steps to reproduce
```Rust
fn foo() {
    bar(
        Baz {
            x
        }, vec![
            1,
            2, // <caret> Move Statement Up/Down (`Cmd + Shift + Up/Down Arrow`)
            3,
        ],
    );
}
```

Changed files:
src/main/kotlin/org/rust/ide/formatter/impl/utils.kt, src/test/kotlin/org/rust/ide/actions/mover/RsCommaListElementUpDownMoverTest.kt, src/main/kotlin/org/rust/ide/actions/mover/RsCommaListElementUpDownMover.kt, src/main/kotlin/org/rust/ide/actions/mover/RsLineMover.kt

diff --git a/src/main/kotlin/org/rust/ide/actions/mover/RsCommaListElementUpDownMover.kt b/src/main/kotlin/org/rust/ide/actions/mover/RsCommaListElementUpDownMover.kt
index 460192c39..12e9d2e58 100644
--- a/src/main/kotlin/org/rust/ide/actions/mover/RsCommaListElementUpDownMover.kt
+++ b/src/main/kotlin/org/rust/ide/actions/mover/RsCommaListElementUpDownMover.kt
@@ -49,7 +49,13 @@ class RsCommaListElementUpDownMover : RsLineMover() {
     }
 
     override fun findTargetElement(sibling: PsiElement, down: Boolean): PsiElement? {
-        if (isMovingOutOfParenBlock(sibling, down) || isMovingOutOfBraceBlock(sibling, down)) return null
+        if (isMovingOutOfParenBlock(sibling, down) ||
+            isMovingOutOfBraceBlock(sibling, down) ||
+            isMovingOutOfBracketBlock(sibling, down)
+        ) {
+            UpDownMoverTestMarks.moveOutOfBlock.hit()
+            return null
+        }
         return sibling
     }
 
diff --git a/src/main/kotlin/org/rust/ide/actions/mover/RsLineMover.kt b/src/main/kotlin/org/rust/ide/actions/mover/RsLineMover.kt
index a74efce32..402e91026 100644
--- a/src/main/kotlin/org/rust/ide/actions/mover/RsLineMover.kt
+++ b/src/main/kotlin/org/rust/ide/actions/mover/RsLineMover.kt
@@ -88,6 +88,9 @@ abstract class RsLineMover : LineMover() {
         fun isMovingOutOfParenBlock(sibling: PsiElement, down: Boolean): Boolean =
             sibling.elementType == (if (down) RsElementTypes.RPAREN else RsElementTypes.LPAREN)
 
+        fun isMovingOutOfBracketBlock(sibling: PsiElement, down: Boolean): Boolean =
+            sibling.elementType == (if (down) RsElementTypes.RBRACK else RsElementTypes.LBRACK)
+
         fun isMovingOutOfFunctionBody(sibling: PsiElement, down: Boolean): Boolean =
             isMovingOutOfBraceBlock(sibling, down) && sibling.parent?.parent is RsFunction
 
@@ -100,4 +103,5 @@ object UpDownMoverTestMarks {
     val moveOutOfImpl = Testmark("moveOutOfImpl")
     val moveOutOfMatch = Testmark("moveOutOfMatch")
     val moveOutOfBody = Testmark("moveOutOfBody")
+    val moveOutOfBlock = Testmark("moveOutOfBlock")
 }
diff --git a/src/main/kotlin/org/rust/ide/formatter/impl/utils.kt b/src/main/kotlin/org/rust/ide/formatter/impl/utils.kt
index 067692946..8d2a9c287 100644
--- a/src/main/kotlin/org/rust/ide/formatter/impl/utils.kt
+++ b/src/main/kotlin/org/rust/ide/formatter/impl/utils.kt
@@ -130,7 +130,9 @@ class CommaList(
 
             CommaList(TUPLE_FIELDS, RPAREN) { it.elementType == TUPLE_FIELD_DECL },
             CommaList(VALUE_PARAMETER_LIST, RPAREN) { it.elementType == VALUE_PARAMETER },
-            CommaList(VALUE_ARGUMENT_LIST, RPAREN) { it is RsExpr }
+            CommaList(VALUE_ARGUMENT_LIST, RPAREN) { it is RsExpr },
+
+            CommaList(VEC_MACRO_ARGUMENT, RBRACK) { it is RsExpr }
         )
     }
 }
diff --git a/src/test/kotlin/org/rust/ide/actions/mover/RsCommaListElementUpDownMoverTest.kt b/src/test/kotlin/org/rust/ide/actions/mover/RsCommaListElementUpDownMoverTest.kt
index d0924fc29..08c18d7ee 100644
--- a/src/test/kotlin/org/rust/ide/actions/mover/RsCommaListElementUpDownMoverTest.kt
+++ b/src/test/kotlin/org/rust/ide/actions/mover/RsCommaListElementUpDownMoverTest.kt
@@ -162,4 +162,57 @@ class RsCommaListElementUpDownMoverTest : RsStatementUpDownMoverTestBase() {
         }
     """)
 
+    fun `test move vec argument`() = moveDownAndBackUp("""
+        fn foo() {
+            bar(
+                Baz {
+                    x
+                }, vec![
+                    1,/*caret*/
+                    2,
+                    3,
+                ],
+            );
+        }
+    """, """
+        fn foo() {
+            bar(
+                Baz {
+                    x
+                }, vec![
+                    2,
+                    1,/*caret*/
+                    3,
+                ],
+            );
+        }
+    """)
+
+    fun `test move up first vec argument`() = moveUp("""
+        fn foo() {
+            bar(
+                Baz {
+                    x
+                }, vec![
+                    1,/*caret*/
+                    2,
+                    3,
+                ],
+            );
+        }
+    """, testmark = UpDownMoverTestMarks.moveOutOfBlock)
+
+    fun `test move down last vec argument`() = moveDown("""
+        fn foo() {
+            bar(
+                Baz {
+                    x
+                }, vec![
+                    1,
+                    2,
+                    3,/*caret*/
+                ],
+            );
+        }
+    """, testmark = UpDownMoverTestMarks.moveOutOfBlock)
 }