diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index b059c2ab9f3a8..8d121eeb58977 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3158,14 +3158,36 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 tcx.sess.span_err(span, "union expressions should have exactly one field");
             }
         } else if check_completeness && !error_happened && !remaining_fields.is_empty() {
-            span_err!(tcx.sess, span, E0063,
-                      "missing field{} {} in initializer of `{}`",
-                      if remaining_fields.len() == 1 {""} else {"s"},
-                      remaining_fields.keys()
-                                      .map(|n| format!("`{}`", n))
-                                      .collect::<Vec<_>>()
-                                      .join(", "),
-                      adt_ty);
+            let len = remaining_fields.len();
+
+            let mut displayable_field_names = remaining_fields
+                                              .keys()
+                                              .map(|x| x.as_str())
+                                              .collect::<Vec<_>>();
+
+            displayable_field_names.sort();
+
+            let truncated_fields_error = if len <= 3 {
+                "".to_string()
+            } else {
+                format!(" and {} other field{}", (len - 3), if len - 3 == 1 {""} else {"s"})
+            };
+
+            let remaining_fields_names = displayable_field_names.iter().take(3)
+                                        .map(|n| format!("`{}`", n))
+                                        .collect::<Vec<_>>()
+                                        .join(", ");
+
+            struct_span_err!(tcx.sess, span, E0063,
+                        "missing field{} {}{} in initializer of `{}`",
+                        if remaining_fields.len() == 1 {""} else {"s"},
+                        remaining_fields_names,
+                        truncated_fields_error,
+                        adt_ty)
+                        .span_label(span, &format!("missing {}{}",
+                            remaining_fields_names,
+                            truncated_fields_error))
+                        .emit();
         }
     }
 
diff --git a/src/test/compile-fail/E0063.rs b/src/test/compile-fail/E0063.rs
index c94f807d807ca..e7044102abc71 100644
--- a/src/test/compile-fail/E0063.rs
+++ b/src/test/compile-fail/E0063.rs
@@ -8,11 +8,47 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Foo {
+// ignore-tidy-linelength
+
+struct SingleFoo {
+    x: i32
+}
+
+struct PluralFoo {
+    x: i32,
+    y: i32,
+    z: i32
+}
+
+struct TruncatedFoo {
+    a: i32,
+    b: i32,
     x: i32,
-    y: i32
+    y: i32,
+    z: i32
 }
 
+struct TruncatedPluralFoo {
+    a: i32,
+    b: i32,
+    c: i32,
+    x: i32,
+    y: i32,
+    z: i32
+}
+
+
 fn main() {
-    let x = Foo { x: 0 }; //~ ERROR E0063
+    let w = SingleFoo { };
+    //~^ ERROR missing field `x` in initializer of `SingleFoo`
+    //~| NOTE missing `x`
+    let x = PluralFoo {x: 1};
+    //~^ ERROR missing fields `y`, `z` in initializer of `PluralFoo`
+    //~| NOTE missing `y`, `z`
+    let y = TruncatedFoo{x:1};
+    //~^ missing fields `a`, `b`, `y` and 1 other field in initializer of `TruncatedFoo`
+    //~| NOTE `a`, `b`, `y` and 1 other field
+    let z = TruncatedPluralFoo{x:1};
+    //~^ ERROR missing fields `a`, `b`, `c` and 2 other fields in initializer of `TruncatedPluralFoo`
+    //~| NOTE missing `a`, `b`, `c` and 2 other fields
 }