diff --git a/src/libcore/mem/maybe_uninit.rs b/src/libcore/mem/maybe_uninit.rs
index 8d064de6f4751..1bbea02e0c7c9 100644
--- a/src/libcore/mem/maybe_uninit.rs
+++ b/src/libcore/mem/maybe_uninit.rs
@@ -13,6 +13,7 @@ use crate::mem::ManuallyDrop;
 /// ever gets used to access memory:
 ///
 /// ```rust,no_run
+/// # #![allow(invalid_value)]
 /// use std::mem::{self, MaybeUninit};
 ///
 /// let x: &i32 = unsafe { mem::zeroed() }; // undefined behavior!
@@ -27,6 +28,7 @@ use crate::mem::ManuallyDrop;
 /// always be `true` or `false`. Hence, creating an uninitialized `bool` is undefined behavior:
 ///
 /// ```rust,no_run
+/// # #![allow(invalid_value)]
 /// use std::mem::{self, MaybeUninit};
 ///
 /// let b: bool = unsafe { mem::uninitialized() }; // undefined behavior!
@@ -40,6 +42,7 @@ use crate::mem::ManuallyDrop;
 /// which otherwise can hold any *fixed* bit pattern:
 ///
 /// ```rust,no_run
+/// # #![allow(invalid_value)]
 /// use std::mem::{self, MaybeUninit};
 ///
 /// let x: i32 = unsafe { mem::uninitialized() }; // undefined behavior!
diff --git a/src/libcore/mem/mod.rs b/src/libcore/mem/mod.rs
index 86dae985fdb00..16cfe0f7683a8 100644
--- a/src/libcore/mem/mod.rs
+++ b/src/libcore/mem/mod.rs
@@ -445,7 +445,8 @@ pub const fn needs_drop<T>() -> bool {
 ///
 /// *Incorrect* usage of this function: initializing a reference with zero.
 ///
-/// ```no_run
+/// ```rust,no_run
+/// # #![allow(invalid_value)]
 /// use std::mem;
 ///
 /// let _x: &i32 = unsafe { mem::zeroed() }; // Undefined behavior!
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index a10578b0a4390..9d563e290de96 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -1842,7 +1842,8 @@ pub struct VariantDef {
     pub ctor_kind: CtorKind,
     /// Flags of the variant (e.g. is field list non-exhaustive)?
     flags: VariantFlags,
-    /// Recovered?
+    /// Variant is obtained as part of recovering from a syntactic error.
+    /// May be incomplete or bogus.
     pub recovered: bool,
 }
 
@@ -1949,7 +1950,7 @@ pub struct FieldDef {
 pub struct AdtDef {
     /// `DefId` of the struct, enum or union item.
     pub did: DefId,
-    /// Variants of the ADT. If this is a struct or enum, then there will be a single variant.
+    /// Variants of the ADT. If this is a struct or union, then there will be a single variant.
     pub variants: IndexVec<self::layout::VariantIdx, VariantDef>,
     /// Flags of the ADT (e.g. is this a struct? is this non-exhaustive?)
     flags: AdtFlags,
@@ -2565,6 +2566,8 @@ impl<'tcx> AdtDef {
 }
 
 impl<'tcx> FieldDef {
+    /// Returns the type of this field. The `subst` is typically obtained
+    /// via the second field of `TyKind::AdtDef`.
     pub fn ty(&self, tcx: TyCtxt<'tcx>, subst: SubstsRef<'tcx>) -> Ty<'tcx> {
         tcx.type_of(self.did).subst(tcx, subst)
     }
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 064c374de2b4c..129ea9b5b674a 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -171,6 +171,7 @@ pub enum TyKind<'tcx> {
     Never,
 
     /// A tuple type. For example, `(i32, bool)`.
+    /// Use `TyS::tuple_fields` to iterate over the field types.
     Tuple(SubstsRef<'tcx>),
 
     /// The projection of an associated type. For example,
@@ -1723,8 +1724,8 @@ impl<'tcx> TyS<'tcx> {
                     })
                 })
             }
-            ty::Tuple(tys) => tys.iter().any(|ty| {
-                ty.expect_ty().conservative_is_privately_uninhabited(tcx)
+            ty::Tuple(..) => self.tuple_fields().any(|ty| {
+                ty.conservative_is_privately_uninhabited(tcx)
             }),
             ty::Array(ty, len) => {
                 match len.try_eval_usize(tcx, ParamEnv::empty()) {
@@ -2103,6 +2104,15 @@ impl<'tcx> TyS<'tcx> {
         }
     }
 
+    /// Iterates over tuple fields.
+    /// Panics when called on anything but a tuple.
+    pub fn tuple_fields(&self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> {
+        match self.sty {
+            Tuple(substs) => substs.iter().map(|field| field.expect_ty()),
+            _ => bug!("tuple_fields called on non-tuple"),
+        }
+    }
+
     /// If the type contains variants, returns the valid range of variant indices.
     /// FIXME This requires the optimized MIR in the case of generators.
     #[inline]
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index c3ecc04b12e01..96e16efd1300a 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -845,15 +845,15 @@ impl<'tcx> ty::TyS<'tcx> {
             ty: Ty<'tcx>,
         ) -> Representability {
             match ty.sty {
-                Tuple(ref ts) => {
+                Tuple(..) => {
                     // Find non representable
-                    fold_repr(ts.iter().map(|ty| {
+                    fold_repr(ty.tuple_fields().map(|ty| {
                         is_type_structurally_recursive(
                             tcx,
                             sp,
                             seen,
                             representable_cache,
-                            ty.expect_ty(),
+                            ty,
                         )
                     }))
                 }
@@ -1095,7 +1095,7 @@ fn needs_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>
         // state transformation pass
         ty::Generator(..) => true,
 
-        ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).any(needs_drop),
+        ty::Tuple(..) => ty.tuple_fields().any(needs_drop),
 
         // unions don't have destructors because of the child types,
         // only if they manually implement `Drop` (handled above).
diff --git a/src/librustc/ty/walk.rs b/src/librustc/ty/walk.rs
index c74511cf0fdda..8c3110792a8b4 100644
--- a/src/librustc/ty/walk.rs
+++ b/src/librustc/ty/walk.rs
@@ -119,8 +119,8 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) {
         ty::GeneratorWitness(ts) => {
             stack.extend(ts.skip_binder().iter().cloned().rev());
         }
-        ty::Tuple(ts) => {
-            stack.extend(ts.iter().map(|k| k.expect_ty()).rev());
+        ty::Tuple(..) => {
+            stack.extend(parent_ty.tuple_fields().rev());
         }
         ty::FnDef(_, substs) => {
             stack.extend(substs.types().rev());
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index c9153f285fff7..13ec27aa1ab3f 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -23,7 +23,7 @@
 
 use rustc::hir::def::{Res, DefKind};
 use rustc::hir::def_id::{DefId, LOCAL_CRATE};
-use rustc::ty::{self, Ty, TyCtxt};
+use rustc::ty::{self, Ty, TyCtxt, layout::VariantIdx};
 use rustc::{lint, util};
 use hir::Node;
 use util::nodemap::HirIdSet;
@@ -1862,3 +1862,92 @@ impl EarlyLintPass for IncompleteFeatures {
             });
     }
 }
+
+declare_lint! {
+    pub INVALID_VALUE,
+    Warn,
+    "an invalid value is being created (such as a NULL reference)"
+}
+
+declare_lint_pass!(InvalidValue => [INVALID_VALUE]);
+
+impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue {
+    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &hir::Expr) {
+
+        const ZEROED_PATH: &[Symbol] = &[sym::core, sym::mem, sym::zeroed];
+        const UININIT_PATH: &[Symbol] = &[sym::core, sym::mem, sym::uninitialized];
+
+        /// Return `false` only if we are sure this type does *not*
+        /// allow zero initialization.
+        fn ty_maybe_allows_zero_init<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
+            use rustc::ty::TyKind::*;
+            match ty.sty {
+                // Primitive types that don't like 0 as a value.
+                Ref(..) | FnPtr(..) | Never => false,
+                Adt(..) if ty.is_box() => false,
+                // Recurse for some compound types.
+                Adt(adt_def, substs) if !adt_def.is_union() => {
+                    match adt_def.variants.len() {
+                        0 => false, // Uninhabited enum!
+                        1 => {
+                            // Struct, or enum with exactly one variant.
+                            // Proceed recursively, check all fields.
+                            let variant = &adt_def.variants[VariantIdx::from_u32(0)];
+                            variant.fields.iter().all(|field| {
+                                ty_maybe_allows_zero_init(
+                                    tcx,
+                                    field.ty(tcx, substs),
+                                )
+                            })
+                        }
+                        _ => true, // Conservative fallback for multi-variant enum.
+                    }
+                }
+                Tuple(..) => {
+                    // Proceed recursively, check all fields.
+                    ty.tuple_fields().all(|field| ty_maybe_allows_zero_init(tcx, field))
+                }
+                // FIXME: Would be nice to also warn for `NonNull`/`NonZero*`.
+                // FIXME: *Only for `mem::uninitialized`*, we could also warn for `bool`,
+                //        `char`, and any multivariant enum.
+                // Conservative fallback.
+                _ => true,
+            }
+        }
+
+        if let hir::ExprKind::Call(ref path_expr, ref _args) = expr.node {
+            if let hir::ExprKind::Path(ref qpath) = path_expr.node {
+                if let Some(def_id) = cx.tables.qpath_res(qpath, path_expr.hir_id).opt_def_id() {
+                    if cx.match_def_path(def_id, &ZEROED_PATH) ||
+                        cx.match_def_path(def_id, &UININIT_PATH)
+                    {
+                        // This conjures an instance of a type out of nothing,
+                        // using zeroed or uninitialized memory.
+                        // We are extremely conservative with what we warn about.
+                        let conjured_ty = cx.tables.expr_ty(expr);
+
+                        if !ty_maybe_allows_zero_init(cx.tcx, conjured_ty) {
+                            cx.struct_span_lint(
+                                INVALID_VALUE,
+                                expr.span,
+                                &format!(
+                                    "the type `{}` does not permit {}",
+                                    conjured_ty,
+                                    if cx.match_def_path(def_id, &ZEROED_PATH) {
+                                        "zero-initialization"
+                                    } else {
+                                        "being left uninitialized"
+                                    }
+                                ),
+                            )
+                            .note("this means that this code causes undefined behavior \
+                                when executed")
+                            .help("use `MaybeUninit` instead")
+                            .emit();
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index 78bc164ba1a0f..3a540fdf4b91f 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -177,6 +177,7 @@ macro_rules! late_lint_mod_passes {
             UnreachablePub: UnreachablePub,
 
             ExplicitOutlivesRequirements: ExplicitOutlivesRequirements,
+            InvalidValue: InvalidValue,
         ]);
     )
 }
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index 42945c79ddf0e..33447eba7492a 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -324,7 +324,7 @@ fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -
                 substs.upvar_tys(def_id, tcx)
             )
         }
-        ty::Tuple(tys) => builder.tuple_like_shim(dest, src, tys.iter().map(|k| k.expect_ty())),
+        ty::Tuple(..) => builder.tuple_like_shim(dest, src, self_ty.tuple_fields()),
         _ => {
             bug!("clone shim for `{:?}` which is not `Copy` and is not an aggregate", self_ty)
         }
diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs
index d17dcaafc04f5..52fd645e38e22 100644
--- a/src/librustc_mir/util/elaborate_drops.rs
+++ b/src/librustc_mir/util/elaborate_drops.rs
@@ -804,8 +804,8 @@ where
                 let tys : Vec<_> = substs.upvar_tys(def_id, self.tcx()).collect();
                 self.open_drop_for_tuple(&tys)
             }
-            ty::Tuple(tys) => {
-                let tys: Vec<_> = tys.iter().map(|k| k.expect_ty()).collect();
+            ty::Tuple(..) => {
+                let tys: Vec<_> = ty.tuple_fields().collect();
                 self.open_drop_for_tuple(&tys)
             }
             ty::Adt(def, substs) => {
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index f7e1b983e5446..2d9556233d15f 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -412,6 +412,7 @@ symbols! {
         match_beginning_vert,
         match_default_bindings,
         may_dangle,
+        mem,
         member_constraints,
         message,
         meta,
@@ -695,6 +696,7 @@ symbols! {
         underscore_imports,
         underscore_lifetimes,
         uniform_paths,
+        uninitialized,
         universal_impl_trait,
         unmarked_api,
         unreachable_code,
@@ -726,6 +728,7 @@ symbols! {
         windows,
         windows_subsystem,
         Yield,
+        zeroed,
     }
 }
 
diff --git a/src/test/ui/lint/uninitialized-zeroed.rs b/src/test/ui/lint/uninitialized-zeroed.rs
new file mode 100644
index 0000000000000..8f9ca8717bda6
--- /dev/null
+++ b/src/test/ui/lint/uninitialized-zeroed.rs
@@ -0,0 +1,58 @@
+// ignore-tidy-linelength
+// This test checks that calling `mem::{uninitialized,zeroed}` with certain types results
+// in a lint.
+
+#![feature(never_type)]
+#![allow(deprecated)]
+#![deny(invalid_value)]
+
+use std::mem::{self, MaybeUninit};
+
+enum Void {}
+
+struct Ref(&'static i32);
+
+struct Wrap<T> { wrapped: T }
+
+#[allow(unused)]
+fn generic<T: 'static>() {
+    unsafe {
+        let _val: &'static T = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+        let _val: &'static T = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+        let _val: Wrap<&'static T> = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+        let _val: Wrap<&'static T> = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+    }
+}
+
+fn main() {
+    unsafe {
+        let _val: ! = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+        let _val: ! = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+        let _val: (i32, !) = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+        let _val: (i32, !) = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+        let _val: Void = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+        let _val: Void = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+        let _val: &'static i32 = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+        let _val: &'static i32 = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+        let _val: Ref = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+        let _val: Ref = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+        let _val: fn() = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+        let _val: fn() = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+        let _val: Wrap<fn()> = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+        let _val: Wrap<fn()> = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+        // Some types that should work just fine.
+        let _val: Option<&'static i32> = mem::zeroed();
+        let _val: Option<fn()> = mem::zeroed();
+        let _val: MaybeUninit<&'static i32> = mem::zeroed();
+        let _val: bool = mem::zeroed();
+        let _val: i32 = mem::zeroed();
+    }
+}
diff --git a/src/test/ui/lint/uninitialized-zeroed.stderr b/src/test/ui/lint/uninitialized-zeroed.stderr
new file mode 100644
index 0000000000000..af54b16bd0b24
--- /dev/null
+++ b/src/test/ui/lint/uninitialized-zeroed.stderr
@@ -0,0 +1,169 @@
+error: the type `&'static T` does not permit zero-initialization
+  --> $DIR/uninitialized-zeroed.rs:20:32
+   |
+LL |         let _val: &'static T = mem::zeroed();
+   |                                ^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/uninitialized-zeroed.rs:7:9
+   |
+LL | #![deny(invalid_value)]
+   |         ^^^^^^^^^^^^^
+   = note: this means that this code causes undefined behavior when executed
+   = help: use `MaybeUninit` instead
+
+error: the type `&'static T` does not permit being left uninitialized
+  --> $DIR/uninitialized-zeroed.rs:21:32
+   |
+LL |         let _val: &'static T = mem::uninitialized();
+   |                                ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this means that this code causes undefined behavior when executed
+   = help: use `MaybeUninit` instead
+
+error: the type `Wrap<&'static T>` does not permit zero-initialization
+  --> $DIR/uninitialized-zeroed.rs:23:38
+   |
+LL |         let _val: Wrap<&'static T> = mem::zeroed();
+   |                                      ^^^^^^^^^^^^^
+   |
+   = note: this means that this code causes undefined behavior when executed
+   = help: use `MaybeUninit` instead
+
+error: the type `Wrap<&'static T>` does not permit being left uninitialized
+  --> $DIR/uninitialized-zeroed.rs:24:38
+   |
+LL |         let _val: Wrap<&'static T> = mem::uninitialized();
+   |                                      ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this means that this code causes undefined behavior when executed
+   = help: use `MaybeUninit` instead
+
+error: the type `!` does not permit zero-initialization
+  --> $DIR/uninitialized-zeroed.rs:30:23
+   |
+LL |         let _val: ! = mem::zeroed();
+   |                       ^^^^^^^^^^^^^
+   |
+   = note: this means that this code causes undefined behavior when executed
+   = help: use `MaybeUninit` instead
+
+error: the type `!` does not permit being left uninitialized
+  --> $DIR/uninitialized-zeroed.rs:31:23
+   |
+LL |         let _val: ! = mem::uninitialized();
+   |                       ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this means that this code causes undefined behavior when executed
+   = help: use `MaybeUninit` instead
+
+error: the type `(i32, !)` does not permit zero-initialization
+  --> $DIR/uninitialized-zeroed.rs:33:30
+   |
+LL |         let _val: (i32, !) = mem::zeroed();
+   |                              ^^^^^^^^^^^^^
+   |
+   = note: this means that this code causes undefined behavior when executed
+   = help: use `MaybeUninit` instead
+
+error: the type `(i32, !)` does not permit being left uninitialized
+  --> $DIR/uninitialized-zeroed.rs:34:30
+   |
+LL |         let _val: (i32, !) = mem::uninitialized();
+   |                              ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this means that this code causes undefined behavior when executed
+   = help: use `MaybeUninit` instead
+
+error: the type `Void` does not permit zero-initialization
+  --> $DIR/uninitialized-zeroed.rs:36:26
+   |
+LL |         let _val: Void = mem::zeroed();
+   |                          ^^^^^^^^^^^^^
+   |
+   = note: this means that this code causes undefined behavior when executed
+   = help: use `MaybeUninit` instead
+
+error: the type `Void` does not permit being left uninitialized
+  --> $DIR/uninitialized-zeroed.rs:37:26
+   |
+LL |         let _val: Void = mem::uninitialized();
+   |                          ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this means that this code causes undefined behavior when executed
+   = help: use `MaybeUninit` instead
+
+error: the type `&'static i32` does not permit zero-initialization
+  --> $DIR/uninitialized-zeroed.rs:39:34
+   |
+LL |         let _val: &'static i32 = mem::zeroed();
+   |                                  ^^^^^^^^^^^^^
+   |
+   = note: this means that this code causes undefined behavior when executed
+   = help: use `MaybeUninit` instead
+
+error: the type `&'static i32` does not permit being left uninitialized
+  --> $DIR/uninitialized-zeroed.rs:40:34
+   |
+LL |         let _val: &'static i32 = mem::uninitialized();
+   |                                  ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this means that this code causes undefined behavior when executed
+   = help: use `MaybeUninit` instead
+
+error: the type `Ref` does not permit zero-initialization
+  --> $DIR/uninitialized-zeroed.rs:42:25
+   |
+LL |         let _val: Ref = mem::zeroed();
+   |                         ^^^^^^^^^^^^^
+   |
+   = note: this means that this code causes undefined behavior when executed
+   = help: use `MaybeUninit` instead
+
+error: the type `Ref` does not permit being left uninitialized
+  --> $DIR/uninitialized-zeroed.rs:43:25
+   |
+LL |         let _val: Ref = mem::uninitialized();
+   |                         ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this means that this code causes undefined behavior when executed
+   = help: use `MaybeUninit` instead
+
+error: the type `fn()` does not permit zero-initialization
+  --> $DIR/uninitialized-zeroed.rs:45:26
+   |
+LL |         let _val: fn() = mem::zeroed();
+   |                          ^^^^^^^^^^^^^
+   |
+   = note: this means that this code causes undefined behavior when executed
+   = help: use `MaybeUninit` instead
+
+error: the type `fn()` does not permit being left uninitialized
+  --> $DIR/uninitialized-zeroed.rs:46:26
+   |
+LL |         let _val: fn() = mem::uninitialized();
+   |                          ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this means that this code causes undefined behavior when executed
+   = help: use `MaybeUninit` instead
+
+error: the type `Wrap<fn()>` does not permit zero-initialization
+  --> $DIR/uninitialized-zeroed.rs:48:32
+   |
+LL |         let _val: Wrap<fn()> = mem::zeroed();
+   |                                ^^^^^^^^^^^^^
+   |
+   = note: this means that this code causes undefined behavior when executed
+   = help: use `MaybeUninit` instead
+
+error: the type `Wrap<fn()>` does not permit being left uninitialized
+  --> $DIR/uninitialized-zeroed.rs:49:32
+   |
+LL |         let _val: Wrap<fn()> = mem::uninitialized();
+   |                                ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this means that this code causes undefined behavior when executed
+   = help: use `MaybeUninit` instead
+
+error: aborting due to 18 previous errors
+
diff --git a/src/test/ui/panic-uninitialized-zeroed.rs b/src/test/ui/panic-uninitialized-zeroed.rs
index 0c97babd51cd4..b0d6629561803 100644
--- a/src/test/ui/panic-uninitialized-zeroed.rs
+++ b/src/test/ui/panic-uninitialized-zeroed.rs
@@ -4,7 +4,7 @@
 // in a runtime panic.
 
 #![feature(never_type)]
-#![allow(deprecated)]
+#![allow(deprecated, invalid_value)]
 
 use std::{mem, panic};
 
diff --git a/src/tools/clippy b/src/tools/clippy
index b041511b5fcd3..72da1015d6d91 160000
--- a/src/tools/clippy
+++ b/src/tools/clippy
@@ -1 +1 @@
-Subproject commit b041511b5fcd386c4ae74a30b60a5081f8717fbe
+Subproject commit 72da1015d6d918fe1b29170acbf486d30e0c2695