Repository: intellij-rust/intellij-rust
Issue: "Cannot borrow immutable as mutable" when the code is correct

## Environment

* **Intellij-Rust plugin version:** 0.2.0.2372-181-nightly
* **IDE name and version:** IntelliJ IDEA 2018.1.6 (Ultimate Edition), Build #IU-181.5540.7
* **Operating system:** Linux

## Problem description
The IDE reports a "Cannot borrow immutable as mutable" error (indicated by a red underline) when there are no real errors in the code.

## Steps to reproduce

Create a new binary project with the following code:
```rust
fn main() {
  let x = vec![1];
  if x.iter().any(|c| *c == 2) {

  }
}
```
The IDE highlights `x.iter()`. The popup message says:

> Cannot borrow immutable local variable `x.iter()` as mutable less... (Ctrl+F1) 
Implements simple cases of borrow checking.


Changed files:
src/main/kotlin/org/rust/lang/core/types/infer/MemoryCategorization.kt, src/test/kotlin/org/rust/lang/core/type/RsMemoryCategorizationTest.kt, src/test/kotlin/org/rust/ide/inspections/RsBorrowCheckerInspectionTest.kt

diff --git a/src/main/kotlin/org/rust/lang/core/types/infer/MemoryCategorization.kt b/src/main/kotlin/org/rust/lang/core/types/infer/MemoryCategorization.kt
index 386269f53..009cdfaab 100644
--- a/src/main/kotlin/org/rust/lang/core/types/infer/MemoryCategorization.kt
+++ b/src/main/kotlin/org/rust/lang/core/types/infer/MemoryCategorization.kt
@@ -61,6 +61,9 @@ private fun processUnaryExpr(unaryExpr: RsUnaryExpr): Cmt {
 }
 
 private fun processDotExpr(dotExpr: RsDotExpr): Cmt {
+    if (dotExpr.methodCall != null) {
+        return processRvalue(dotExpr)
+    }
     val type = dotExpr.type
     val base = dotExpr.expr
     val baseCmt = processExpr(base)
@@ -123,6 +126,9 @@ private fun processDeref(baseCmt: Cmt): Cmt {
     }
 }
 
+private fun processRvalue(expr: RsExpr): Cmt =
+    Cmt(expr.type, MutabilityCategory.Declared)
+
 private fun processExprUnadjusted(expr: RsExpr): Cmt =
     when (expr) {
         is RsUnaryExpr -> processUnaryExpr(expr)
@@ -130,7 +136,7 @@ private fun processExprUnadjusted(expr: RsExpr): Cmt =
         is RsIndexExpr -> processIndexExpr(expr)
         is RsPathExpr -> processPathExpr(expr)
         is RsParenExpr -> processParenExpr(expr)
-        else -> Cmt(expr.type)
+        else -> processRvalue(expr)
     }
 
 
diff --git a/src/test/kotlin/org/rust/ide/inspections/RsBorrowCheckerInspectionTest.kt b/src/test/kotlin/org/rust/ide/inspections/RsBorrowCheckerInspectionTest.kt
index 54a1f3b78..b89f9b14b 100644
--- a/src/test/kotlin/org/rust/ide/inspections/RsBorrowCheckerInspectionTest.kt
+++ b/src/test/kotlin/org/rust/ide/inspections/RsBorrowCheckerInspectionTest.kt
@@ -323,4 +323,21 @@ class RsBorrowCheckerInspectionTest : RsInspectionsTestBase(RsBorrowCheckerInspe
             let local = &mut A::foo;
         }
     """)
+
+    fun `test rvalue method call`() = checkByText("""
+        fn main() {
+            let v = vec![1];
+            v.iter().any(|c| *c == 2);
+        }
+    """)
+
+    fun `test rvalue if expr`() = checkByText("""
+        struct S {}
+        impl S {
+            fn f_mut(&mut self) { }
+        }
+        fn main() {
+          (if true { S } else { S }).f_mut();
+        }
+    """)
 }
diff --git a/src/test/kotlin/org/rust/lang/core/type/RsMemoryCategorizationTest.kt b/src/test/kotlin/org/rust/lang/core/type/RsMemoryCategorizationTest.kt
index 7a6e593db..62b5c0edf 100644
--- a/src/test/kotlin/org/rust/lang/core/type/RsMemoryCategorizationTest.kt
+++ b/src/test/kotlin/org/rust/lang/core/type/RsMemoryCategorizationTest.kt
@@ -181,4 +181,20 @@ class RsMemoryCategorizationTest : RsTestBase() {
             }
         }
     """)
+
+    fun `test rvalue method call`() = testExpr("""
+        fn main() {
+          let v = vec![1];
+          v.iter();
+               //^ Declared
+        }
+    """)
+
+    fun `test rvalue if expr`() = testExpr("""
+        struct S {}
+        fn main() {
+          (if true { S } else { S });
+                                 //^ Declared
+        }
+    """)
 }