Repository: intellij-rust/intellij-rust
Issue: Box pattern in struct field is not supported

## Environment

* **Intellij-Rust plugin version:** 0.2.0.2532-183-nightly
* **Rust toolchain version:** 1.34.0-nightly
* **IDE name and version:** CLion 2018.3.4
* **Operating system:** macOS Mojave 10.14.2

## Problem description

```rust
#![feature(box_patterns)]

struct S { x: Box<i32> }
fn main() {
    let S { box x } = S { x: Box::new(0) };
    x;
  //^ Expected: i32, found: Box<i32>.
}
```

Changed files:
src/main/kotlin/org/rust/lang/core/psi/ext/RsPatField.kt, src/main/kotlin/org/rust/lang/core/types/infer/PatternMatching.kt, src/test/kotlin/org/rust/lang/core/type/RsPatternMatchingTest.kt

diff --git a/src/main/kotlin/org/rust/lang/core/psi/ext/RsPatField.kt b/src/main/kotlin/org/rust/lang/core/psi/ext/RsPatField.kt
index 86a575dc7..9fa9e8925 100644
--- a/src/main/kotlin/org/rust/lang/core/psi/ext/RsPatField.kt
+++ b/src/main/kotlin/org/rust/lang/core/psi/ext/RsPatField.kt
@@ -11,7 +11,7 @@ import org.rust.lang.core.psi.RsPatBinding
 import org.rust.lang.core.psi.RsPatField
 
 val RsPatField.kind: RsPatFieldKind
-    get() = patBinding?.let { RsPatFieldKind.Shorthand(it) } ?: RsPatFieldKind.Full(identifier!!, pat!!)
+    get() = patBinding?.let { RsPatFieldKind.Shorthand(it, box != null) } ?: RsPatFieldKind.Full(identifier!!, pat!!)
 
 // PatField ::= identifier ':' Pat | box? PatBinding
 sealed class RsPatFieldKind {
@@ -26,7 +26,7 @@ sealed class RsPatFieldKind {
      * let S { ref a } = ...
      *         ~~~~~
      */
-    data class Shorthand(val binding: RsPatBinding): RsPatFieldKind()
+    data class Shorthand(val binding: RsPatBinding, val isBox: Boolean): RsPatFieldKind()
 }
 
 val RsPatFieldKind.fieldName: String
diff --git a/src/main/kotlin/org/rust/lang/core/types/infer/PatternMatching.kt b/src/main/kotlin/org/rust/lang/core/types/infer/PatternMatching.kt
index 01874c506..7143a964a 100644
--- a/src/main/kotlin/org/rust/lang/core/types/infer/PatternMatching.kt
+++ b/src/main/kotlin/org/rust/lang/core/types/infer/PatternMatching.kt
@@ -79,8 +79,13 @@ fun RsPat.extractBindings(fcx: RsFnInferenceContext, type: Ty, ignoreRef: Boolea
                     is RsPatFieldKind.Full -> kind.pat.extractBindings(fcx, fieldType.toRefIfNeeded(mut), mut != null)
                     is RsPatFieldKind.Shorthand -> {
                         val bindingKind = kind.binding.kind
-                        val bindingType = fieldType.toRefIfNeeded(if (bindingKind is BindByReference) bindingKind.mutability else mut)
-                        fcx.writeBindingTy(kind.binding, bindingType)
+                        val bindingType = if (fieldType is TyAdt && kind.isBox) {
+                            fieldType.typeArguments.singleOrNull() ?: return
+                        }  else {
+                            fieldType
+                        }
+                        val mutability = if (bindingKind is BindByReference) bindingKind.mutability else mut
+                        fcx.writeBindingTy(kind.binding, bindingType.toRefIfNeeded(mutability))
                     }
                 }
             }
diff --git a/src/test/kotlin/org/rust/lang/core/type/RsPatternMatchingTest.kt b/src/test/kotlin/org/rust/lang/core/type/RsPatternMatchingTest.kt
index a144d8952..a01172159 100644
--- a/src/test/kotlin/org/rust/lang/core/type/RsPatternMatchingTest.kt
+++ b/src/test/kotlin/org/rust/lang/core/type/RsPatternMatchingTest.kt
@@ -277,7 +277,7 @@ class RsPatternMatchingTest : RsTypificationTestBase() {
     """)
 
     @ProjectDescriptor(WithStdlibRustProjectDescriptor::class)
-    fun `test box pattern`() = stubOnlyTypeInfer("""
+    fun `test box pattern (pat box)`() = stubOnlyTypeInfer("""
     //- main.rs
         #![feature(box_patterns)]
         fn main() {
@@ -288,6 +288,19 @@ class RsPatternMatchingTest : RsTypificationTestBase() {
         }
     """)
 
+    @ProjectDescriptor(WithStdlibRustProjectDescriptor::class)
+    fun `test box pattern (pat field)`() = stubOnlyTypeInfer("""
+    //- main.rs
+        #![feature(box_patterns)]
+        struct S { x: Box<i32> }
+        fn main() {
+            let a = S { x: Box::new(0) };
+            let S { box x } = a;
+            x;
+          //^ i32
+        }
+    """)
+
     // Match ergonomics are enabled if a reference value (on the right side)
     // is matched by a non reference pattern (on the left side)
     // See https://github.com/rust-lang/rfcs/blob/master/text/2005-match-ergonomics.md