diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index a8a1646183c86..a3139ce5a3455 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -129,6 +129,13 @@ pub fn time_trace_profiler_finish(file_name: &str) {
 // WARNING: the features after applying `to_llvm_feature` must be known
 // to LLVM or the feature detection code will walk past the end of the feature
 // array, leading to crashes.
+// To find a list of LLVM's names, check llvm-project/llvm/include/llvm/Support/*TargetParser.def
+// where the * matches the architecture's name
+// Beware to not use the llvm github project for this, but check the git submodule
+// found in src/llvm-project
+// Though note that Rust can also be build with an external precompiled version of LLVM
+// which might lead to failures if the oldest tested / supported LLVM version
+// doesn't yet support the relevant intrinsics
 pub fn to_llvm_feature<'a>(sess: &Session, s: &'a str) -> &'a str {
     let arch = if sess.target.arch == "x86_64" { "x86" } else { &*sess.target.arch };
     match (arch, s) {
@@ -136,6 +143,9 @@ pub fn to_llvm_feature<'a>(sess: &Session, s: &'a str) -> &'a str {
         ("x86", "rdrand") => "rdrnd",
         ("x86", "bmi1") => "bmi",
         ("x86", "cmpxchg16b") => "cx16",
+        ("x86", "avx512vaes") => "vaes",
+        ("x86", "avx512gfni") => "gfni",
+        ("x86", "avx512vpclmulqdq") => "vpclmulqdq",
         ("aarch64", "fp") => "fp-armv8",
         ("aarch64", "fp16") => "fullfp16",
         (_, s) => s,
diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
index 000ddf4260429..fd18f42f2dd4f 100644
--- a/compiler/rustc_codegen_ssa/src/target_features.rs
+++ b/compiler/rustc_codegen_ssa/src/target_features.rs
@@ -4,6 +4,11 @@ use rustc_session::Session;
 use rustc_span::symbol::sym;
 use rustc_span::symbol::Symbol;
 
+// When adding features to the below lists
+// check whether they're named already elsewhere in rust
+// e.g. in stdarch and whether the given name matches LLVM's
+// if it doesn't, to_llvm_feature in llvm_util in rustc_codegen_llvm needs to be adapted
+
 const ARM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
     ("aclass", Some(sym::arm_target_feature)),
     ("mclass", Some(sym::arm_target_feature)),
@@ -50,15 +55,23 @@ const X86_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
     ("aes", None),
     ("avx", None),
     ("avx2", None),
+    ("avx512bf16", Some(sym::avx512_target_feature)),
+    ("avx512bitalg", Some(sym::avx512_target_feature)),
     ("avx512bw", Some(sym::avx512_target_feature)),
     ("avx512cd", Some(sym::avx512_target_feature)),
     ("avx512dq", Some(sym::avx512_target_feature)),
     ("avx512er", Some(sym::avx512_target_feature)),
     ("avx512f", Some(sym::avx512_target_feature)),
+    ("avx512gfni", Some(sym::avx512_target_feature)),
     ("avx512ifma", Some(sym::avx512_target_feature)),
     ("avx512pf", Some(sym::avx512_target_feature)),
+    ("avx512vaes", Some(sym::avx512_target_feature)),
     ("avx512vbmi", Some(sym::avx512_target_feature)),
+    ("avx512vbmi2", Some(sym::avx512_target_feature)),
     ("avx512vl", Some(sym::avx512_target_feature)),
+    ("avx512vnni", Some(sym::avx512_target_feature)),
+    ("avx512vp2intersect", Some(sym::avx512_target_feature)),
+    ("avx512vpclmulqdq", Some(sym::avx512_target_feature)),
     ("avx512vpopcntdq", Some(sym::avx512_target_feature)),
     ("bmi1", None),
     ("bmi2", None),
diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs
index 978f08927c6ef..47c140e0b1882 100644
--- a/compiler/rustc_middle/src/middle/stability.rs
+++ b/compiler/rustc_middle/src/middle/stability.rs
@@ -4,7 +4,7 @@
 pub use self::StabilityLevel::*;
 
 use crate::ty::{self, TyCtxt};
-use rustc_ast::CRATE_NODE_ID;
+use rustc_ast::NodeId;
 use rustc_attr::{self as attr, ConstStability, Deprecation, Stability};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::{Applicability, DiagnosticBuilder};
@@ -211,13 +211,14 @@ pub fn early_report_deprecation(
     suggestion: Option<Symbol>,
     lint: &'static Lint,
     span: Span,
+    node_id: NodeId,
 ) {
     if span.in_derive_expansion() {
         return;
     }
 
     let diag = BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span);
-    lint_buffer.buffer_lint_with_diagnostic(lint, CRATE_NODE_ID, span, message, diag);
+    lint_buffer.buffer_lint_with_diagnostic(lint, node_id, span, message, diag);
 }
 
 fn late_report_deprecation(
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index d8d639ab73451..638dd8ce9706f 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -1,70 +1,70 @@
+//! # The MIR Visitor
+//!
+//! ## Overview
+//!
+//! There are two visitors, one for immutable and one for mutable references,
+//! but both are generated by the following macro. The code is written according
+//! to the following conventions:
+//!
+//! - introduce a `visit_foo` and a `super_foo` method for every MIR type
+//! - `visit_foo`, by default, calls `super_foo`
+//! - `super_foo`, by default, destructures the `foo` and calls `visit_foo`
+//!
+//! This allows you as a user to override `visit_foo` for types are
+//! interested in, and invoke (within that method) call
+//! `self.super_foo` to get the default behavior. Just as in an OO
+//! language, you should never call `super` methods ordinarily except
+//! in that circumstance.
+//!
+//! For the most part, we do not destructure things external to the
+//! MIR, e.g., types, spans, etc, but simply visit them and stop. This
+//! avoids duplication with other visitors like `TypeFoldable`.
+//!
+//! ## Updating
+//!
+//! The code is written in a very deliberate style intended to minimize
+//! the chance of things being overlooked. You'll notice that we always
+//! use pattern matching to reference fields and we ensure that all
+//! matches are exhaustive.
+//!
+//! For example, the `super_basic_block_data` method begins like this:
+//!
+//! ```rust
+//! fn super_basic_block_data(&mut self,
+//!                           block: BasicBlock,
+//!                           data: & $($mutability)? BasicBlockData<'tcx>) {
+//!     let BasicBlockData {
+//!         statements,
+//!         terminator,
+//!         is_cleanup: _
+//!     } = *data;
+//!
+//!     for statement in statements {
+//!         self.visit_statement(block, statement);
+//!     }
+//!
+//!     ...
+//! }
+//! ```
+//!
+//! Here we used `let BasicBlockData { <fields> } = *data` deliberately,
+//! rather than writing `data.statements` in the body. This is because if one
+//! adds a new field to `BasicBlockData`, one will be forced to revise this code,
+//! and hence one will (hopefully) invoke the correct visit methods (if any).
+//!
+//! For this to work, ALL MATCHES MUST BE EXHAUSTIVE IN FIELDS AND VARIANTS.
+//! That means you never write `..` to skip over fields, nor do you write `_`
+//! to skip over variants in a `match`.
+//!
+//! The only place that `_` is acceptable is to match a field (or
+//! variant argument) that does not require visiting, as in
+//! `is_cleanup` above.
+
 use crate::mir::*;
 use crate::ty::subst::SubstsRef;
 use crate::ty::{CanonicalUserTypeAnnotation, Ty};
 use rustc_span::Span;
 
-// # The MIR Visitor
-//
-// ## Overview
-//
-// There are two visitors, one for immutable and one for mutable references,
-// but both are generated by the following macro. The code is written according
-// to the following conventions:
-//
-// - introduce a `visit_foo` and a `super_foo` method for every MIR type
-// - `visit_foo`, by default, calls `super_foo`
-// - `super_foo`, by default, destructures the `foo` and calls `visit_foo`
-//
-// This allows you as a user to override `visit_foo` for types are
-// interested in, and invoke (within that method) call
-// `self.super_foo` to get the default behavior. Just as in an OO
-// language, you should never call `super` methods ordinarily except
-// in that circumstance.
-//
-// For the most part, we do not destructure things external to the
-// MIR, e.g., types, spans, etc, but simply visit them and stop. This
-// avoids duplication with other visitors like `TypeFoldable`.
-//
-// ## Updating
-//
-// The code is written in a very deliberate style intended to minimize
-// the chance of things being overlooked. You'll notice that we always
-// use pattern matching to reference fields and we ensure that all
-// matches are exhaustive.
-//
-// For example, the `super_basic_block_data` method begins like this:
-//
-// ```rust
-// fn super_basic_block_data(&mut self,
-//                           block: BasicBlock,
-//                           data: & $($mutability)? BasicBlockData<'tcx>) {
-//     let BasicBlockData {
-//         statements,
-//         terminator,
-//         is_cleanup: _
-//     } = *data;
-//
-//     for statement in statements {
-//         self.visit_statement(block, statement);
-//     }
-//
-//     ...
-// }
-// ```
-//
-// Here we used `let BasicBlockData { <fields> } = *data` deliberately,
-// rather than writing `data.statements` in the body. This is because if one
-// adds a new field to `BasicBlockData`, one will be forced to revise this code,
-// and hence one will (hopefully) invoke the correct visit methods (if any).
-//
-// For this to work, ALL MATCHES MUST BE EXHAUSTIVE IN FIELDS AND VARIANTS.
-// That means you never write `..` to skip over fields, nor do you write `_`
-// to skip over variants in a `match`.
-//
-// The only place that `_` is acceptable is to match a field (or
-// variant argument) that does not require visiting, as in
-// `is_cleanup` above.
-
 macro_rules! make_mir_visitor {
     ($visitor_trait_name:ident, $($mutability:ident)?) => {
         pub trait $visitor_trait_name<'tcx> {
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index acc7d3c4960e8..5626c864fe175 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -176,7 +176,7 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> {
         match *self {
             LayoutError::Unknown(ty) => write!(f, "the type `{}` has an unknown layout", ty),
             LayoutError::SizeOverflow(ty) => {
-                write!(f, "the type `{}` is too big for the current architecture", ty)
+                write!(f, "values of the type `{}` are too big for the current architecture", ty)
             }
         }
     }
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index e052b6b334529..21e43be20456b 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -1034,6 +1034,7 @@ impl<'a> Resolver<'a> {
                 depr.suggestion,
                 lint,
                 span,
+                node_id,
             );
         }
     }
diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
index 873d300a5e309..54743ef9ce911 100644
--- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
@@ -97,6 +97,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
         self.infcx.tcx
     }
 
+    #[instrument(skip(self))]
     fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
         if !ty.has_projections() {
             return ty;
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 41202546566a7..d67f9c15a1916 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -80,6 +80,7 @@
 #![feature(const_mut_refs)]
 #![feature(const_int_pow)]
 #![feature(constctlz)]
+#![feature(const_cttz)]
 #![feature(const_panic)]
 #![feature(const_pin)]
 #![feature(const_fn)]
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 5a9fd902c9ca1..716b4a90e5ec2 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -6,6 +6,7 @@ use crate::str::FromStr;
 
 use super::from_str_radix;
 use super::{IntErrorKind, ParseIntError};
+use crate::intrinsics;
 
 macro_rules! doc_comment {
     ($x:expr, $($tt:tt)*) => {
@@ -189,3 +190,76 @@ macro_rules! from_str_radix_nzint_impl {
 
 from_str_radix_nzint_impl! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize
 NonZeroI8 NonZeroI16 NonZeroI32 NonZeroI64 NonZeroI128 NonZeroIsize }
+
+macro_rules! nonzero_leading_trailing_zeros {
+    ( $( $Ty: ident($Uint: ty) , $LeadingTestExpr:expr ;)+ ) => {
+        $(
+            impl $Ty {
+                doc_comment! {
+                    concat!("Returns the number of leading zeros in the binary representation of `self`.
+
+On many architectures, this function can perform better than `leading_zeros()` on the underlying integer type, as special handling of zero can be avoided.
+
+# Examples
+
+Basic usage:
+
+```
+#![feature(nonzero_leading_trailing_zeros)]
+let n = std::num::", stringify!($Ty), "::new(", stringify!($LeadingTestExpr), ").unwrap();
+
+assert_eq!(n.leading_zeros(), 0);
+```"),
+                    #[unstable(feature = "nonzero_leading_trailing_zeros", issue = "79143")]
+                    #[rustc_const_unstable(feature = "nonzero_leading_trailing_zeros", issue = "79143")]
+                    #[inline]
+                    pub const fn leading_zeros(self) -> u32 {
+                        // SAFETY: since `self` can not be zero it is safe to call ctlz_nonzero
+                        unsafe { intrinsics::ctlz_nonzero(self.0 as $Uint) as u32 }
+                    }
+                }
+
+                doc_comment! {
+                    concat!("Returns the number of trailing zeros in the binary representation
+of `self`.
+
+On many architectures, this function can perform better than `trailing_zeros()` on the underlying integer type, as special handling of zero can be avoided.
+
+# Examples
+
+Basic usage:
+
+```
+#![feature(nonzero_leading_trailing_zeros)]
+let n = std::num::", stringify!($Ty), "::new(0b0101000).unwrap();
+
+assert_eq!(n.trailing_zeros(), 3);
+```"),
+                    #[unstable(feature = "nonzero_leading_trailing_zeros", issue = "79143")]
+                    #[rustc_const_unstable(feature = "nonzero_leading_trailing_zeros", issue = "79143")]
+                    #[inline]
+                    pub const fn trailing_zeros(self) -> u32 {
+                        // SAFETY: since `self` can not be zero it is safe to call cttz_nonzero
+                        unsafe { intrinsics::cttz_nonzero(self.0 as $Uint) as u32 }
+                    }
+                }
+
+            }
+        )+
+    }
+}
+
+nonzero_leading_trailing_zeros! {
+    NonZeroU8(u8), u8::MAX;
+    NonZeroU16(u16), u16::MAX;
+    NonZeroU32(u32), u32::MAX;
+    NonZeroU64(u64), u64::MAX;
+    NonZeroU128(u128), u128::MAX;
+    NonZeroUsize(usize), usize::MAX;
+    NonZeroI8(u8), -1i8;
+    NonZeroI16(u16), -1i16;
+    NonZeroI32(u32), -1i32;
+    NonZeroI64(u64), -1i64;
+    NonZeroI128(u128), -1i128;
+    NonZeroIsize(usize), -1isize;
+}
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index c9f9b890c3938..14ef03fd53eba 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -60,6 +60,8 @@
 #![feature(once_cell)]
 #![feature(unsafe_block_in_unsafe_fn)]
 #![feature(int_bits_const)]
+#![feature(nonzero_leading_trailing_zeros)]
+#![feature(const_option)]
 #![deny(unsafe_op_in_unsafe_fn)]
 
 extern crate test;
diff --git a/library/core/tests/nonzero.rs b/library/core/tests/nonzero.rs
index fb1293c99bba9..ca449b4350ede 100644
--- a/library/core/tests/nonzero.rs
+++ b/library/core/tests/nonzero.rs
@@ -1,5 +1,8 @@
 use core::convert::TryFrom;
-use core::num::{IntErrorKind, NonZeroI32, NonZeroI8, NonZeroU32, NonZeroU8};
+use core::num::{
+    IntErrorKind, NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize,
+    NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize,
+};
 use core::option::Option::{self, None, Some};
 use std::mem::size_of;
 
@@ -212,3 +215,100 @@ fn nonzero_const() {
     const ONE: Option<NonZeroU8> = NonZeroU8::new(1);
     assert!(ONE.is_some());
 }
+
+#[test]
+fn nonzero_leading_zeros() {
+    assert_eq!(NonZeroU8::new(1).unwrap().leading_zeros(), 7);
+    assert_eq!(NonZeroI8::new(1).unwrap().leading_zeros(), 7);
+    assert_eq!(NonZeroU16::new(1).unwrap().leading_zeros(), 15);
+    assert_eq!(NonZeroI16::new(1).unwrap().leading_zeros(), 15);
+    assert_eq!(NonZeroU32::new(1).unwrap().leading_zeros(), 31);
+    assert_eq!(NonZeroI32::new(1).unwrap().leading_zeros(), 31);
+    assert_eq!(NonZeroU64::new(1).unwrap().leading_zeros(), 63);
+    assert_eq!(NonZeroI64::new(1).unwrap().leading_zeros(), 63);
+    assert_eq!(NonZeroU128::new(1).unwrap().leading_zeros(), 127);
+    assert_eq!(NonZeroI128::new(1).unwrap().leading_zeros(), 127);
+    assert_eq!(NonZeroUsize::new(1).unwrap().leading_zeros(), usize::BITS - 1);
+    assert_eq!(NonZeroIsize::new(1).unwrap().leading_zeros(), usize::BITS - 1);
+
+    assert_eq!(NonZeroU8::new(u8::MAX >> 2).unwrap().leading_zeros(), 2);
+    assert_eq!(NonZeroI8::new((u8::MAX >> 2) as i8).unwrap().leading_zeros(), 2);
+    assert_eq!(NonZeroU16::new(u16::MAX >> 2).unwrap().leading_zeros(), 2);
+    assert_eq!(NonZeroI16::new((u16::MAX >> 2) as i16).unwrap().leading_zeros(), 2);
+    assert_eq!(NonZeroU32::new(u32::MAX >> 2).unwrap().leading_zeros(), 2);
+    assert_eq!(NonZeroI32::new((u32::MAX >> 2) as i32).unwrap().leading_zeros(), 2);
+    assert_eq!(NonZeroU64::new(u64::MAX >> 2).unwrap().leading_zeros(), 2);
+    assert_eq!(NonZeroI64::new((u64::MAX >> 2) as i64).unwrap().leading_zeros(), 2);
+    assert_eq!(NonZeroU128::new(u128::MAX >> 2).unwrap().leading_zeros(), 2);
+    assert_eq!(NonZeroI128::new((u128::MAX >> 2) as i128).unwrap().leading_zeros(), 2);
+    assert_eq!(NonZeroUsize::new(usize::MAX >> 2).unwrap().leading_zeros(), 2);
+    assert_eq!(NonZeroIsize::new((usize::MAX >> 2) as isize).unwrap().leading_zeros(), 2);
+
+    assert_eq!(NonZeroU8::new(u8::MAX).unwrap().leading_zeros(), 0);
+    assert_eq!(NonZeroI8::new(-1i8).unwrap().leading_zeros(), 0);
+    assert_eq!(NonZeroU16::new(u16::MAX).unwrap().leading_zeros(), 0);
+    assert_eq!(NonZeroI16::new(-1i16).unwrap().leading_zeros(), 0);
+    assert_eq!(NonZeroU32::new(u32::MAX).unwrap().leading_zeros(), 0);
+    assert_eq!(NonZeroI32::new(-1i32).unwrap().leading_zeros(), 0);
+    assert_eq!(NonZeroU64::new(u64::MAX).unwrap().leading_zeros(), 0);
+    assert_eq!(NonZeroI64::new(-1i64).unwrap().leading_zeros(), 0);
+    assert_eq!(NonZeroU128::new(u128::MAX).unwrap().leading_zeros(), 0);
+    assert_eq!(NonZeroI128::new(-1i128).unwrap().leading_zeros(), 0);
+    assert_eq!(NonZeroUsize::new(usize::MAX).unwrap().leading_zeros(), 0);
+    assert_eq!(NonZeroIsize::new(-1isize).unwrap().leading_zeros(), 0);
+
+    const LEADING_ZEROS: u32 = NonZeroU16::new(1).unwrap().leading_zeros();
+    assert_eq!(LEADING_ZEROS, 15);
+}
+
+#[test]
+fn nonzero_trailing_zeros() {
+    assert_eq!(NonZeroU8::new(1).unwrap().trailing_zeros(), 0);
+    assert_eq!(NonZeroI8::new(1).unwrap().trailing_zeros(), 0);
+    assert_eq!(NonZeroU16::new(1).unwrap().trailing_zeros(), 0);
+    assert_eq!(NonZeroI16::new(1).unwrap().trailing_zeros(), 0);
+    assert_eq!(NonZeroU32::new(1).unwrap().trailing_zeros(), 0);
+    assert_eq!(NonZeroI32::new(1).unwrap().trailing_zeros(), 0);
+    assert_eq!(NonZeroU64::new(1).unwrap().trailing_zeros(), 0);
+    assert_eq!(NonZeroI64::new(1).unwrap().trailing_zeros(), 0);
+    assert_eq!(NonZeroU128::new(1).unwrap().trailing_zeros(), 0);
+    assert_eq!(NonZeroI128::new(1).unwrap().trailing_zeros(), 0);
+    assert_eq!(NonZeroUsize::new(1).unwrap().trailing_zeros(), 0);
+    assert_eq!(NonZeroIsize::new(1).unwrap().trailing_zeros(), 0);
+
+    assert_eq!(NonZeroU8::new(1 << 2).unwrap().trailing_zeros(), 2);
+    assert_eq!(NonZeroI8::new(1 << 2).unwrap().trailing_zeros(), 2);
+    assert_eq!(NonZeroU16::new(1 << 2).unwrap().trailing_zeros(), 2);
+    assert_eq!(NonZeroI16::new(1 << 2).unwrap().trailing_zeros(), 2);
+    assert_eq!(NonZeroU32::new(1 << 2).unwrap().trailing_zeros(), 2);
+    assert_eq!(NonZeroI32::new(1 << 2).unwrap().trailing_zeros(), 2);
+    assert_eq!(NonZeroU64::new(1 << 2).unwrap().trailing_zeros(), 2);
+    assert_eq!(NonZeroI64::new(1 << 2).unwrap().trailing_zeros(), 2);
+    assert_eq!(NonZeroU128::new(1 << 2).unwrap().trailing_zeros(), 2);
+    assert_eq!(NonZeroI128::new(1 << 2).unwrap().trailing_zeros(), 2);
+    assert_eq!(NonZeroUsize::new(1 << 2).unwrap().trailing_zeros(), 2);
+    assert_eq!(NonZeroIsize::new(1 << 2).unwrap().trailing_zeros(), 2);
+
+    assert_eq!(NonZeroU8::new(1 << 7).unwrap().trailing_zeros(), 7);
+    assert_eq!(NonZeroI8::new(1 << 7).unwrap().trailing_zeros(), 7);
+    assert_eq!(NonZeroU16::new(1 << 15).unwrap().trailing_zeros(), 15);
+    assert_eq!(NonZeroI16::new(1 << 15).unwrap().trailing_zeros(), 15);
+    assert_eq!(NonZeroU32::new(1 << 31).unwrap().trailing_zeros(), 31);
+    assert_eq!(NonZeroI32::new(1 << 31).unwrap().trailing_zeros(), 31);
+    assert_eq!(NonZeroU64::new(1 << 63).unwrap().trailing_zeros(), 63);
+    assert_eq!(NonZeroI64::new(1 << 63).unwrap().trailing_zeros(), 63);
+    assert_eq!(NonZeroU128::new(1 << 127).unwrap().trailing_zeros(), 127);
+    assert_eq!(NonZeroI128::new(1 << 127).unwrap().trailing_zeros(), 127);
+
+    assert_eq!(
+        NonZeroUsize::new(1 << (usize::BITS - 1)).unwrap().trailing_zeros(),
+        usize::BITS - 1
+    );
+    assert_eq!(
+        NonZeroIsize::new(1 << (usize::BITS - 1)).unwrap().trailing_zeros(),
+        usize::BITS - 1
+    );
+
+    const TRAILING_ZEROS: u32 = NonZeroU16::new(1 << 2).unwrap().trailing_zeros();
+    assert_eq!(TRAILING_ZEROS, 2);
+}
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index 703c3755b6383..dfbf6c3f24443 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -1307,10 +1307,10 @@ pub trait Write {
         default_write_vectored(|b| self.write(b), bufs)
     }
 
-    /// Determines if this `Write`er has an efficient [`write_vectored`]
+    /// Determines if this `Write`r has an efficient [`write_vectored`]
     /// implementation.
     ///
-    /// If a `Write`er does not override the default [`write_vectored`]
+    /// If a `Write`r does not override the default [`write_vectored`]
     /// implementation, code using it may want to avoid the method all together
     /// and coalesce writes into a single buffer for higher performance.
     ///
diff --git a/library/std/src/sys/unix/kernel_copy.rs b/library/std/src/sys/unix/kernel_copy.rs
index ac2fcfcb53f72..1dc16ef099367 100644
--- a/library/std/src/sys/unix/kernel_copy.rs
+++ b/library/std/src/sys/unix/kernel_copy.rs
@@ -445,15 +445,15 @@ pub(super) fn copy_regular_files(reader: RawFd, writer: RawFd, max_len: u64) ->
     // We store the availability in a global to avoid unnecessary syscalls
     static HAS_COPY_FILE_RANGE: AtomicBool = AtomicBool::new(true);
 
-    unsafe fn copy_file_range(
-        fd_in: libc::c_int,
-        off_in: *mut libc::loff_t,
-        fd_out: libc::c_int,
-        off_out: *mut libc::loff_t,
-        len: libc::size_t,
-        flags: libc::c_uint,
-    ) -> libc::c_long {
-        libc::syscall(libc::SYS_copy_file_range, fd_in, off_in, fd_out, off_out, len, flags)
+    syscall! {
+        fn copy_file_range(
+            fd_in: libc::c_int,
+            off_in: *mut libc::loff_t,
+            fd_out: libc::c_int,
+            off_out: *mut libc::loff_t,
+            len: libc::size_t,
+            flags: libc::c_uint
+        ) -> libc::ssize_t
     }
 
     let has_copy_file_range = HAS_COPY_FILE_RANGE.load(Ordering::Relaxed);
diff --git a/library/std/src/sys/unix/rand.rs b/library/std/src/sys/unix/rand.rs
index eed6fbf13b7d2..38ddb41700c4b 100644
--- a/library/std/src/sys/unix/rand.rs
+++ b/library/std/src/sys/unix/rand.rs
@@ -25,10 +25,19 @@ mod imp {
     use crate::io::Read;
 
     #[cfg(any(target_os = "linux", target_os = "android"))]
-    fn getrandom(buf: &mut [u8]) -> libc::c_long {
-        unsafe {
-            libc::syscall(libc::SYS_getrandom, buf.as_mut_ptr(), buf.len(), libc::GRND_NONBLOCK)
+    fn getrandom(buf: &mut [u8]) -> libc::ssize_t {
+        // A weak symbol allows interposition, e.g. for perf measurements that want to
+        // disable randomness for consistency. Otherwise, we'll try a raw syscall.
+        // (`getrandom` was added in glibc 2.25, musl 1.1.20, android API level 28)
+        syscall! {
+            fn getrandom(
+                buffer: *mut libc::c_void,
+                length: libc::size_t,
+                flags: libc::c_uint
+            ) -> libc::ssize_t
         }
+
+        unsafe { getrandom(buf.as_mut_ptr().cast(), buf.len(), libc::GRND_NONBLOCK) }
     }
 
     #[cfg(not(any(target_os = "linux", target_os = "android")))]
diff --git a/library/std/src/sys/unix/weak.rs b/library/std/src/sys/unix/weak.rs
index f4b33a00f7c85..53d95dca4cd82 100644
--- a/library/std/src/sys/unix/weak.rs
+++ b/library/std/src/sys/unix/weak.rs
@@ -24,7 +24,7 @@
 use crate::ffi::CStr;
 use crate::marker;
 use crate::mem;
-use crate::sync::atomic::{AtomicUsize, Ordering};
+use crate::sync::atomic::{self, AtomicUsize, Ordering};
 
 macro_rules! weak {
     (fn $name:ident($($t:ty),*) -> $ret:ty) => (
@@ -47,15 +47,49 @@ impl<F> Weak<F> {
     pub fn get(&self) -> Option<F> {
         assert_eq!(mem::size_of::<F>(), mem::size_of::<usize>());
         unsafe {
-            if self.addr.load(Ordering::SeqCst) == 1 {
-                self.addr.store(fetch(self.name), Ordering::SeqCst);
-            }
-            match self.addr.load(Ordering::SeqCst) {
+            // Relaxed is fine here because we fence before reading through the
+            // pointer (see the comment below).
+            match self.addr.load(Ordering::Relaxed) {
+                1 => self.initialize(),
                 0 => None,
-                addr => Some(mem::transmute_copy::<usize, F>(&addr)),
+                addr => {
+                    let func = mem::transmute_copy::<usize, F>(&addr);
+                    // The caller is presumably going to read through this value
+                    // (by calling the function we've dlsymed). This means we'd
+                    // need to have loaded it with at least C11's consume
+                    // ordering in order to be guaranteed that the data we read
+                    // from the pointer isn't from before the pointer was
+                    // stored. Rust has no equivalent to memory_order_consume,
+                    // so we use an acquire fence (sorry, ARM).
+                    //
+                    // Now, in practice this likely isn't needed even on CPUs
+                    // where relaxed and consume mean different things. The
+                    // symbols we're loading are probably present (or not) at
+                    // init, and even if they aren't the runtime dynamic loader
+                    // is extremely likely have sufficient barriers internally
+                    // (possibly implicitly, for example the ones provided by
+                    // invoking `mprotect`).
+                    //
+                    // That said, none of that's *guaranteed*, and so we fence.
+                    atomic::fence(Ordering::Acquire);
+                    Some(func)
+                }
             }
         }
     }
+
+    // Cold because it should only happen during first-time initalization.
+    #[cold]
+    unsafe fn initialize(&self) -> Option<F> {
+        let val = fetch(self.name);
+        // This synchronizes with the acquire fence in `get`.
+        self.addr.store(val, Ordering::Release);
+
+        match val {
+            0 => None,
+            addr => Some(mem::transmute_copy::<usize, F>(&addr)),
+        }
+    }
 }
 
 unsafe fn fetch(name: &str) -> usize {
@@ -66,7 +100,7 @@ unsafe fn fetch(name: &str) -> usize {
     libc::dlsym(libc::RTLD_DEFAULT, name.as_ptr()) as usize
 }
 
-#[cfg(not(target_os = "linux"))]
+#[cfg(not(any(target_os = "linux", target_os = "android")))]
 macro_rules! syscall {
     (fn $name:ident($($arg_name:ident: $t:ty),*) -> $ret:ty) => (
         unsafe fn $name($($arg_name: $t),*) -> $ret {
@@ -84,7 +118,7 @@ macro_rules! syscall {
     )
 }
 
-#[cfg(target_os = "linux")]
+#[cfg(any(target_os = "linux", target_os = "android"))]
 macro_rules! syscall {
     (fn $name:ident($($arg_name:ident: $t:ty),*) -> $ret:ty) => (
         unsafe fn $name($($arg_name:$t),*) -> $ret {
@@ -92,10 +126,18 @@ macro_rules! syscall {
             // (not paths).
             use libc::*;
 
-            syscall(
-                concat_idents!(SYS_, $name),
-                $($arg_name as c_long),*
-            ) as $ret
+            weak! { fn $name($($t),*) -> $ret }
+
+            // Use a weak symbol from libc when possible, allowing `LD_PRELOAD`
+            // interposition, but if it's not found just use a raw syscall.
+            if let Some(fun) = $name.get() {
+                fun($($arg_name),*)
+            } else {
+                syscall(
+                    concat_idents!(SYS_, $name),
+                    $($arg_name as c_long),*
+                ) as $ret
+            }
         }
     )
 }
diff --git a/library/std/tests/run-time-detect.rs b/library/std/tests/run-time-detect.rs
index 8dd1a8ac0d2df..61a04c467224b 100644
--- a/library/std/tests/run-time-detect.rs
+++ b/library/std/tests/run-time-detect.rs
@@ -54,42 +54,62 @@ fn powerpc64_linux() {
 #[test]
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
 fn x86_all() {
+    // the below is the set of features we can test at runtime, but don't actually
+    // use to gate anything and are thus not part of the X86_ALLOWED_FEATURES list
+
+    println!("abm: {:?}", is_x86_feature_detected!("abm")); // this is a synonym for lzcnt but we test it anyways
+    println!("mmx: {:?}", is_x86_feature_detected!("mmx"));
+    println!("tsc: {:?}", is_x86_feature_detected!("tsc"));
+
+    // the below is in alphabetical order and matches
+    // the order of X86_ALLOWED_FEATURES in rustc_codegen_ssa's target_features.rs
+
+    println!("adx: {:?}", is_x86_feature_detected!("adx"));
     println!("aes: {:?}", is_x86_feature_detected!("aes"));
-    println!("pcmulqdq: {:?}", is_x86_feature_detected!("pclmulqdq"));
+    println!("avx: {:?}", is_x86_feature_detected!("avx"));
+    println!("avx2: {:?}", is_x86_feature_detected!("avx2"));
+    println!("avx512bf16: {:?}", is_x86_feature_detected!("avx512bf16"));
+    println!("avx512bitalg: {:?}", is_x86_feature_detected!("avx512bitalg"));
+    println!("avx512bw: {:?}", is_x86_feature_detected!("avx512bw"));
+    println!("avx512cd: {:?}", is_x86_feature_detected!("avx512cd"));
+    println!("avx512dq: {:?}", is_x86_feature_detected!("avx512dq"));
+    println!("avx512er: {:?}", is_x86_feature_detected!("avx512er"));
+    println!("avx512f: {:?}", is_x86_feature_detected!("avx512f"));
+    println!("avx512gfni: {:?}", is_x86_feature_detected!("avx512gfni"));
+    println!("avx512ifma: {:?}", is_x86_feature_detected!("avx512ifma"));
+    println!("avx512pf: {:?}", is_x86_feature_detected!("avx512pf"));
+    println!("avx512vaes: {:?}", is_x86_feature_detected!("avx512vaes"));
+    println!("avx512vbmi: {:?}", is_x86_feature_detected!("avx512vbmi"));
+    println!("avx512vbmi2: {:?}", is_x86_feature_detected!("avx512vbmi2"));
+    println!("avx512vl: {:?}", is_x86_feature_detected!("avx512vl"));
+    println!("avx512vnni: {:?}", is_x86_feature_detected!("avx512vnni"));
+    println!("avx512vp2intersect: {:?}", is_x86_feature_detected!("avx512vp2intersect"));
+    println!("avx512vpclmulqdq: {:?}", is_x86_feature_detected!("avx512vpclmulqdq"));
+    println!("avx512vpopcntdq: {:?}", is_x86_feature_detected!("avx512vpopcntdq"));
+    println!("bmi1: {:?}", is_x86_feature_detected!("bmi1"));
+    println!("bmi2: {:?}", is_x86_feature_detected!("bmi2"));
+    println!("cmpxchg16b: {:?}", is_x86_feature_detected!("cmpxchg16b"));
+    println!("f16c: {:?}", is_x86_feature_detected!("f16c"));
+    println!("fma: {:?}", is_x86_feature_detected!("fma"));
+    println!("fxsr: {:?}", is_x86_feature_detected!("fxsr"));
+    println!("lzcnt: {:?}", is_x86_feature_detected!("lzcnt"));
+    //println!("movbe: {:?}", is_x86_feature_detected!("movbe")); // movbe is unsupported as a target feature
+    println!("pclmulqdq: {:?}", is_x86_feature_detected!("pclmulqdq"));
+    println!("popcnt: {:?}", is_x86_feature_detected!("popcnt"));
     println!("rdrand: {:?}", is_x86_feature_detected!("rdrand"));
     println!("rdseed: {:?}", is_x86_feature_detected!("rdseed"));
-    println!("tsc: {:?}", is_x86_feature_detected!("tsc"));
-    println!("mmx: {:?}", is_x86_feature_detected!("mmx"));
+    println!("rtm: {:?}", is_x86_feature_detected!("rtm"));
+    println!("sha: {:?}", is_x86_feature_detected!("sha"));
     println!("sse: {:?}", is_x86_feature_detected!("sse"));
     println!("sse2: {:?}", is_x86_feature_detected!("sse2"));
     println!("sse3: {:?}", is_x86_feature_detected!("sse3"));
-    println!("ssse3: {:?}", is_x86_feature_detected!("ssse3"));
     println!("sse4.1: {:?}", is_x86_feature_detected!("sse4.1"));
     println!("sse4.2: {:?}", is_x86_feature_detected!("sse4.2"));
     println!("sse4a: {:?}", is_x86_feature_detected!("sse4a"));
-    println!("sha: {:?}", is_x86_feature_detected!("sha"));
-    println!("avx: {:?}", is_x86_feature_detected!("avx"));
-    println!("avx2: {:?}", is_x86_feature_detected!("avx2"));
-    println!("avx512f {:?}", is_x86_feature_detected!("avx512f"));
-    println!("avx512cd {:?}", is_x86_feature_detected!("avx512cd"));
-    println!("avx512er {:?}", is_x86_feature_detected!("avx512er"));
-    println!("avx512pf {:?}", is_x86_feature_detected!("avx512pf"));
-    println!("avx512bw {:?}", is_x86_feature_detected!("avx512bw"));
-    println!("avx512dq {:?}", is_x86_feature_detected!("avx512dq"));
-    println!("avx512vl {:?}", is_x86_feature_detected!("avx512vl"));
-    println!("avx512_ifma {:?}", is_x86_feature_detected!("avx512ifma"));
-    println!("avx512_vbmi {:?}", is_x86_feature_detected!("avx512vbmi"));
-    println!("avx512_vpopcntdq {:?}", is_x86_feature_detected!("avx512vpopcntdq"));
-    println!("fma: {:?}", is_x86_feature_detected!("fma"));
-    println!("bmi1: {:?}", is_x86_feature_detected!("bmi1"));
-    println!("bmi2: {:?}", is_x86_feature_detected!("bmi2"));
-    println!("abm: {:?}", is_x86_feature_detected!("abm"));
-    println!("lzcnt: {:?}", is_x86_feature_detected!("lzcnt"));
+    println!("ssse3: {:?}", is_x86_feature_detected!("ssse3"));
     println!("tbm: {:?}", is_x86_feature_detected!("tbm"));
-    println!("popcnt: {:?}", is_x86_feature_detected!("popcnt"));
-    println!("fxsr: {:?}", is_x86_feature_detected!("fxsr"));
     println!("xsave: {:?}", is_x86_feature_detected!("xsave"));
+    println!("xsavec: {:?}", is_x86_feature_detected!("xsavec"));
     println!("xsaveopt: {:?}", is_x86_feature_detected!("xsaveopt"));
     println!("xsaves: {:?}", is_x86_feature_detected!("xsaves"));
-    println!("xsavec: {:?}", is_x86_feature_detected!("xsavec"));
 }
diff --git a/library/stdarch b/library/stdarch
index 3c3664355ef46..777efaf564470 160000
--- a/library/stdarch
+++ b/library/stdarch
@@ -1 +1 @@
-Subproject commit 3c3664355ef46e788b53080e521d6542fbddfd84
+Subproject commit 777efaf5644706b36706a7a5c51edb63835e05ca
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 54d0a23dec58d..4fb58034ce216 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -360,7 +360,6 @@ def output(filepath):
 class RustBuild(object):
     """Provide all the methods required to build Rust"""
     def __init__(self):
-        self.cargo_channel = ''
         self.date = ''
         self._download_url = ''
         self.rustc_channel = ''
@@ -387,7 +386,6 @@ def download_stage0(self):
         will move all the content to the right place.
         """
         rustc_channel = self.rustc_channel
-        cargo_channel = self.cargo_channel
         rustfmt_channel = self.rustfmt_channel
 
         if self.rustc().startswith(self.bin_root()) and \
@@ -400,12 +398,15 @@ def download_stage0(self):
                 rustc_channel, self.build, tarball_suffix)
             pattern = "rust-std-{}".format(self.build)
             self._download_stage0_helper(filename, pattern, tarball_suffix)
-
             filename = "rustc-{}-{}{}".format(rustc_channel, self.build,
                                               tarball_suffix)
             self._download_stage0_helper(filename, "rustc", tarball_suffix)
+            filename = "cargo-{}-{}{}".format(rustc_channel, self.build,
+                                              tarball_suffix)
+            self._download_stage0_helper(filename, "cargo", tarball_suffix)
             self.fix_bin_or_dylib("{}/bin/rustc".format(self.bin_root()))
             self.fix_bin_or_dylib("{}/bin/rustdoc".format(self.bin_root()))
+            self.fix_bin_or_dylib("{}/bin/cargo".format(self.bin_root()))
             lib_dir = "{}/lib".format(self.bin_root())
             for lib in os.listdir(lib_dir):
                 if lib.endswith(".so"):
@@ -413,17 +414,6 @@ def download_stage0(self):
             with output(self.rustc_stamp()) as rust_stamp:
                 rust_stamp.write(self.date)
 
-        if self.cargo().startswith(self.bin_root()) and \
-                (not os.path.exists(self.cargo()) or
-                 self.program_out_of_date(self.cargo_stamp())):
-            tarball_suffix = '.tar.xz' if support_xz() else '.tar.gz'
-            filename = "cargo-{}-{}{}".format(cargo_channel, self.build,
-                                              tarball_suffix)
-            self._download_stage0_helper(filename, "cargo", tarball_suffix)
-            self.fix_bin_or_dylib("{}/bin/cargo".format(self.bin_root()))
-            with output(self.cargo_stamp()) as cargo_stamp:
-                cargo_stamp.write(self.date)
-
         if self.rustfmt() and self.rustfmt().startswith(self.bin_root()) and (
             not os.path.exists(self.rustfmt())
             or self.program_out_of_date(self.rustfmt_stamp(), self.rustfmt_channel)
@@ -601,16 +591,6 @@ def rustc_stamp(self):
         """
         return os.path.join(self.bin_root(), '.rustc-stamp')
 
-    def cargo_stamp(self):
-        """Return the path for .cargo-stamp
-
-        >>> rb = RustBuild()
-        >>> rb.build_dir = "build"
-        >>> rb.cargo_stamp() == os.path.join("build", "stage0", ".cargo-stamp")
-        True
-        """
-        return os.path.join(self.bin_root(), '.cargo-stamp')
-
     def rustfmt_stamp(self):
         """Return the path for .rustfmt-stamp
 
@@ -1056,7 +1036,6 @@ def bootstrap(help_triggered):
     data = stage0_data(build.rust_root)
     build.date = data['date']
     build.rustc_channel = data['rustc']
-    build.cargo_channel = data['cargo']
 
     if "rustfmt" in data:
         build.rustfmt_channel = data['rustfmt']
diff --git a/src/stage0.txt b/src/stage0.txt
index 9eaa58dd43869..dae9d219b7b9b 100644
--- a/src/stage0.txt
+++ b/src/stage0.txt
@@ -1,6 +1,5 @@
 # This file describes the stage0 compiler that's used to then bootstrap the Rust
-# compiler itself. For the rustbuild build system, this also describes the
-# relevant Cargo revision that we're using.
+# compiler itself.
 #
 # Currently Rust always bootstraps from the previous stable release, and in our
 # train model this means that the master branch bootstraps from beta, beta
@@ -8,13 +7,13 @@
 # release.
 #
 # If you're looking at this file on the master branch, you'll likely see that
-# rustc and cargo are configured to `beta`, whereas if you're looking at a
-# source tarball for a stable release you'll likely see `1.x.0` for rustc and
-# `0.(x+1).0` for Cargo where they were released on `date`.
+# rustc is configured to `beta`, whereas if you're looking at a source tarball
+# for a stable release you'll likely see `1.x.0` for rustc, with the previous
+# stable release's version number. `date` is the date where the release we're
+# bootstrapping off was released.
 
 date: 2020-10-16
 rustc: beta
-cargo: beta
 
 # We use a nightly rustfmt to format the source because it solves some
 # bootstrapping issues with use of new syntax in this repo. If you're looking at
diff --git a/src/test/compile-fail/consts/issue-55878.rs b/src/test/compile-fail/consts/issue-55878.rs
index aa1dd58d2463d..541befa7b1310 100644
--- a/src/test/compile-fail/consts/issue-55878.rs
+++ b/src/test/compile-fail/consts/issue-55878.rs
@@ -1,7 +1,7 @@
 // normalize-stderr-64bit "18446744073709551615" -> "SIZE"
 // normalize-stderr-32bit "4294967295" -> "SIZE"
 
-// error-pattern: is too big for the current architecture
+// error-pattern: are too big for the current architecture
 fn main() {
     println!("Size: {}", std::mem::size_of::<[u8; std::u64::MAX as usize]>());
 }
diff --git a/src/test/ui/huge-array-simple-32.stderr b/src/test/ui/huge-array-simple-32.stderr
index d734a9689e05c..31e120df626de 100644
--- a/src/test/ui/huge-array-simple-32.stderr
+++ b/src/test/ui/huge-array-simple-32.stderr
@@ -1,4 +1,4 @@
-error: the type `[u8; 2147516416]` is too big for the current architecture
+error: values of the type `[u8; 2147516416]` are too big for the current architecture
   --> $DIR/huge-array-simple-32.rs:10:9
    |
 LL |     let _fat: [u8; (1<<31)+(1<<15)] =
diff --git a/src/test/ui/huge-array-simple-64.stderr b/src/test/ui/huge-array-simple-64.stderr
index 791baa8468747..c5d3fe85d0d83 100644
--- a/src/test/ui/huge-array-simple-64.stderr
+++ b/src/test/ui/huge-array-simple-64.stderr
@@ -1,4 +1,4 @@
-error: the type `[u8; 2305843011361177600]` is too big for the current architecture
+error: values of the type `[u8; 2305843011361177600]` are too big for the current architecture
   --> $DIR/huge-array-simple-64.rs:10:9
    |
 LL |     let _fat: [u8; (1<<61)+(1<<31)] =
diff --git a/src/test/ui/huge-array.rs b/src/test/ui/huge-array.rs
index 846380586a009..3070801f86576 100644
--- a/src/test/ui/huge-array.rs
+++ b/src/test/ui/huge-array.rs
@@ -6,7 +6,7 @@
 
 fn generic<T: Copy>(t: T) {
     let s: [T; 1518600000] = [t; 1518600000];
-    //~^ ERROR the type `[[u8; 1518599999]; 1518600000]` is too big for the current architecture
+    //~^ ERROR values of the type `[[u8; 1518599999]; 1518600000]` are too big
 }
 
 fn main() {
diff --git a/src/test/ui/huge-array.stderr b/src/test/ui/huge-array.stderr
index 23d9e87ae0054..817458b73e47b 100644
--- a/src/test/ui/huge-array.stderr
+++ b/src/test/ui/huge-array.stderr
@@ -1,4 +1,4 @@
-error: the type `[[u8; 1518599999]; 1518600000]` is too big for the current architecture
+error: values of the type `[[u8; 1518599999]; 1518600000]` are too big for the current architecture
   --> $DIR/huge-array.rs:8:9
    |
 LL |     let s: [T; 1518600000] = [t; 1518600000];
diff --git a/src/test/ui/huge-enum.rs b/src/test/ui/huge-enum.rs
index 8a713c3a26eda..39ea6e11b1ff7 100644
--- a/src/test/ui/huge-enum.rs
+++ b/src/test/ui/huge-enum.rs
@@ -14,5 +14,5 @@ type BIG = Option<[u32; (1<<45)-1]>;
 
 fn main() {
     let big: BIG = None;
-    //~^ ERROR is too big for the current architecture
+    //~^ ERROR are too big for the current architecture
 }
diff --git a/src/test/ui/huge-enum.stderr b/src/test/ui/huge-enum.stderr
index a069c37b80a21..a1456e1a8ab0a 100644
--- a/src/test/ui/huge-enum.stderr
+++ b/src/test/ui/huge-enum.stderr
@@ -1,4 +1,4 @@
-error: the type `Option<TYPE>` is too big for the current architecture
+error: values of the type `Option<TYPE>` are too big for the current architecture
   --> $DIR/huge-enum.rs:16:9
    |
 LL |     let big: BIG = None;
diff --git a/src/test/ui/huge-struct.rs b/src/test/ui/huge-struct.rs
index 71169a1104798..02f38d860b496 100644
--- a/src/test/ui/huge-struct.rs
+++ b/src/test/ui/huge-struct.rs
@@ -48,6 +48,6 @@ struct S1M<T> { val: S1k<S1k<T>> }
 
 fn main() {
     let fat: Option<S1M<S1M<S1M<u32>>>> = None;
-    //~^ ERROR is too big for the current architecture
+    //~^ ERROR are too big for the current architecture
 
 }
diff --git a/src/test/ui/huge-struct.stderr b/src/test/ui/huge-struct.stderr
index 72e32a8593b18..f0ee88e595539 100644
--- a/src/test/ui/huge-struct.stderr
+++ b/src/test/ui/huge-struct.stderr
@@ -1,4 +1,4 @@
-error: the type `SXX<SXX<SXX<u32>>>` is too big for the current architecture
+error: values of the type `SXX<SXX<SXX<u32>>>` are too big for the current architecture
   --> $DIR/huge-struct.rs:50:9
    |
 LL |     let fat: Option<SXX<SXX<SXX<u32>>>> = None;
diff --git a/src/test/ui/issues/issue-15919-32.stderr b/src/test/ui/issues/issue-15919-32.stderr
index 8411313fc81b3..133637f9a058b 100644
--- a/src/test/ui/issues/issue-15919-32.stderr
+++ b/src/test/ui/issues/issue-15919-32.stderr
@@ -1,4 +1,4 @@
-error: the type `[usize; 4294967295]` is too big for the current architecture
+error: values of the type `[usize; 4294967295]` are too big for the current architecture
   --> $DIR/issue-15919-32.rs:9:9
    |
 LL |     let x = [0usize; 0xffff_ffff];
diff --git a/src/test/ui/issues/issue-15919-64.stderr b/src/test/ui/issues/issue-15919-64.stderr
index f624c96ce84da..193b823035c09 100644
--- a/src/test/ui/issues/issue-15919-64.stderr
+++ b/src/test/ui/issues/issue-15919-64.stderr
@@ -1,4 +1,4 @@
-error: the type `[usize; 18446744073709551615]` is too big for the current architecture
+error: values of the type `[usize; 18446744073709551615]` are too big for the current architecture
   --> $DIR/issue-15919-64.rs:9:9
    |
 LL |     let x = [0usize; 0xffff_ffff_ffff_ffff];
diff --git a/src/test/ui/issues/issue-17913.stderr b/src/test/ui/issues/issue-17913.stderr
index ae388c4d491df..9a6431d447004 100644
--- a/src/test/ui/issues/issue-17913.stderr
+++ b/src/test/ui/issues/issue-17913.stderr
@@ -1,4 +1,4 @@
-error: the type `[&usize; N]` is too big for the current architecture
+error: values of the type `[&usize; N]` are too big for the current architecture
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-56762.rs b/src/test/ui/issues/issue-56762.rs
index 5ba5b9847d085..fb0a270f18bef 100644
--- a/src/test/ui/issues/issue-56762.rs
+++ b/src/test/ui/issues/issue-56762.rs
@@ -17,8 +17,8 @@ impl TooBigArray {
 }
 
 static MY_TOO_BIG_ARRAY_1: TooBigArray = TooBigArray::new();
-//~^ ERROR the type `[u8; 2305843009213693951]` is too big for the current architecture
+//~^ ERROR values of the type `[u8; 2305843009213693951]` are too big
 static MY_TOO_BIG_ARRAY_2: [u8; HUGE_SIZE] = [0x00; HUGE_SIZE];
-//~^ ERROR the type `[u8; 2305843009213693951]` is too big for the current architecture
+//~^ ERROR values of the type `[u8; 2305843009213693951]` are too big
 
 fn main() { }
diff --git a/src/test/ui/issues/issue-56762.stderr b/src/test/ui/issues/issue-56762.stderr
index 69626d4bc7a9e..f26ef280b20b7 100644
--- a/src/test/ui/issues/issue-56762.stderr
+++ b/src/test/ui/issues/issue-56762.stderr
@@ -1,10 +1,10 @@
-error[E0080]: the type `[u8; 2305843009213693951]` is too big for the current architecture
+error[E0080]: values of the type `[u8; 2305843009213693951]` are too big for the current architecture
   --> $DIR/issue-56762.rs:19:1
    |
 LL | static MY_TOO_BIG_ARRAY_1: TooBigArray = TooBigArray::new();
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0080]: the type `[u8; 2305843009213693951]` is too big for the current architecture
+error[E0080]: values of the type `[u8; 2305843009213693951]` are too big for the current architecture
   --> $DIR/issue-56762.rs:21:1
    |
 LL | static MY_TOO_BIG_ARRAY_2: [u8; HUGE_SIZE] = [0x00; HUGE_SIZE];
diff --git a/src/test/ui/layout/big-type-no-err.rs b/src/test/ui/layout/big-type-no-err.rs
new file mode 100644
index 0000000000000..af8191a9cb919
--- /dev/null
+++ b/src/test/ui/layout/big-type-no-err.rs
@@ -0,0 +1,13 @@
+// Enormous types are allowed if they are never actually instantiated.
+// run-pass
+trait Foo {
+    type Assoc;
+}
+
+impl Foo for [u16; usize::MAX] {
+    type Assoc = u32;
+}
+
+fn main() {
+    let _a: Option<<[u16; usize::MAX] as Foo>::Assoc> = None;
+}
diff --git a/src/test/ui/lint/expansion-time.rs b/src/test/ui/lint/expansion-time.rs
index c98ecc980dd3d..a9c7ac363b0b3 100644
--- a/src/test/ui/lint/expansion-time.rs
+++ b/src/test/ui/lint/expansion-time.rs
@@ -12,6 +12,16 @@ mod benches {
     fn foo() {}
 }
 
+#[deprecated = "reason"]
+macro_rules! deprecated {
+    () => {}
+}
+
+#[allow(deprecated)]
+mod deprecated {
+    deprecated!(); // No warning
+}
+
 #[warn(incomplete_include)]
 fn main() {
     // WARN see in the stderr file, the warning points to the included file.
diff --git a/src/test/ui/lint/expansion-time.stderr b/src/test/ui/lint/expansion-time.stderr
index bc48d64e7e6b7..24e2733064e48 100644
--- a/src/test/ui/lint/expansion-time.stderr
+++ b/src/test/ui/lint/expansion-time.stderr
@@ -33,7 +33,7 @@ LL | 2
    | ^
    |
 note: the lint level is defined here
-  --> $DIR/expansion-time.rs:15:8
+  --> $DIR/expansion-time.rs:25:8
    |
 LL | #[warn(incomplete_include)]
    |        ^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/lint/issue-69485-var-size-diffs-too-large.rs b/src/test/ui/lint/issue-69485-var-size-diffs-too-large.rs
index 0895f4c18e387..2560ffe168be5 100644
--- a/src/test/ui/lint/issue-69485-var-size-diffs-too-large.rs
+++ b/src/test/ui/lint/issue-69485-var-size-diffs-too-large.rs
@@ -3,7 +3,7 @@
 // compile-flags: -Zmir-opt-level=0
 
 fn main() {
-    Bug::V([0; !0]); //~ ERROR is too big for the current
+    Bug::V([0; !0]); //~ ERROR are too big for the current
 }
 
 enum Bug {
diff --git a/src/test/ui/lint/issue-69485-var-size-diffs-too-large.stderr b/src/test/ui/lint/issue-69485-var-size-diffs-too-large.stderr
index 51eac95afb9ce..c229458da47da 100644
--- a/src/test/ui/lint/issue-69485-var-size-diffs-too-large.stderr
+++ b/src/test/ui/lint/issue-69485-var-size-diffs-too-large.stderr
@@ -1,4 +1,4 @@
-error: the type `[u8; 18446744073709551615]` is too big for the current architecture
+error: values of the type `[u8; 18446744073709551615]` are too big for the current architecture
   --> $DIR/issue-69485-var-size-diffs-too-large.rs:6:12
    |
 LL |     Bug::V([0; !0]);
diff --git a/src/tools/clippy/clippy_lints/src/assertions_on_constants.rs b/src/tools/clippy/clippy_lints/src/assertions_on_constants.rs
index 982d5ecf8d02f..a2ccb0369c4a4 100644
--- a/src/tools/clippy/clippy_lints/src/assertions_on_constants.rs
+++ b/src/tools/clippy/clippy_lints/src/assertions_on_constants.rs
@@ -1,6 +1,5 @@
 use crate::consts::{constant, Constant};
-use crate::utils::paths;
-use crate::utils::{is_direct_expn_of, is_expn_of, match_function_call, snippet_opt, span_lint_and_help};
+use crate::utils::{is_direct_expn_of, is_expn_of, match_panic_call, snippet_opt, span_lint_and_help};
 use if_chain::if_chain;
 use rustc_ast::ast::LitKind;
 use rustc_hir::{Expr, ExprKind, PatKind, UnOp};
@@ -133,7 +132,7 @@ fn match_assert_with_message<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>)
         if let ExprKind::Block(ref inner_block, _) = block_expr.kind;
         if let Some(begin_panic_call) = &inner_block.expr;
         // function call
-        if let Some(args) = match_function_call(cx, begin_panic_call, &paths::BEGIN_PANIC);
+        if let Some(args) = match_panic_call(cx, begin_panic_call);
         if args.len() == 1;
         // bind the second argument of the `assert!` macro if it exists
         if let panic_message = snippet_opt(cx, args[0].span);
diff --git a/src/tools/clippy/clippy_lints/src/attrs.rs b/src/tools/clippy/clippy_lints/src/attrs.rs
index 55904a0ec0a84..57702dafa6a0c 100644
--- a/src/tools/clippy/clippy_lints/src/attrs.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs.rs
@@ -1,7 +1,7 @@
 //! checks for attributes
 
 use crate::utils::{
-    first_line_of_span, is_present_in_source, match_def_path, paths, snippet_opt, span_lint, span_lint_and_help,
+    first_line_of_span, is_present_in_source, match_panic_def_id, snippet_opt, span_lint, span_lint_and_help,
     span_lint_and_sugg, span_lint_and_then, without_block_comments,
 };
 use if_chain::if_chain;
@@ -513,7 +513,7 @@ fn is_relevant_expr(cx: &LateContext<'_>, typeck_results: &ty::TypeckResults<'_>
                 typeck_results
                     .qpath_res(qpath, path_expr.hir_id)
                     .opt_def_id()
-                    .map_or(true, |fun_id| !match_def_path(cx, fun_id, &paths::BEGIN_PANIC))
+                    .map_or(true, |fun_id| !match_panic_def_id(cx, fun_id))
             } else {
                 true
             }
diff --git a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs
index fe817fe94f2e4..509a4a4e15f62 100644
--- a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs
+++ b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs
@@ -1,5 +1,7 @@
-use crate::utils::paths::{BEGIN_PANIC, BEGIN_PANIC_FMT, FROM_TRAIT};
-use crate::utils::{is_expn_of, is_type_diagnostic_item, match_def_path, method_chain_args, span_lint_and_then};
+use crate::utils::paths::FROM_TRAIT;
+use crate::utils::{
+    is_expn_of, is_type_diagnostic_item, match_def_path, match_panic_def_id, method_chain_args, span_lint_and_then,
+};
 use if_chain::if_chain;
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LateLintPass};
@@ -84,8 +86,7 @@ fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, impl_items: &[h
                 if let ExprKind::Call(ref func_expr, _) = expr.kind;
                 if let ExprKind::Path(QPath::Resolved(_, ref path)) = func_expr.kind;
                 if let Some(path_def_id) = path.res.opt_def_id();
-                if match_def_path(self.lcx, path_def_id, &BEGIN_PANIC) ||
-                    match_def_path(self.lcx, path_def_id, &BEGIN_PANIC_FMT);
+                if match_panic_def_id(self.lcx, path_def_id);
                 if is_expn_of(expr.span, "unreachable").is_none();
                 then {
                     self.result.push(expr.span);
diff --git a/src/tools/clippy/clippy_lints/src/implicit_return.rs b/src/tools/clippy/clippy_lints/src/implicit_return.rs
index 22c4fef32a32b..ed7f3b9293dbf 100644
--- a/src/tools/clippy/clippy_lints/src/implicit_return.rs
+++ b/src/tools/clippy/clippy_lints/src/implicit_return.rs
@@ -1,8 +1,4 @@
-use crate::utils::{
-    fn_has_unsatisfiable_preds, match_def_path,
-    paths::{BEGIN_PANIC, BEGIN_PANIC_FMT},
-    snippet_opt, span_lint_and_then,
-};
+use crate::utils::{fn_has_unsatisfiable_preds, match_panic_def_id, snippet_opt, span_lint_and_then};
 use if_chain::if_chain;
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::FnKind;
@@ -109,8 +105,7 @@ fn expr_match(cx: &LateContext<'_>, expr: &Expr<'_>) {
             if_chain! {
                 if let ExprKind::Path(qpath) = &expr.kind;
                 if let Some(path_def_id) = cx.qpath_res(qpath, expr.hir_id).opt_def_id();
-                if match_def_path(cx, path_def_id, &BEGIN_PANIC) ||
-                    match_def_path(cx, path_def_id, &BEGIN_PANIC_FMT);
+                if match_panic_def_id(cx, path_def_id);
                 then { }
                 else {
                     lint(cx, expr.span, expr.span, LINT_RETURN)
diff --git a/src/tools/clippy/clippy_lints/src/panic_unimplemented.rs b/src/tools/clippy/clippy_lints/src/panic_unimplemented.rs
index 6379dffd22e37..3d888fe732573 100644
--- a/src/tools/clippy/clippy_lints/src/panic_unimplemented.rs
+++ b/src/tools/clippy/clippy_lints/src/panic_unimplemented.rs
@@ -1,4 +1,4 @@
-use crate::utils::{is_direct_expn_of, is_expn_of, match_function_call, paths, span_lint};
+use crate::utils::{is_direct_expn_of, is_expn_of, match_panic_call, span_lint};
 use if_chain::if_chain;
 use rustc_ast::ast::LitKind;
 use rustc_hir::{Expr, ExprKind};
@@ -93,27 +93,27 @@ declare_lint_pass!(PanicUnimplemented => [PANIC_PARAMS, UNIMPLEMENTED, UNREACHAB
 
 impl<'tcx> LateLintPass<'tcx> for PanicUnimplemented {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        if_chain! {
-            if let ExprKind::Block(ref block, _) = expr.kind;
-            if let Some(ref ex) = block.expr;
-            if let Some(params) = match_function_call(cx, ex, &paths::BEGIN_PANIC)
-                .or_else(|| match_function_call(cx, ex, &paths::BEGIN_PANIC_FMT));
-            then {
-                let span = get_outer_span(expr);
-                if is_expn_of(expr.span, "unimplemented").is_some() {
-                    span_lint(cx, UNIMPLEMENTED, span,
-                              "`unimplemented` should not be present in production code");
-                } else if is_expn_of(expr.span, "todo").is_some() {
-                    span_lint(cx, TODO, span,
-                              "`todo` should not be present in production code");
-                } else if is_expn_of(expr.span, "unreachable").is_some() {
-                    span_lint(cx, UNREACHABLE, span,
-                              "`unreachable` should not be present in production code");
-                } else if is_expn_of(expr.span, "panic").is_some() {
-                    span_lint(cx, PANIC, span,
-                              "`panic` should not be present in production code");
-                    match_panic(params, expr, cx);
-                }
+        if let Some(params) = match_panic_call(cx, expr) {
+            let span = get_outer_span(expr);
+            if is_expn_of(expr.span, "unimplemented").is_some() {
+                span_lint(
+                    cx,
+                    UNIMPLEMENTED,
+                    span,
+                    "`unimplemented` should not be present in production code",
+                );
+            } else if is_expn_of(expr.span, "todo").is_some() {
+                span_lint(cx, TODO, span, "`todo` should not be present in production code");
+            } else if is_expn_of(expr.span, "unreachable").is_some() {
+                span_lint(
+                    cx,
+                    UNREACHABLE,
+                    span,
+                    "`unreachable` should not be present in production code",
+                );
+            } else if is_expn_of(expr.span, "panic").is_some() {
+                span_lint(cx, PANIC, span, "`panic` should not be present in production code");
+                match_panic(params, expr, cx);
             }
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/utils/mod.rs b/src/tools/clippy/clippy_lints/src/utils/mod.rs
index b027bfebacb6a..270fdc9bf462f 100644
--- a/src/tools/clippy/clippy_lints/src/utils/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/mod.rs
@@ -1196,7 +1196,7 @@ pub fn has_iter_method(cx: &LateContext<'_>, probably_ref_ty: Ty<'_>) -> Option<
 /// Usage:
 ///
 /// ```rust,ignore
-/// if let Some(args) = match_function_call(cx, begin_panic_call, &paths::BEGIN_PANIC);
+/// if let Some(args) = match_function_call(cx, cmp_max_call, &paths::CMP_MAX);
 /// ```
 pub fn match_function_call<'tcx>(
     cx: &LateContext<'tcx>,
@@ -1231,6 +1231,24 @@ pub fn match_def_path<'tcx>(cx: &LateContext<'tcx>, did: DefId, syms: &[&str]) -
     cx.match_def_path(did, &syms)
 }
 
+pub fn match_panic_call<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<&'tcx [Expr<'tcx>]> {
+    match_function_call(cx, expr, &paths::BEGIN_PANIC)
+        .or_else(|| match_function_call(cx, expr, &paths::BEGIN_PANIC_FMT))
+        .or_else(|| match_function_call(cx, expr, &paths::PANIC_ANY))
+        .or_else(|| match_function_call(cx, expr, &paths::PANICKING_PANIC))
+        .or_else(|| match_function_call(cx, expr, &paths::PANICKING_PANIC_FMT))
+        .or_else(|| match_function_call(cx, expr, &paths::PANICKING_PANIC_STR))
+}
+
+pub fn match_panic_def_id(cx: &LateContext<'_>, did: DefId) -> bool {
+    match_def_path(cx, did, &paths::BEGIN_PANIC)
+        || match_def_path(cx, did, &paths::BEGIN_PANIC_FMT)
+        || match_def_path(cx, did, &paths::PANIC_ANY)
+        || match_def_path(cx, did, &paths::PANICKING_PANIC)
+        || match_def_path(cx, did, &paths::PANICKING_PANIC_FMT)
+        || match_def_path(cx, did, &paths::PANICKING_PANIC_STR)
+}
+
 /// Returns the list of condition expressions and the list of blocks in a
 /// sequence of `if/else`.
 /// E.g., this returns `([a, b], [c, d, e])` for the expression
diff --git a/src/tools/clippy/clippy_lints/src/utils/paths.rs b/src/tools/clippy/clippy_lints/src/utils/paths.rs
index 1ad8c6029860b..8f5fbfd9f846a 100644
--- a/src/tools/clippy/clippy_lints/src/utils/paths.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/paths.rs
@@ -8,8 +8,8 @@ pub const ANY_TRAIT: [&str; 3] = ["std", "any", "Any"];
 pub const ARC_PTR_EQ: [&str; 4] = ["alloc", "sync", "Arc", "ptr_eq"];
 pub const ASMUT_TRAIT: [&str; 3] = ["core", "convert", "AsMut"];
 pub const ASREF_TRAIT: [&str; 3] = ["core", "convert", "AsRef"];
-pub const BEGIN_PANIC: [&str; 3] = ["std", "panicking", "begin_panic"];
-pub const BEGIN_PANIC_FMT: [&str; 3] = ["std", "panicking", "begin_panic_fmt"];
+pub(super) const BEGIN_PANIC: [&str; 3] = ["std", "panicking", "begin_panic"];
+pub(super) const BEGIN_PANIC_FMT: [&str; 3] = ["std", "panicking", "begin_panic_fmt"];
 pub const BINARY_HEAP: [&str; 4] = ["alloc", "collections", "binary_heap", "BinaryHeap"];
 pub const BORROW_TRAIT: [&str; 3] = ["core", "borrow", "Borrow"];
 pub const BOX: [&str; 3] = ["alloc", "boxed", "Box"];
@@ -78,6 +78,10 @@ pub const ORD: [&str; 3] = ["core", "cmp", "Ord"];
 pub const OS_STRING: [&str; 4] = ["std", "ffi", "os_str", "OsString"];
 pub const OS_STRING_AS_OS_STR: [&str; 5] = ["std", "ffi", "os_str", "OsString", "as_os_str"];
 pub const OS_STR_TO_OS_STRING: [&str; 5] = ["std", "ffi", "os_str", "OsStr", "to_os_string"];
+pub(super) const PANICKING_PANIC: [&str; 3] = ["core", "panicking", "panic"];
+pub(super) const PANICKING_PANIC_FMT: [&str; 3] = ["core", "panicking", "panic_fmt"];
+pub(super) const PANICKING_PANIC_STR: [&str; 3] = ["core", "panicking", "panic_str"];
+pub(super) const PANIC_ANY: [&str; 3] = ["std", "panic", "panic_any"];
 pub const PARKING_LOT_MUTEX_GUARD: [&str; 2] = ["parking_lot", "MutexGuard"];
 pub const PARKING_LOT_RWLOCK_READ_GUARD: [&str; 2] = ["parking_lot", "RwLockReadGuard"];
 pub const PARKING_LOT_RWLOCK_WRITE_GUARD: [&str; 2] = ["parking_lot", "RwLockWriteGuard"];
diff --git a/src/tools/clippy/tests/ui/panicking_macros.rs b/src/tools/clippy/tests/ui/panicking_macros.rs
index f91ccfaed743d..77fcb8dfd02fd 100644
--- a/src/tools/clippy/tests/ui/panicking_macros.rs
+++ b/src/tools/clippy/tests/ui/panicking_macros.rs
@@ -1,6 +1,8 @@
 #![warn(clippy::unimplemented, clippy::unreachable, clippy::todo, clippy::panic)]
 #![allow(clippy::assertions_on_constants)]
 
+extern crate core;
+
 fn panic() {
     let a = 2;
     panic!();
@@ -33,9 +35,18 @@ fn unreachable() {
     let b = a + 2;
 }
 
+fn core_versions() {
+    use core::{panic, todo, unimplemented, unreachable};
+    panic!();
+    todo!();
+    unimplemented!();
+    unreachable!();
+}
+
 fn main() {
     panic();
     todo();
     unimplemented();
     unreachable();
+    core_versions();
 }
diff --git a/src/tools/clippy/tests/ui/panicking_macros.stderr b/src/tools/clippy/tests/ui/panicking_macros.stderr
index 37c11d72a574a..83234c0ed92cc 100644
--- a/src/tools/clippy/tests/ui/panicking_macros.stderr
+++ b/src/tools/clippy/tests/ui/panicking_macros.stderr
@@ -1,5 +1,5 @@
 error: `panic` should not be present in production code
-  --> $DIR/panicking_macros.rs:6:5
+  --> $DIR/panicking_macros.rs:8:5
    |
 LL |     panic!();
    |     ^^^^^^^^^
@@ -7,7 +7,7 @@ LL |     panic!();
    = note: `-D clippy::panic` implied by `-D warnings`
 
 error: `panic` should not be present in production code
-  --> $DIR/panicking_macros.rs:7:5
+  --> $DIR/panicking_macros.rs:9:5
    |
 LL |     panic!("message");
    |     ^^^^^^^^^^^^^^^^^^
@@ -15,7 +15,7 @@ LL |     panic!("message");
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: `panic` should not be present in production code
-  --> $DIR/panicking_macros.rs:8:5
+  --> $DIR/panicking_macros.rs:10:5
    |
 LL |     panic!("{} {}", "panic with", "multiple arguments");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -23,7 +23,7 @@ LL |     panic!("{} {}", "panic with", "multiple arguments");
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: `todo` should not be present in production code
-  --> $DIR/panicking_macros.rs:14:5
+  --> $DIR/panicking_macros.rs:16:5
    |
 LL |     todo!();
    |     ^^^^^^^^
@@ -31,19 +31,19 @@ LL |     todo!();
    = note: `-D clippy::todo` implied by `-D warnings`
 
 error: `todo` should not be present in production code
-  --> $DIR/panicking_macros.rs:15:5
+  --> $DIR/panicking_macros.rs:17:5
    |
 LL |     todo!("message");
    |     ^^^^^^^^^^^^^^^^^
 
 error: `todo` should not be present in production code
-  --> $DIR/panicking_macros.rs:16:5
+  --> $DIR/panicking_macros.rs:18:5
    |
 LL |     todo!("{} {}", "panic with", "multiple arguments");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `unimplemented` should not be present in production code
-  --> $DIR/panicking_macros.rs:22:5
+  --> $DIR/panicking_macros.rs:24:5
    |
 LL |     unimplemented!();
    |     ^^^^^^^^^^^^^^^^^
@@ -51,19 +51,19 @@ LL |     unimplemented!();
    = note: `-D clippy::unimplemented` implied by `-D warnings`
 
 error: `unimplemented` should not be present in production code
-  --> $DIR/panicking_macros.rs:23:5
+  --> $DIR/panicking_macros.rs:25:5
    |
 LL |     unimplemented!("message");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `unimplemented` should not be present in production code
-  --> $DIR/panicking_macros.rs:24:5
+  --> $DIR/panicking_macros.rs:26:5
    |
 LL |     unimplemented!("{} {}", "panic with", "multiple arguments");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `unreachable` should not be present in production code
-  --> $DIR/panicking_macros.rs:30:5
+  --> $DIR/panicking_macros.rs:32:5
    |
 LL |     unreachable!();
    |     ^^^^^^^^^^^^^^^
@@ -71,7 +71,7 @@ LL |     unreachable!();
    = note: `-D clippy::unreachable` implied by `-D warnings`
 
 error: `unreachable` should not be present in production code
-  --> $DIR/panicking_macros.rs:31:5
+  --> $DIR/panicking_macros.rs:33:5
    |
 LL |     unreachable!("message");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -79,10 +79,34 @@ LL |     unreachable!("message");
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: `unreachable` should not be present in production code
-  --> $DIR/panicking_macros.rs:32:5
+  --> $DIR/panicking_macros.rs:34:5
    |
 LL |     unreachable!("{} {}", "panic with", "multiple arguments");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 12 previous errors
+error: `panic` should not be present in production code
+  --> $DIR/panicking_macros.rs:40:5
+   |
+LL |     panic!();
+   |     ^^^^^^^^^
+
+error: `todo` should not be present in production code
+  --> $DIR/panicking_macros.rs:41:5
+   |
+LL |     todo!();
+   |     ^^^^^^^^
+
+error: `unimplemented` should not be present in production code
+  --> $DIR/panicking_macros.rs:42:5
+   |
+LL |     unimplemented!();
+   |     ^^^^^^^^^^^^^^^^^
+
+error: `unreachable` should not be present in production code
+  --> $DIR/panicking_macros.rs:43:5
+   |
+LL |     unreachable!();
+   |     ^^^^^^^^^^^^^^^
+
+error: aborting due to 16 previous errors