Repository: intellij-rust/intellij-rust
Issue: False positive: "Cannot borrow immutable local variable as mutable"

## Environment

* **Intellij-Rust plugin version: 0.2.0.2422-182-nightly**
* **Rust toolchain version: rustc 1.30.0-nightly (cb6d2dfa8 2018-09-16)**
* **IDE name and version: IntelliJ IDEA Ultimate 2018.2.3**
* **Operating system: Ubuntu 16.04 LTS**

## Problem description

Mutably borrowing field from immutably bound mutable struct reference is incorrectly reported as an error.

## Steps to reproduce
```rust
fn main() {
    let mut x = (0, 0);
    let y = &mut x;
    let _z = &mut y.0;
}
```
Cannot borrow immutable local variable `y.0` as mutable

Changed files:
src/main/kotlin/org/rust/lang/core/types/infer/MemoryCategorization.kt, src/main/kotlin/org/rust/lang/core/types/infer/TypeInference.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 3c75c0265..a4c7aa035 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
@@ -248,7 +248,7 @@ class MemoryCategorizationContext(val lookup: ImplLookup, val inference: RsInfer
         val type = inference.getExprType(dotExpr)
         val base = dotExpr.expr
         val baseCmt = processExpr(base)
-        val fieldName = dotExpr.fieldLookup?.identifier?.text
+        val fieldName = dotExpr.fieldLookup?.identifier?.text ?: dotExpr.fieldLookup?.integerLiteral?.text
         return cmtOfField(dotExpr, baseCmt, fieldName, type)
     }
 
diff --git a/src/main/kotlin/org/rust/lang/core/types/infer/TypeInference.kt b/src/main/kotlin/org/rust/lang/core/types/infer/TypeInference.kt
index 276691919..dd76e8cab 100644
--- a/src/main/kotlin/org/rust/lang/core/types/infer/TypeInference.kt
+++ b/src/main/kotlin/org/rust/lang/core/types/infer/TypeInference.kt
@@ -1178,9 +1178,10 @@ class RsFnInferenceContext(
         ctx.writeResolvedField(fieldLookup, variants.map { it.element })
         val field = variants.firstOrNull()
         if (field == null) {
-            for (type in lookup.coercionSequence(receiver)) {
+            for ((index, type) in lookup.coercionSequence(receiver).withIndex()) {
                 if (type is TyTuple) {
                     val fieldIndex = fieldLookup.integerLiteral?.text?.toIntOrNull() ?: return TyUnknown
+                    ctx.addAdjustment(fieldLookup.parentDotExpr.expr, Adjustment.Deref(receiver), index)
                     return type.types.getOrElse(fieldIndex) { TyUnknown }
                 }
             }
diff --git a/src/test/kotlin/org/rust/ide/inspections/RsBorrowCheckerInspectionTest.kt b/src/test/kotlin/org/rust/ide/inspections/RsBorrowCheckerInspectionTest.kt
index 497aec542..38c7039fd 100644
--- a/src/test/kotlin/org/rust/ide/inspections/RsBorrowCheckerInspectionTest.kt
+++ b/src/test/kotlin/org/rust/ide/inspections/RsBorrowCheckerInspectionTest.kt
@@ -345,6 +345,22 @@ class RsBorrowCheckerInspectionTest : RsInspectionsTestBase(RsBorrowCheckerInspe
         }
     """)
 
+    fun `test tuple`() = checkByText("""
+        fn main() {
+            let mut x = (0, 0);
+            let y = &mut x;
+            let _z = &mut y.0;
+        }
+    """)
+
+    fun `test tuple multiple deref`() = checkByText("""
+        fn main() {
+            let mut x = (0, 0);
+            let y = &mut & x;
+            let _z = &mut <error descr="Cannot borrow immutable local variable `y.0` as mutable">y.0</error>;
+        }
+    """)
+
     /** [See github issue 2711](https://github.com/intellij-rust/intellij-rust/issues/2711) */
     @ProjectDescriptor(WithStdlibRustProjectDescriptor::class)
     fun `test vector index`() = checkByText("""