Repository: intellij-rust/intellij-rust
Issue: IllegalStateException in CFGBuilder

## Environment

* **IntelliJ Rust plugin version:** 0.2.123.3090-201-nightly
* **Rust toolchain version:** 1.43.0 (4fb7144ed 2020-04-20) x86_64-apple-darwin
* **IDE name and version:** IntelliJ IDEA 2020.1 Ultimate Edition (IU-201.6668.121)
* **Operating system:** macOS 10.15.3

## Problem description
```
java.lang.IllegalStateException: Processing ended inconclusively
        at org.rust.lang.core.cfg.CFGBuilder.process(CFGBuilder.kt:166)
        at org.rust.lang.core.cfg.CFGBuilder.visitExprStmt(CFGBuilder.kt:219)
        at org.rust.lang.core.psi.impl.RsExprStmtImpl.accept(RsExprStmtImpl.java:20)
        at org.rust.lang.core.psi.impl.RsExprStmtImpl.accept(RsExprStmtImpl.java:24)
        at org.rust.lang.core.cfg.CFGBuilder.process(CFGBuilder.kt:162)
        at org.rust.lang.core.cfg.CFGBuilder.visitBlock(CFGBuilder.kt:197)
        at org.rust.lang.core.psi.impl.RsBlockImpl.accept(RsBlockImpl.java:27)
        at org.rust.lang.core.psi.impl.RsBlockImpl.accept(RsBlockImpl.java:31)
        at org.rust.lang.core.cfg.CFGBuilder.process(CFGBuilder.kt:162)
        at org.rust.lang.core.cfg.CFGBuilder.visitBlockExpr(CFGBuilder.kt:351)
        at org.rust.lang.core.psi.impl.RsBlockExprImpl.accept(RsBlockExprImpl.java:26)
        at org.rust.lang.core.psi.impl.RsBlockExprImpl.accept(RsBlockExprImpl.java:30)
        at org.rust.lang.core.cfg.CFGBuilder.process(CFGBuilder.kt:162)
        at org.rust.lang.core.cfg.CFGBuilder.visitLambdaExpr(CFGBuilder.kt:638)
        at org.rust.lang.core.psi.impl.RsLambdaExprImpl.accept(RsLambdaExprImpl.java:26)
        at org.rust.lang.core.psi.impl.RsLambdaExprImpl.accept(RsLambdaExprImpl.java:30)
        at org.rust.lang.core.cfg.CFGBuilder.process(CFGBuilder.kt:162)
        at org.rust.lang.core.cfg.CFGBuilder.straightLine(CFGBuilder.kt:152)
        at org.rust.lang.core.cfg.CFGBuilder.processCall(CFGBuilder.kt:186)
        at org.rust.lang.core.cfg.CFGBuilder.visitDotExpr(CFGBuilder.kt:567)
        at org.rust.lang.core.psi.impl.RsDotExprImpl.accept(RsDotExprImpl.java:26)
        at org.rust.lang.core.psi.impl.RsDotExprImpl.accept(RsDotExprImpl.java:30)
        at org.rust.lang.core.cfg.CFGBuilder.process(CFGBuilder.kt:162)
        at org.rust.lang.core.cfg.CFGBuilder.processCall(CFGBuilder.kt:185)
        at org.rust.lang.core.cfg.CFGBuilder.visitDotExpr(CFGBuilder.kt:567)
        at org.rust.lang.core.psi.impl.RsDotExprImpl.accept(RsDotExprImpl.java:26)
        at org.rust.lang.core.psi.impl.RsDotExprImpl.accept(RsDotExprImpl.java:30)
        at org.rust.lang.core.cfg.CFGBuilder.process(CFGBuilder.kt:162)
        at org.rust.lang.core.cfg.CFGBuilder.visitLetDecl(CFGBuilder.kt:208)
        at org.rust.lang.core.psi.impl.RsLetDeclImpl.accept(RsLetDeclImpl.java:20)
        at org.rust.lang.core.psi.impl.RsLetDeclImpl.accept(RsLetDeclImpl.java:24)
        at org.rust.lang.core.cfg.CFGBuilder.process(CFGBuilder.kt:162)
        at org.rust.lang.core.cfg.CFGBuilder.visitBlock(CFGBuilder.kt:197)
        at org.rust.lang.core.psi.impl.RsBlockImpl.accept(RsBlockImpl.java:27)
        at org.rust.lang.core.psi.impl.RsBlockImpl.accept(RsBlockImpl.java:31)
        at org.rust.lang.core.cfg.CFGBuilder.process(CFGBuilder.kt:162)
        at org.rust.lang.core.cfg.CFGBuilder.visitBlockExpr(CFGBuilder.kt:351)
        at org.rust.lang.core.psi.impl.RsBlockExprImpl.accept(RsBlockExprImpl.java:26)
        at org.rust.lang.core.psi.impl.RsBlockExprImpl.accept(RsBlockExprImpl.java:30)
        at org.rust.lang.core.cfg.CFGBuilder.process(CFGBuilder.kt:162)
        at org.rust.lang.core.cfg.CFGBuilder.visitLambdaExpr(CFGBuilder.kt:638)
        at org.rust.lang.core.psi.impl.RsLambdaExprImpl.accept(RsLambdaExprImpl.java:26)
        at org.rust.lang.core.psi.impl.RsLambdaExprImpl.accept(RsLambdaExprImpl.java:30)
        at org.rust.lang.core.cfg.CFGBuilder.process(CFGBuilder.kt:162)
        at org.rust.lang.core.cfg.CFGBuilder.straightLine(CFGBuilder.kt:152)
        at org.rust.lang.core.cfg.CFGBuilder.processCall(CFGBuilder.kt:186)
        at org.rust.lang.core.cfg.CFGBuilder.visitCallExpr(CFGBuilder.kt:538)
        at org.rust.lang.core.psi.impl.RsCallExprImpl.accept(RsCallExprImpl.java:26)
        at org.rust.lang.core.psi.impl.RsCallExprImpl.accept(RsCallExprImpl.java:30)
        at org.rust.lang.core.cfg.CFGBuilder.process(CFGBuilder.kt:162)
        at org.rust.lang.core.cfg.CFGBuilder.straightLine(CFGBuilder.kt:152)
        at org.rust.lang.core.cfg.CFGBuilder.visitDotExpr(CFGBuilder.kt:565)
        at org.rust.lang.core.psi.impl.RsDotExprImpl.accept(RsDotExprImpl.java:26)
        at org.rust.lang.core.psi.impl.RsDotExprImpl.accept(RsDotExprImpl.java:30)
        at org.rust.lang.core.cfg.CFGBuilder.process(CFGBuilder.kt:162)
        at org.rust.lang.core.cfg.CFGBuilder.visitLetDecl(CFGBuilder.kt:208)
        at org.rust.lang.core.psi.impl.RsLetDeclImpl.accept(RsLetDeclImpl.java:20)
        at org.rust.lang.core.psi.impl.RsLetDeclImpl.accept(RsLetDeclImpl.java:24)
        at org.rust.lang.core.cfg.CFGBuilder.process(CFGBuilder.kt:162)
        at org.rust.lang.core.cfg.CFGBuilder.visitBlock(CFGBuilder.kt:197)
        at org.rust.lang.core.psi.impl.RsBlockImpl.accept(RsBlockImpl.java:27)
        at org.rust.lang.core.psi.impl.RsBlockImpl.accept(RsBlockImpl.java:31)
        at org.rust.lang.core.cfg.CFGBuilder.process(CFGBuilder.kt:162)
        at org.rust.lang.core.cfg.ControlFlowGraph$Companion.buildFor(ControlFlowGraph.kt:83)
        at org.rust.lang.core.types.ExtensionsKt$controlFlowGraph$1.compute(Extensions.kt:148)
        at com.intellij.psi.util.CachedValuesManager$1.compute(CachedValuesManager.java:158)
        at com.intellij.psi.impl.PsiCachedValueImpl.doCompute(PsiCachedValueImpl.java:54)
        at com.intellij.util.CachedValueBase.lambda$getValueWithLock$1(CachedValueBase.java:235)
        at com.intellij.openapi.util.RecursionManager$1.doPreventingRecursion(RecursionManager.java:117)
        at com.intellij.openapi.util.RecursionManager.doPreventingRecursion(RecursionManager.java:75)
        at com.intellij.util.CachedValueBase.getValueWithLock(CachedValueBase.java:236)
        at com.intellij.psi.impl.PsiCachedValueImpl.getValue(PsiCachedValueImpl.java:43)
        at com.intellij.util.CachedValuesManagerImpl.getCachedValue(CachedValuesManagerImpl.java:73)
        at com.intellij.psi.util.CachedValuesManager.getCachedValue(CachedValuesManager.java:154)
        at org.rust.lang.core.types.ExtensionsKt.getControlFlowGraph(Extensions.kt:146)
        at org.rust.lang.core.types.LivenessContext$Companion.buildFor(Liveness.kt:50)
        at org.rust.lang.core.types.ExtensionsKt$liveness$1.compute(Extensions.kt:156)
        at com.intellij.psi.util.CachedValuesManager$1.compute(CachedValuesManager.java:158)
        at com.intellij.psi.impl.PsiCachedValueImpl.doCompute(PsiCachedValueImpl.java:54)
        at com.intellij.util.CachedValueBase.lambda$getValueWithLock$1(CachedValueBase.java:235)
        at com.intellij.openapi.util.RecursionManager$1.doPreventingRecursion(RecursionManager.java:117)
        at com.intellij.openapi.util.RecursionManager.doPreventingRecursion(RecursionManager.java:75)
        at com.intellij.util.CachedValueBase.getValueWithLock(CachedValueBase.java:236)
        at com.intellij.psi.impl.PsiCachedValueImpl.getValue(PsiCachedValueImpl.java:43)
        at com.intellij.util.CachedValuesManagerImpl.getCachedValue(CachedValuesManagerImpl.java:73)
        at com.intellij.psi.util.CachedValuesManager.getCachedValue(CachedValuesManager.java:154)
        at org.rust.lang.core.types.ExtensionsKt.getLiveness(Extensions.kt:155)
        at org.rust.ide.inspections.RsLivenessInspection$buildVisitor$1.visitFunction(RsLivenessInspection.kt:41)
        at org.rust.lang.core.psi.impl.RsFunctionImpl.accept(RsFunctionImpl.java:27)
        at org.rust.lang.core.psi.impl.RsFunctionImpl.accept(RsFunctionImpl.java:31)
        at com.intellij.codeInspection.InspectionEngine.acceptElements(InspectionEngine.java:69)
        at com.intellij.codeInsight.daemon.impl.LocalInspectionsPass.lambda$null$6(LocalInspectionsPass.java:320)
        at com.intellij.util.AstLoadingFilter.lambda$toComputable$2(AstLoadingFilter.java:168)
        at com.intellij.util.AstLoadingFilter.disallowTreeLoading(AstLoadingFilter.java:126)
        at com.intellij.util.AstLoadingFilter.disallowTreeLoading(AstLoadingFilter.java:115)
        at com.intellij.util.AstLoadingFilter.disallowTreeLoading(AstLoadingFilter.java:110)
        at com.intellij.codeInsight.daemon.impl.LocalInspectionsPass.lambda$visitRestElementsAndCleanup$7(LocalInspectionsPass.java:320)
        at com.intellij.concurrency.ApplierCompleter.execAndForkSubTasks(ApplierCompleter.java:149)
        at com.intellij.openapi.application.impl.ApplicationImpl.tryRunReadAction(ApplicationImpl.java:1106)
        at com.intellij.concurrency.ApplierCompleter.lambda$wrapInReadActionAndIndicator$1(ApplierCompleter.java:105)
        at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:627)
        at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:572)
        at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:61)
        at com.intellij.concurrency.ApplierCompleter.wrapInReadActionAndIndicator(ApplierCompleter.java:117)
        at com.intellij.concurrency.ApplierCompleter.lambda$compute$0(ApplierCompleter.java:96)
        at com.intellij.openapi.application.impl.ReadMostlyRWLock.executeByImpatientReader(ReadMostlyRWLock.java:168)
        at com.intellij.openapi.application.impl.ApplicationImpl.executeByImpatientReader(ApplicationImpl.java:168)
        at com.intellij.concurrency.ApplierCompleter.compute(ApplierCompleter.java:96)
        at java.base/java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:746)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
        at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177)
```

Cc @fletcher91

Changed files:
src/test/kotlin/org/rust/lang/core/cfg/RsControlFlowGraphTest.kt, src/test/kotlin/org/rust/ide/inspections/borrowck/RsBorrowCheckerMovesTest.kt, src/main/kotlin/org/rust/lang/core/types/borrowck/ExprUseWalker.kt, src/main/kotlin/org/rust/lang/core/cfg/CFGBuilder.kt

diff --git a/src/main/kotlin/org/rust/lang/core/cfg/CFGBuilder.kt b/src/main/kotlin/org/rust/lang/core/cfg/CFGBuilder.kt
index f1cb5b958..29a024b1c 100644
--- a/src/main/kotlin/org/rust/lang/core/cfg/CFGBuilder.kt
+++ b/src/main/kotlin/org/rust/lang/core/cfg/CFGBuilder.kt
@@ -613,7 +613,8 @@ class CFGBuilder(
     }
 
     override fun visitParenExpr(parenExpr: RsParenExpr) {
-        parenExpr.expr?.accept(this)
+        val exprExit = process(parenExpr.expr, pred)
+        finishWithAstNode(parenExpr, exprExit)
     }
 
     override fun visitTryExpr(tryExpr: RsTryExpr) {
diff --git a/src/main/kotlin/org/rust/lang/core/types/borrowck/ExprUseWalker.kt b/src/main/kotlin/org/rust/lang/core/types/borrowck/ExprUseWalker.kt
index 5ef6dd6b4..ab8bb4288 100644
--- a/src/main/kotlin/org/rust/lang/core/types/borrowck/ExprUseWalker.kt
+++ b/src/main/kotlin/org/rust/lang/core/types/borrowck/ExprUseWalker.kt
@@ -293,10 +293,7 @@ class ExprUseWalker(private val delegate: Delegate, private val mc: MemoryCatego
 
             is RsCastExpr -> consumeExpr(expr.expr)
 
-            is RsParenExpr -> when (expr.parent) {
-                is RsDotExpr -> expr.expr?.let { walkExpr(it) }
-                else -> expr.expr?.let { consumeExpr(it) }
-            }
+            is RsParenExpr -> expr.expr?.let { walkExpr(it) }
 
             is RsTryExpr -> walkExpr(expr.expr)
 
diff --git a/src/test/kotlin/org/rust/ide/inspections/borrowck/RsBorrowCheckerMovesTest.kt b/src/test/kotlin/org/rust/ide/inspections/borrowck/RsBorrowCheckerMovesTest.kt
index 992d80dd4..b201c14d1 100644
--- a/src/test/kotlin/org/rust/ide/inspections/borrowck/RsBorrowCheckerMovesTest.kt
+++ b/src/test/kotlin/org/rust/ide/inspections/borrowck/RsBorrowCheckerMovesTest.kt
@@ -641,6 +641,17 @@ class RsBorrowCheckerMovesTest : RsInspectionsTestBase(RsBorrowCheckerInspection
         }
     """, checkWarn = false)
 
+    @ProjectDescriptor(WithStdlibRustProjectDescriptor::class)
+    fun `test no move struct expr with base paren`() = checkByText("""
+        struct S { x: i32, y: i32 }
+
+        fn main() {
+            let s1 = S { x: 1, y: 2 };
+            let s2 = S { x: 10, ..(s1) };
+            s1;
+        }
+    """, checkWarn = false)
+
     @ProjectDescriptor(WithStdlibRustProjectDescriptor::class)
     fun `test no move generic struct expr with base`() = checkByText("""
         struct S<T> { x: T, y: T }
diff --git a/src/test/kotlin/org/rust/lang/core/cfg/RsControlFlowGraphTest.kt b/src/test/kotlin/org/rust/lang/core/cfg/RsControlFlowGraphTest.kt
index 4cc8cf079..f438e6324 100644
--- a/src/test/kotlin/org/rust/lang/core/cfg/RsControlFlowGraphTest.kt
+++ b/src/test/kotlin/org/rust/lang/core/cfg/RsControlFlowGraphTest.kt
@@ -26,6 +26,7 @@ class RsControlFlowGraphTest : RsTestBase() {
     fun `test straightforward`() = testCFG("""
         fn main() {
             let x = (1 + 2) as i32;
+            let x = (;
             let arr = [0, 5 * 7 + x];
             let mut y = -arr[x + 10];
             { y = 10; y += x; };
@@ -37,10 +38,15 @@ class RsControlFlowGraphTest : RsTestBase() {
         1
         2
         1 + 2
+        (1 + 2)
         (1 + 2) as i32
         x
         x
         let x = (1 + 2) as i32;
+        (
+        x
+        x
+        let x = (;
         0
         5
         7