about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock2
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs13
-rw-r--r--compiler/rustc_borrowck/src/facts.rs15
-rw-r--r--compiler/rustc_borrowck/src/place_ext.rs14
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types.rs12
-rw-r--r--compiler/rustc_borrowck/src/universal_regions.rs24
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs37
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs24
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs14
-rw-r--r--compiler/rustc_infer/src/infer/canonical/instantiate.rs26
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs15
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs7
-rw-r--r--compiler/rustc_infer/src/traits/engine.rs15
-rw-r--r--compiler/rustc_macros/src/extension.rs154
-rw-r--r--compiler/rustc_macros/src/lib.rs6
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs24
-rw-r--r--compiler/rustc_middle/src/ty/util.rs9
-rw-r--r--compiler/rustc_mir_transform/src/const_prop_lint.rs5
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs13
-rw-r--r--compiler/rustc_trait_selection/src/infer.rs82
-rw-r--r--compiler/rustc_trait_selection/src/regions.rs10
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs14
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs10
-rw-r--r--compiler/rustc_trait_selection/src/solve/inspect/analyse.rs11
-rw-r--r--compiler/rustc_trait_selection/src/solve/mod.rs7
-rw-r--r--compiler/rustc_trait_selection/src/traits/engine.rs7
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs37
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs21
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs276
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs286
-rw-r--r--compiler/rustc_trait_selection/src/traits/outlives_bounds.rs25
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs33
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs34
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/normalize.rs22
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs34
-rw-r--r--compiler/rustc_trait_selection/src/traits/structural_normalize.rs11
-rwxr-xr-xconfigure4
-rw-r--r--library/core/src/intrinsics.rs102
-rw-r--r--library/core/src/slice/mod.rs27
-rw-r--r--library/std/src/sys/pal/windows/os.rs30
-rw-r--r--src/tools/miri/CONTRIBUTING.md11
-rw-r--r--src/tools/miri/Cargo.lock56
-rw-r--r--src/tools/miri/Cargo.toml2
-rw-r--r--src/tools/miri/README.md7
-rwxr-xr-xsrc/tools/miri/ci/ci.sh5
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/bin/miri.rs12
-rw-r--r--src/tools/miri/src/borrow_tracker/mod.rs1
-rw-r--r--src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs2
-rw-r--r--src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs2
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs2
-rw-r--r--src/tools/miri/src/concurrency/data_race.rs20
-rw-r--r--src/tools/miri/src/concurrency/sync.rs19
-rw-r--r--src/tools/miri/src/concurrency/thread.rs1
-rw-r--r--src/tools/miri/src/diagnostics.rs17
-rw-r--r--src/tools/miri/src/eval.rs5
-rw-r--r--src/tools/miri/src/helpers.rs2
-rw-r--r--src/tools/miri/src/intptrcast.rs1
-rw-r--r--src/tools/miri/src/lib.rs2
-rw-r--r--src/tools/miri/src/operator.rs2
-rw-r--r--src/tools/miri/src/shims/foreign_items.rs2
-rw-r--r--src/tools/miri/src/shims/intrinsics/mod.rs2
-rw-r--r--src/tools/miri/src/shims/panic.rs2
-rw-r--r--src/tools/miri/src/shims/tls.rs2
-rw-r--r--src/tools/miri/src/shims/unix/foreign_items.rs22
-rw-r--r--src/tools/miri/src/shims/unix/fs.rs2
-rw-r--r--src/tools/miri/src/shims/unix/linux/foreign_items.rs20
-rw-r--r--src/tools/miri/src/shims/unix/mem.rs3
-rw-r--r--src/tools/miri/src/shims/x86/avx.rs417
-rw-r--r--src/tools/miri/src/shims/x86/mod.rs223
-rw-r--r--src/tools/miri/src/shims/x86/sse.rs5
-rw-r--r--src/tools/miri/src/shims/x86/sse2.rs10
-rw-r--r--src/tools/miri/src/shims/x86/sse41.rs5
-rw-r--r--src/tools/miri/tests/fail/enum-set-discriminant-niche-variant-wrong.rs6
-rw-r--r--src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.rs3
-rw-r--r--src/tools/miri/tests/pass-dep/concurrency/libc_pthread_cond.rs2
-rw-r--r--src/tools/miri/tests/pass-dep/concurrency/libc_pthread_cond_isolated.rs2
-rw-r--r--src/tools/miri/tests/pass-dep/shims/mmap.rs39
-rw-r--r--src/tools/miri/tests/pass-dep/shims/pthread-sync.rs134
-rw-r--r--src/tools/miri/tests/pass/align_offset_symbolic.rs2
-rw-r--r--src/tools/miri/tests/pass/concurrency/sync.rs27
-rw-r--r--src/tools/miri/tests/pass/imported_main.rs8
-rw-r--r--src/tools/miri/tests/pass/imported_main.stdout1
-rw-r--r--src/tools/miri/tests/pass/intrinsics-x86-avx.rs1269
-rw-r--r--src/tools/miri/tests/pass/overflow_checks_off.rs7
-rw-r--r--tests/coverage/closure_unit_return.cov-map34
-rw-r--r--tests/coverage/closure_unit_return.coverage30
-rw-r--r--tests/coverage/closure_unit_return.rs29
-rw-r--r--tests/coverage/coverage_attr_closure.cov-map8
-rw-r--r--tests/coverage/coverage_attr_closure.coverage8
-rw-r--r--tests/coverage/inline-dead.cov-map6
-rw-r--r--tests/coverage/macro_name_span.cov-map4
-rw-r--r--tests/coverage/macro_name_span.coverage2
-rw-r--r--tests/coverage/unicode.cov-map8
-rw-r--r--tests/coverage/unicode.coverage3
-rw-r--r--tests/ui/associated-consts/defaults-cyclic-fail.stderr2
-rw-r--r--tests/ui/associated-consts/defaults-not-assumed-fail.stderr8
-rw-r--r--tests/ui/consts/const-err2.noopt.stderr48
-rw-r--r--tests/ui/consts/const-err2.opt.stderr48
-rw-r--r--tests/ui/consts/const-err2.opt_with_overflow_checks.stderr48
-rw-r--r--tests/ui/consts/const-err2.rs39
-rw-r--r--tests/ui/consts/const-eval/issue-44578.stderr8
-rw-r--r--tests/ui/consts/const-eval/issue-50814.rs1
-rw-r--r--tests/ui/consts/const-eval/issue-50814.stderr22
-rw-r--r--tests/ui/consts/const-ref-to-static-linux-vtable.rs43
-rw-r--r--tests/ui/consts/issue-17718-const-bad-values.rs1
-rw-r--r--tests/ui/consts/issue-17718-const-bad-values.stderr12
-rw-r--r--tests/ui/consts/miri_unleashed/box.stderr2
-rw-r--r--tests/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr2
-rw-r--r--tests/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr2
-rw-r--r--tests/ui/consts/mut-ptr-to-static.rs40
-rw-r--r--tests/ui/consts/overflowing-consts.noopt.stderr1023
-rw-r--r--tests/ui/consts/overflowing-consts.opt.stderr1023
-rw-r--r--tests/ui/consts/overflowing-consts.opt_with_overflow_checks.stderr1023
-rw-r--r--tests/ui/consts/overflowing-consts.rs288
-rw-r--r--tests/ui/consts/promotion.rs3
-rw-r--r--tests/ui/error-codes/E0017.rs8
-rw-r--r--tests/ui/error-codes/E0017.stderr36
-rw-r--r--tests/ui/error-codes/E0388.rs4
-rw-r--r--tests/ui/error-codes/E0388.stderr24
-rw-r--r--tests/ui/intrinsics/safe-intrinsic-mismatch.rs8
-rw-r--r--tests/ui/intrinsics/safe-intrinsic-mismatch.stderr21
-rw-r--r--tests/ui/lint/issue-117949.noopt.stderr54
-rw-r--r--tests/ui/lint/issue-117949.opt.stderr54
-rw-r--r--tests/ui/lint/issue-117949.opt_with_overflow_checks.stderr54
-rw-r--r--tests/ui/lint/issue-117949.rs20
-rw-r--r--tests/ui/lint/lint-exceeding-bitshifts.noopt.stderr152
-rw-r--r--tests/ui/lint/lint-exceeding-bitshifts.opt.stderr152
-rw-r--r--tests/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr152
-rw-r--r--tests/ui/lint/lint-exceeding-bitshifts.rs79
-rw-r--r--tests/ui/lint/lint-overflowing-ops.noopt.stderr1030
-rw-r--r--tests/ui/lint/lint-overflowing-ops.opt.stderr1030
-rw-r--r--tests/ui/lint/lint-overflowing-ops.opt_with_overflow_checks.stderr1030
-rw-r--r--tests/ui/lint/lint-overflowing-ops.rs294
-rw-r--r--tests/ui/numbers-arithmetic/promoted_overflow_opt.rs8
-rw-r--r--tests/ui/reify-intrinsic.rs5
-rw-r--r--tests/ui/reify-intrinsic.stderr11
-rw-r--r--triagebot.toml9
139 files changed, 9803 insertions, 2154 deletions
diff --git a/Cargo.lock b/Cargo.lock
index a30ab648c3f..7c6c10cdbd7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2524,14 +2524,12 @@ dependencies = [
  "aes",
  "colored",
  "ctrlc",
- "env_logger 0.10.2",
  "getrandom",
  "jemalloc-sys",
  "lazy_static",
  "libc",
  "libffi",
  "libloading",
- "log",
  "measureme",
  "rand",
  "regex",
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index e9e1095a4ae..a5be91bb872 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -57,6 +57,7 @@ use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
 use rustc_hir::def_id::{LocalDefId, LocalDefIdMap, CRATE_DEF_ID, LOCAL_CRATE};
 use rustc_hir::{ConstArg, GenericArg, ItemLocalMap, ParamName, TraitCandidate};
 use rustc_index::{Idx, IndexSlice, IndexVec};
+use rustc_macros::extension;
 use rustc_middle::span_bug;
 use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
 use rustc_session::parse::{add_feature_diagnostics, feature_err};
@@ -190,16 +191,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     }
 }
 
-trait ResolverAstLoweringExt {
-    fn legacy_const_generic_args(&self, expr: &Expr) -> Option<Vec<usize>>;
-    fn get_partial_res(&self, id: NodeId) -> Option<PartialRes>;
-    fn get_import_res(&self, id: NodeId) -> PerNS<Option<Res<NodeId>>>;
-    fn get_label_res(&self, id: NodeId) -> Option<NodeId>;
-    fn get_lifetime_res(&self, id: NodeId) -> Option<LifetimeRes>;
-    fn take_extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)>;
-}
-
-impl ResolverAstLoweringExt for ResolverAstLowering {
+#[extension(trait ResolverAstLoweringExt)]
+impl ResolverAstLowering {
     fn legacy_const_generic_args(&self, expr: &Expr) -> Option<Vec<usize>> {
         if let ExprKind::Path(None, path) = &expr.kind {
             // Don't perform legacy const generics rewriting if the path already
diff --git a/compiler/rustc_borrowck/src/facts.rs b/compiler/rustc_borrowck/src/facts.rs
index 68dc9a6764b..e7faec7bbac 100644
--- a/compiler/rustc_borrowck/src/facts.rs
+++ b/compiler/rustc_borrowck/src/facts.rs
@@ -2,6 +2,7 @@ use crate::location::{LocationIndex, LocationTable};
 use crate::BorrowIndex;
 use polonius_engine::AllFacts as PoloniusFacts;
 use polonius_engine::Atom;
+use rustc_macros::extension;
 use rustc_middle::mir::Local;
 use rustc_middle::ty::{RegionVid, TyCtxt};
 use rustc_mir_dataflow::move_paths::MovePathIndex;
@@ -24,20 +25,10 @@ impl polonius_engine::FactTypes for RustcFacts {
 
 pub type AllFacts = PoloniusFacts<RustcFacts>;
 
-pub(crate) trait AllFactsExt {
+#[extension(pub(crate) trait AllFactsExt)]
+impl AllFacts {
     /// Returns `true` if there is a need to gather `AllFacts` given the
     /// current `-Z` flags.
-    fn enabled(tcx: TyCtxt<'_>) -> bool;
-
-    fn write_to_dir(
-        &self,
-        dir: impl AsRef<Path>,
-        location_table: &LocationTable,
-    ) -> Result<(), Box<dyn Error>>;
-}
-
-impl AllFactsExt for AllFacts {
-    /// Return
     fn enabled(tcx: TyCtxt<'_>) -> bool {
         tcx.sess.opts.unstable_opts.nll_facts
             || tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled()
diff --git a/compiler/rustc_borrowck/src/place_ext.rs b/compiler/rustc_borrowck/src/place_ext.rs
index b59ab7fafa5..0f806df9da1 100644
--- a/compiler/rustc_borrowck/src/place_ext.rs
+++ b/compiler/rustc_borrowck/src/place_ext.rs
@@ -1,11 +1,12 @@
 use crate::borrow_set::LocalsStateAtExit;
 use rustc_hir as hir;
+use rustc_macros::extension;
 use rustc_middle::mir::ProjectionElem;
 use rustc_middle::mir::{Body, Mutability, Place};
 use rustc_middle::ty::{self, TyCtxt};
 
-/// Extension methods for the `Place` type.
-pub trait PlaceExt<'tcx> {
+#[extension(pub trait PlaceExt<'tcx>)]
+impl<'tcx> Place<'tcx> {
     /// Returns `true` if we can safely ignore borrows of this place.
     /// This is true whenever there is no action that the user can do
     /// to the place `self` that would invalidate the borrow. This is true
@@ -15,15 +16,6 @@ pub trait PlaceExt<'tcx> {
         tcx: TyCtxt<'tcx>,
         body: &Body<'tcx>,
         locals_state_at_exit: &LocalsStateAtExit,
-    ) -> bool;
-}
-
-impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
-    fn ignore_borrow(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        body: &Body<'tcx>,
-        locals_state_at_exit: &LocalsStateAtExit,
     ) -> bool {
         // If a local variable is immutable, then we only need to track borrows to guard
         // against two kinds of errors:
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index cd2fe56ca49..a5a906658b8 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -6,6 +6,7 @@ use rustc_hir::OpaqueTyOrigin;
 use rustc_infer::infer::InferCtxt;
 use rustc_infer::infer::TyCtxtInferExt as _;
 use rustc_infer::traits::{Obligation, ObligationCause};
+use rustc_macros::extension;
 use rustc_middle::traits::DefiningAnchor;
 use rustc_middle::ty::visit::TypeVisitableExt;
 use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable};
@@ -225,15 +226,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     }
 }
 
-pub trait InferCtxtExt<'tcx> {
-    fn infer_opaque_definition_from_instantiation(
-        &self,
-        opaque_type_key: OpaqueTypeKey<'tcx>,
-        instantiated_ty: OpaqueHiddenType<'tcx>,
-    ) -> Ty<'tcx>;
-}
-
-impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
+#[extension(pub trait InferCtxtExt<'tcx>)]
+impl<'tcx> InferCtxt<'tcx> {
     /// Given the fully resolved, instantiated type for an opaque
     /// type, i.e., the value of an inference variable like C1 or C2
     /// (*), computes the "definition type" for an opaque type
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs
index 90e8f1b93b2..a69f5335f71 100644
--- a/compiler/rustc_borrowck/src/universal_regions.rs
+++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -22,6 +22,7 @@ use rustc_hir::lang_items::LangItem;
 use rustc_hir::BodyOwnerKind;
 use rustc_index::IndexVec;
 use rustc_infer::infer::NllRegionVariableOrigin;
+use rustc_macros::extension;
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{self, InlineConstArgs, InlineConstArgsParts, RegionVid, Ty, TyCtxt};
@@ -793,27 +794,8 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
     }
 }
 
-trait InferCtxtExt<'tcx> {
-    fn replace_free_regions_with_nll_infer_vars<T>(
-        &self,
-        origin: NllRegionVariableOrigin,
-        value: T,
-    ) -> T
-    where
-        T: TypeFoldable<TyCtxt<'tcx>>;
-
-    fn replace_bound_regions_with_nll_infer_vars<T>(
-        &self,
-        origin: NllRegionVariableOrigin,
-        all_outlive_scope: LocalDefId,
-        value: ty::Binder<'tcx, T>,
-        indices: &mut UniversalRegionIndices<'tcx>,
-    ) -> T
-    where
-        T: TypeFoldable<TyCtxt<'tcx>>;
-}
-
-impl<'cx, 'tcx> InferCtxtExt<'tcx> for BorrowckInferCtxt<'cx, 'tcx> {
+#[extension(trait InferCtxtExt<'tcx>)]
+impl<'cx, 'tcx> BorrowckInferCtxt<'cx, 'tcx> {
     #[instrument(skip(self), level = "debug")]
     fn replace_free_regions_with_nll_infer_vars<T>(
         &self,
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index 96c9e740568..a3c4734f0a3 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -344,7 +344,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
         visitor.visit_ty(ty);
     }
 
-    fn check_mut_borrow(&mut self, local: Local, kind: hir::BorrowKind) {
+    fn check_mut_borrow(&mut self, place: &Place<'_>, kind: hir::BorrowKind) {
         match self.const_kind() {
             // In a const fn all borrows are transient or point to the places given via
             // references in the arguments (so we already checked them with
@@ -355,10 +355,19 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
             // to mutable memory.
             hir::ConstContext::ConstFn => self.check_op(ops::TransientMutBorrow(kind)),
             _ => {
+                // For indirect places, we are not creating a new permanent borrow, it's just as
+                // transient as the already existing one. For reborrowing references this is handled
+                // at the top of `visit_rvalue`, but for raw pointers we handle it here.
+                // Pointers/references to `static mut` and cases where the `*` is not the first
+                // projection also end up here.
                 // Locals with StorageDead do not live beyond the evaluation and can
                 // thus safely be borrowed without being able to be leaked to the final
                 // value of the constant.
-                if self.local_has_storage_dead(local) {
+                // Note: This is only sound if every local that has a `StorageDead` has a
+                // `StorageDead` in every control flow path leading to a `return` terminator.
+                // The good news is that interning will detect if any unexpected mutable
+                // pointer slips through.
+                if place.is_indirect() || self.local_has_storage_dead(place.local) {
                     self.check_op(ops::TransientMutBorrow(kind));
                 } else {
                     self.check_op(ops::MutBorrow(kind));
@@ -390,6 +399,11 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
         trace!("visit_rvalue: rvalue={:?} location={:?}", rvalue, location);
 
         // Special-case reborrows to be more like a copy of a reference.
+        // FIXME: this does not actually handle all reborrows. It only detects cases where `*` is the outermost
+        // projection of the borrowed place, it skips deref'ing raw pointers and it skips `static`.
+        // All those cases are handled below with shared/mutable borrows.
+        // Once `const_mut_refs` is stable, we should be able to entirely remove this special case.
+        // (`const_refs_to_cell` is not needed, we already allow all borrows of indirect places anyway.)
         match *rvalue {
             Rvalue::Ref(_, kind, place) => {
                 if let Some(reborrowed_place_ref) = place_as_reborrow(self.tcx, self.body, place) {
@@ -460,7 +474,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
 
                 if !is_allowed {
                     self.check_mut_borrow(
-                        place.local,
+                        place,
                         if matches!(rvalue, Rvalue::Ref(..)) {
                             hir::BorrowKind::Ref
                         } else {
@@ -478,7 +492,14 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                     place.as_ref(),
                 );
 
-                if borrowed_place_has_mut_interior {
+                // If the place is indirect, this is basically a reborrow. We have a reborrow
+                // special case above, but for raw pointers and pointers/references to `static` and
+                // when the `*` is not the first projection, `place_as_reborrow` does not recognize
+                // them as such, so we end up here. This should probably be considered a
+                // `TransientCellBorrow` (we consider the equivalent mutable case a
+                // `TransientMutBorrow`), but such reborrows got accidentally stabilized already and
+                // it is too much of a breaking change to take back.
+                if borrowed_place_has_mut_interior && !place.is_indirect() {
                     match self.const_kind() {
                         // In a const fn all borrows are transient or point to the places given via
                         // references in the arguments (so we already checked them with
@@ -495,6 +516,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                             // final value.
                             // Note: This is only sound if every local that has a `StorageDead` has a
                             // `StorageDead` in every control flow path leading to a `return` terminator.
+                            // The good news is that interning will detect if any unexpected mutable
+                            // pointer slips through.
                             if self.local_has_storage_dead(place.local) {
                                 self.check_op(ops::TransientCellBorrow);
                             } else {
@@ -948,6 +971,12 @@ fn place_as_reborrow<'tcx>(
 ) -> Option<PlaceRef<'tcx>> {
     match place.as_ref().last_projection() {
         Some((place_base, ProjectionElem::Deref)) => {
+            // FIXME: why do statics and raw pointers get excluded here? This makes
+            // some code involving mutable pointers unstable, but it is unclear
+            // why that code is treated differently from mutable references.
+            // Once TransientMutBorrow and TransientCellBorrow are stable,
+            // this can probably be cleaned up without any behavioral changes.
+
             // A borrow of a `static` also looks like `&(*_1)` in the MIR, but `_1` is a `const`
             // that points to the allocation for the static. Don't treat these as reborrows.
             if body.local_decls[place_base.local].is_ref_to_static() {
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
index 67fef208079..7eb3c181d69 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
@@ -74,6 +74,13 @@ pub trait Qualif {
         adt: AdtDef<'tcx>,
         args: GenericArgsRef<'tcx>,
     ) -> bool;
+
+    /// Returns `true` if this `Qualif` behaves sructurally for pointers and references:
+    /// the pointer/reference qualifies if and only if the pointee qualifies.
+    ///
+    /// (This is currently `false` for all our instances, but that may change in the future. Also,
+    /// by keeping it abstract, the handling of `Deref` in `in_place` becomes more clear.)
+    fn deref_structural<'tcx>(cx: &ConstCx<'_, 'tcx>) -> bool;
 }
 
 /// Constant containing interior mutability (`UnsafeCell<T>`).
@@ -103,6 +110,10 @@ impl Qualif for HasMutInterior {
         // It arises structurally for all other types.
         adt.is_unsafe_cell()
     }
+
+    fn deref_structural<'tcx>(_cx: &ConstCx<'_, 'tcx>) -> bool {
+        false
+    }
 }
 
 /// Constant containing an ADT that implements `Drop`.
@@ -131,6 +142,10 @@ impl Qualif for NeedsDrop {
     ) -> bool {
         adt.has_dtor(cx.tcx)
     }
+
+    fn deref_structural<'tcx>(_cx: &ConstCx<'_, 'tcx>) -> bool {
+        false
+    }
 }
 
 /// Constant containing an ADT that implements non-const `Drop`.
@@ -210,6 +225,10 @@ impl Qualif for NeedsNonConstDrop {
     ) -> bool {
         adt.has_non_const_dtor(cx.tcx)
     }
+
+    fn deref_structural<'tcx>(_cx: &ConstCx<'_, 'tcx>) -> bool {
+        false
+    }
 }
 
 // FIXME: Use `mir::visit::Visitor` for the `in_*` functions if/when it supports early return.
@@ -303,6 +322,11 @@ where
             return false;
         }
 
+        if matches!(elem, ProjectionElem::Deref) && !Q::deref_structural(cx) {
+            // We have to assume that this qualifies.
+            return true;
+        }
+
         place = place_base;
     }
 
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index f0f6bfff64a..903c98e8317 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -407,9 +407,9 @@ pub fn check_intrinsic_type(
             }
             sym::float_to_int_unchecked => (2, 0, vec![param(0)], param(1)),
 
-            sym::assume => (0, 0, vec![tcx.types.bool], Ty::new_unit(tcx)),
-            sym::likely => (0, 0, vec![tcx.types.bool], tcx.types.bool),
-            sym::unlikely => (0, 0, vec![tcx.types.bool], tcx.types.bool),
+            sym::assume => (0, 1, vec![tcx.types.bool], Ty::new_unit(tcx)),
+            sym::likely => (0, 1, vec![tcx.types.bool], tcx.types.bool),
+            sym::unlikely => (0, 1, vec![tcx.types.bool], tcx.types.bool),
 
             sym::read_via_copy => (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], param(0)),
             sym::write_via_move => {
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index 287cb880908..325a0ee9a18 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -14,6 +14,7 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{GenericArg, GenericParam, GenericParamKind, HirIdMap, LifetimeName, Node};
+use rustc_macros::extension;
 use rustc_middle::bug;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::middle::resolve_bound_vars::*;
@@ -27,17 +28,8 @@ use std::fmt;
 
 use crate::errors;
 
-trait RegionExt {
-    fn early(param: &GenericParam<'_>) -> (LocalDefId, ResolvedArg);
-
-    fn late(index: u32, param: &GenericParam<'_>) -> (LocalDefId, ResolvedArg);
-
-    fn id(&self) -> Option<DefId>;
-
-    fn shifted(self, amount: u32) -> ResolvedArg;
-}
-
-impl RegionExt for ResolvedArg {
+#[extension(trait RegionExt)]
+impl ResolvedArg {
     fn early(param: &GenericParam<'_>) -> (LocalDefId, ResolvedArg) {
         debug!("ResolvedArg::early: def_id={:?}", param.def_id);
         (param.def_id, ResolvedArg::EarlyBound(param.def_id.to_def_id()))
diff --git a/compiler/rustc_infer/src/infer/canonical/instantiate.rs b/compiler/rustc_infer/src/infer/canonical/instantiate.rs
index f6b583151fd..c8adbf7f57a 100644
--- a/compiler/rustc_infer/src/infer/canonical/instantiate.rs
+++ b/compiler/rustc_infer/src/infer/canonical/instantiate.rs
@@ -13,12 +13,16 @@ use rustc_middle::ty::{self, TyCtxt};
 
 /// FIXME(-Znext-solver): This or public because it is shared with the
 /// new trait solver implementation. We should deduplicate canonicalization.
-pub trait CanonicalExt<'tcx, V> {
+#[extension(pub trait CanonicalExt<'tcx, V>)]
+impl<'tcx, V> Canonical<'tcx, V> {
     /// Instantiate the wrapped value, replacing each canonical value
     /// with the value given in `var_values`.
     fn instantiate(&self, tcx: TyCtxt<'tcx>, var_values: &CanonicalVarValues<'tcx>) -> V
     where
-        V: TypeFoldable<TyCtxt<'tcx>>;
+        V: TypeFoldable<TyCtxt<'tcx>>,
+    {
+        self.instantiate_projected(tcx, var_values, |value| value.clone())
+    }
 
     /// Allows one to apply a instantiation to some subset of
     /// `self.value`. Invoke `projection_fn` with `self.value` to get
@@ -33,24 +37,6 @@ pub trait CanonicalExt<'tcx, V> {
         projection_fn: impl FnOnce(&V) -> T,
     ) -> T
     where
-        T: TypeFoldable<TyCtxt<'tcx>>;
-}
-
-impl<'tcx, V> CanonicalExt<'tcx, V> for Canonical<'tcx, V> {
-    fn instantiate(&self, tcx: TyCtxt<'tcx>, var_values: &CanonicalVarValues<'tcx>) -> V
-    where
-        V: TypeFoldable<TyCtxt<'tcx>>,
-    {
-        self.instantiate_projected(tcx, var_values, |value| value.clone())
-    }
-
-    fn instantiate_projected<T>(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        var_values: &CanonicalVarValues<'tcx>,
-        projection_fn: impl FnOnce(&V) -> T,
-    ) -> T
-    where
         T: TypeFoldable<TyCtxt<'tcx>>,
     {
         assert_eq!(self.variables.len(), var_values.len());
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 104bf4a5be8..8f06a5eeb5f 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -2786,19 +2786,8 @@ pub enum FailureCode {
     Error0644,
 }
 
-pub trait ObligationCauseExt<'tcx> {
-    fn as_failure_code(&self, terr: TypeError<'tcx>) -> FailureCode;
-
-    fn as_failure_code_diag(
-        &self,
-        terr: TypeError<'tcx>,
-        span: Span,
-        subdiags: Vec<TypeErrorAdditionalDiags>,
-    ) -> ObligationCauseFailureCode;
-    fn as_requirement_str(&self) -> &'static str;
-}
-
-impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
+#[extension(pub trait ObligationCauseExt<'tcx>)]
+impl<'tcx> ObligationCause<'tcx> {
     fn as_failure_code(&self, terr: TypeError<'tcx>) -> FailureCode {
         use self::FailureCode::*;
         use crate::traits::ObligationCauseCode::*;
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 2caf3b3cc93..243558b11a8 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -626,11 +626,8 @@ pub struct InferCtxtBuilder<'tcx> {
     next_trait_solver: bool,
 }
 
-pub trait TyCtxtInferExt<'tcx> {
-    fn infer_ctxt(self) -> InferCtxtBuilder<'tcx>;
-}
-
-impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> {
+#[extension(pub trait TyCtxtInferExt<'tcx>)]
+impl<'tcx> TyCtxt<'tcx> {
     fn infer_ctxt(self) -> InferCtxtBuilder<'tcx> {
         InferCtxtBuilder {
             tcx: self,
diff --git a/compiler/rustc_infer/src/traits/engine.rs b/compiler/rustc_infer/src/traits/engine.rs
index 64b9714c7c0..c495810858f 100644
--- a/compiler/rustc_infer/src/traits/engine.rs
+++ b/compiler/rustc_infer/src/traits/engine.rs
@@ -52,18 +52,8 @@ pub trait TraitEngine<'tcx>: 'tcx {
     ) -> Vec<PredicateObligation<'tcx>>;
 }
 
-pub trait TraitEngineExt<'tcx> {
-    fn register_predicate_obligations(
-        &mut self,
-        infcx: &InferCtxt<'tcx>,
-        obligations: impl IntoIterator<Item = PredicateObligation<'tcx>>,
-    );
-
-    #[must_use]
-    fn select_all_or_error(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>>;
-}
-
-impl<'tcx, T: ?Sized + TraitEngine<'tcx>> TraitEngineExt<'tcx> for T {
+#[extension(pub trait TraitEngineExt<'tcx>)]
+impl<'tcx, T: ?Sized + TraitEngine<'tcx>> T {
     fn register_predicate_obligations(
         &mut self,
         infcx: &InferCtxt<'tcx>,
@@ -74,6 +64,7 @@ impl<'tcx, T: ?Sized + TraitEngine<'tcx>> TraitEngineExt<'tcx> for T {
         }
     }
 
+    #[must_use]
     fn select_all_or_error(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>> {
         let errors = self.select_where_possible(infcx);
         if !errors.is_empty() {
diff --git a/compiler/rustc_macros/src/extension.rs b/compiler/rustc_macros/src/extension.rs
new file mode 100644
index 00000000000..5377bbdfeab
--- /dev/null
+++ b/compiler/rustc_macros/src/extension.rs
@@ -0,0 +1,154 @@
+use proc_macro2::Ident;
+use quote::quote;
+use syn::parse::{Parse, ParseStream};
+use syn::punctuated::Punctuated;
+use syn::spanned::Spanned;
+use syn::{
+    braced, parse_macro_input, Attribute, Generics, ImplItem, Pat, PatIdent, Path, Signature,
+    Token, TraitItem, TraitItemConst, TraitItemFn, TraitItemMacro, TraitItemType, Type, Visibility,
+};
+
+pub(crate) fn extension(
+    attr: proc_macro::TokenStream,
+    input: proc_macro::TokenStream,
+) -> proc_macro::TokenStream {
+    let ExtensionAttr { vis, trait_ } = parse_macro_input!(attr as ExtensionAttr);
+    let Impl { attrs, generics, self_ty, items } = parse_macro_input!(input as Impl);
+    let headers: Vec<_> = items
+        .iter()
+        .map(|item| match item {
+            ImplItem::Fn(f) => TraitItem::Fn(TraitItemFn {
+                attrs: scrub_attrs(&f.attrs),
+                sig: scrub_header(f.sig.clone()),
+                default: None,
+                semi_token: Some(Token![;](f.block.span())),
+            }),
+            ImplItem::Const(ct) => TraitItem::Const(TraitItemConst {
+                attrs: scrub_attrs(&ct.attrs),
+                const_token: ct.const_token,
+                ident: ct.ident.clone(),
+                generics: ct.generics.clone(),
+                colon_token: ct.colon_token,
+                ty: ct.ty.clone(),
+                default: None,
+                semi_token: ct.semi_token,
+            }),
+            ImplItem::Type(ty) => TraitItem::Type(TraitItemType {
+                attrs: scrub_attrs(&ty.attrs),
+                type_token: ty.type_token,
+                ident: ty.ident.clone(),
+                generics: ty.generics.clone(),
+                colon_token: None,
+                bounds: Punctuated::new(),
+                default: None,
+                semi_token: ty.semi_token,
+            }),
+            ImplItem::Macro(mac) => TraitItem::Macro(TraitItemMacro {
+                attrs: scrub_attrs(&mac.attrs),
+                mac: mac.mac.clone(),
+                semi_token: mac.semi_token,
+            }),
+            ImplItem::Verbatim(stream) => TraitItem::Verbatim(stream.clone()),
+            _ => unimplemented!(),
+        })
+        .collect();
+
+    quote! {
+        #(#attrs)*
+        #vis trait #trait_ {
+            #(#headers)*
+        }
+
+        impl #generics #trait_ for #self_ty {
+            #(#items)*
+        }
+    }
+    .into()
+}
+
+/// Only keep `#[doc]` attrs.
+fn scrub_attrs(attrs: &[Attribute]) -> Vec<Attribute> {
+    attrs
+        .into_iter()
+        .cloned()
+        .filter(|attr| {
+            let ident = &attr.path().segments[0].ident;
+            ident == "doc" || ident == "must_use"
+        })
+        .collect()
+}
+
+/// Scrub arguments so that they're valid for trait signatures.
+fn scrub_header(mut sig: Signature) -> Signature {
+    for (idx, input) in sig.inputs.iter_mut().enumerate() {
+        match input {
+            syn::FnArg::Receiver(rcvr) => {
+                // `mut self` -> `self`
+                if rcvr.reference.is_none() {
+                    rcvr.mutability.take();
+                }
+            }
+            syn::FnArg::Typed(arg) => match &mut *arg.pat {
+                Pat::Ident(arg) => {
+                    // `ref mut ident @ pat` -> `ident`
+                    arg.by_ref.take();
+                    arg.mutability.take();
+                    arg.subpat.take();
+                }
+                _ => {
+                    // `pat` -> `__arg0`
+                    arg.pat = Box::new(
+                        PatIdent {
+                            attrs: vec![],
+                            by_ref: None,
+                            mutability: None,
+                            ident: Ident::new(&format!("__arg{idx}"), arg.pat.span()),
+                            subpat: None,
+                        }
+                        .into(),
+                    )
+                }
+            },
+        }
+    }
+    sig
+}
+
+struct ExtensionAttr {
+    vis: Visibility,
+    trait_: Path,
+}
+
+impl Parse for ExtensionAttr {
+    fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
+        let vis = input.parse()?;
+        let _: Token![trait] = input.parse()?;
+        let trait_ = input.parse()?;
+        Ok(ExtensionAttr { vis, trait_ })
+    }
+}
+
+struct Impl {
+    attrs: Vec<Attribute>,
+    generics: Generics,
+    self_ty: Type,
+    items: Vec<ImplItem>,
+}
+
+impl Parse for Impl {
+    fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
+        let attrs = input.call(Attribute::parse_outer)?;
+        let _: Token![impl] = input.parse()?;
+        let generics = input.parse()?;
+        let self_ty = input.parse()?;
+
+        let content;
+        let _brace_token = braced!(content in input);
+        let mut items = Vec::new();
+        while !content.is_empty() {
+            items.push(content.parse()?);
+        }
+
+        Ok(Impl { attrs, generics, self_ty, items })
+    }
+}
diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs
index af65c908ee6..619f93c8a53 100644
--- a/compiler/rustc_macros/src/lib.rs
+++ b/compiler/rustc_macros/src/lib.rs
@@ -14,6 +14,7 @@ use proc_macro::TokenStream;
 
 mod current_version;
 mod diagnostics;
+mod extension;
 mod hash_stable;
 mod lift;
 mod query;
@@ -40,6 +41,11 @@ pub fn symbols(input: TokenStream) -> TokenStream {
     symbols::symbols(input.into()).into()
 }
 
+#[proc_macro_attribute]
+pub fn extension(attr: TokenStream, input: TokenStream) -> TokenStream {
+    extension::extension(attr, input)
+}
+
 decl_derive!([HashStable, attributes(stable_hasher)] => hash_stable::hash_stable_derive);
 decl_derive!(
     [HashStable_Generic, attributes(stable_hasher)] =>
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 2b34f5daaf6..c1e33fe114f 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -23,20 +23,8 @@ use std::fmt;
 use std::num::NonZero;
 use std::ops::Bound;
 
-pub trait IntegerExt {
-    fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>, signed: bool) -> Ty<'tcx>;
-    fn from_int_ty<C: HasDataLayout>(cx: &C, ity: ty::IntTy) -> Integer;
-    fn from_uint_ty<C: HasDataLayout>(cx: &C, uty: ty::UintTy) -> Integer;
-    fn repr_discr<'tcx>(
-        tcx: TyCtxt<'tcx>,
-        ty: Ty<'tcx>,
-        repr: &ReprOptions,
-        min: i128,
-        max: i128,
-    ) -> (Integer, bool);
-}
-
-impl IntegerExt for Integer {
+#[extension(pub trait IntegerExt)]
+impl Integer {
     #[inline]
     fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>, signed: bool) -> Ty<'tcx> {
         match (*self, signed) {
@@ -123,12 +111,8 @@ impl IntegerExt for Integer {
     }
 }
 
-pub trait PrimitiveExt {
-    fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx>;
-    fn to_int_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx>;
-}
-
-impl PrimitiveExt for Primitive {
+#[extension(pub trait PrimitiveExt)]
+impl Primitive {
     #[inline]
     fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         match *self {
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 2addfa37f8b..3f539945841 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -96,13 +96,8 @@ impl<'tcx> Discr<'tcx> {
     }
 }
 
-pub trait IntTypeExt {
-    fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx>;
-    fn disr_incr<'tcx>(&self, tcx: TyCtxt<'tcx>, val: Option<Discr<'tcx>>) -> Option<Discr<'tcx>>;
-    fn initial_discriminant<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Discr<'tcx>;
-}
-
-impl IntTypeExt for IntegerType {
+#[extension(pub trait IntTypeExt)]
+impl IntegerType {
     fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         match self {
             IntegerType::Pointer(true) => tcx.types.isize,
diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs
index f8e6905282c..6212155a8fe 100644
--- a/compiler/rustc_mir_transform/src/const_prop_lint.rs
+++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs
@@ -32,11 +32,6 @@ impl<'tcx> MirLint<'tcx> for ConstPropLint {
             return;
         }
 
-        // will be evaluated by miri and produce its errors there
-        if body.source.promoted.is_some() {
-            return;
-        }
-
         let def_id = body.source.def_id().expect_local();
         let def_kind = tcx.def_kind(def_id);
         let is_fn_like = def_kind.is_fn_like();
diff --git a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
index 9517ede288f..2db358379fe 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
@@ -132,18 +132,23 @@ fn bcb_to_initial_coverage_spans<'a, 'tcx>(
     bcb_data.basic_blocks.iter().flat_map(move |&bb| {
         let data = &mir_body[bb];
 
+        let unexpand = move |expn_span| {
+            unexpand_into_body_span_with_visible_macro(expn_span, body_span)
+                // Discard any spans that fill the entire body, because they tend
+                // to represent compiler-inserted code, e.g. implicitly returning `()`.
+                .filter(|(span, _)| !span.source_equal(body_span))
+        };
+
         let statement_spans = data.statements.iter().filter_map(move |statement| {
             let expn_span = filtered_statement_span(statement)?;
-            let (span, visible_macro) =
-                unexpand_into_body_span_with_visible_macro(expn_span, body_span)?;
+            let (span, visible_macro) = unexpand(expn_span)?;
 
             Some(SpanFromMir::new(span, visible_macro, bcb, is_closure_like(statement)))
         });
 
         let terminator_span = Some(data.terminator()).into_iter().filter_map(move |terminator| {
             let expn_span = filtered_terminator_span(terminator)?;
-            let (span, visible_macro) =
-                unexpand_into_body_span_with_visible_macro(expn_span, body_span)?;
+            let (span, visible_macro) = unexpand(expn_span)?;
 
             Some(SpanFromMir::new(span, visible_macro, bcb, false))
         });
diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs
index ef4a0f52f9e..f694dd00703 100644
--- a/compiler/rustc_trait_selection/src/infer.rs
+++ b/compiler/rustc_trait_selection/src/infer.rs
@@ -17,49 +17,8 @@ use std::fmt::Debug;
 
 pub use rustc_infer::infer::*;
 
-pub trait InferCtxtExt<'tcx> {
-    fn type_is_copy_modulo_regions(&self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool;
-
-    fn type_is_sized_modulo_regions(&self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool;
-
-    /// Check whether a `ty` implements given trait(trait_def_id) without side-effects.
-    ///
-    /// The inputs are:
-    ///
-    /// - the def-id of the trait
-    /// - the type parameters of the trait, including the self-type
-    /// - the parameter environment
-    ///
-    /// Invokes `evaluate_obligation`, so in the event that evaluating
-    /// `Ty: Trait` causes overflow, EvaluatedToErrStackDependent
-    /// (or EvaluatedToAmbigStackDependent) will be returned.
-    fn type_implements_trait(
-        &self,
-        trait_def_id: DefId,
-        params: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
-        param_env: ty::ParamEnv<'tcx>,
-    ) -> traits::EvaluationResult;
-
-    /// Returns `Some` if a type implements a trait shallowly, without side-effects,
-    /// along with any errors that would have been reported upon further obligation
-    /// processing.
-    ///
-    /// - If this returns `Some([])`, then the trait holds modulo regions.
-    /// - If this returns `Some([errors..])`, then the trait has an impl for
-    /// the self type, but some nested obligations do not hold.
-    /// - If this returns `None`, no implementation that applies could be found.
-    ///
-    /// FIXME(-Znext-solver): Due to the recursive nature of the new solver,
-    /// this will probably only ever return `Some([])` or `None`.
-    fn type_implements_trait_shallow(
-        &self,
-        trait_def_id: DefId,
-        ty: Ty<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-    ) -> Option<Vec<traits::FulfillmentError<'tcx>>>;
-}
-
-impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
+#[extension(pub trait InferCtxtExt<'tcx>)]
+impl<'tcx> InferCtxt<'tcx> {
     fn type_is_copy_modulo_regions(&self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool {
         let ty = self.resolve_vars_if_possible(ty);
 
@@ -81,6 +40,17 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
         traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, lang_item)
     }
 
+    /// Check whether a `ty` implements given trait(trait_def_id) without side-effects.
+    ///
+    /// The inputs are:
+    ///
+    /// - the def-id of the trait
+    /// - the type parameters of the trait, including the self-type
+    /// - the parameter environment
+    ///
+    /// Invokes `evaluate_obligation`, so in the event that evaluating
+    /// `Ty: Trait` causes overflow, EvaluatedToErrStackDependent
+    /// (or EvaluatedToAmbigStackDependent) will be returned.
     #[instrument(level = "debug", skip(self, params), ret)]
     fn type_implements_trait(
         &self,
@@ -99,6 +69,17 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
         self.evaluate_obligation(&obligation).unwrap_or(traits::EvaluationResult::EvaluatedToErr)
     }
 
+    /// Returns `Some` if a type implements a trait shallowly, without side-effects,
+    /// along with any errors that would have been reported upon further obligation
+    /// processing.
+    ///
+    /// - If this returns `Some([])`, then the trait holds modulo regions.
+    /// - If this returns `Some([errors..])`, then the trait has an impl for
+    /// the self type, but some nested obligations do not hold.
+    /// - If this returns `None`, no implementation that applies could be found.
+    ///
+    /// FIXME(-Znext-solver): Due to the recursive nature of the new solver,
+    /// this will probably only ever return `Some([])` or `None`.
     fn type_implements_trait_shallow(
         &self,
         trait_def_id: DefId,
@@ -124,19 +105,8 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
     }
 }
 
-pub trait InferCtxtBuilderExt<'tcx> {
-    fn enter_canonical_trait_query<K, R>(
-        self,
-        canonical_key: &Canonical<'tcx, K>,
-        operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Result<R, NoSolution>,
-    ) -> Result<CanonicalQueryResponse<'tcx, R>, NoSolution>
-    where
-        K: TypeFoldable<TyCtxt<'tcx>>,
-        R: Debug + TypeFoldable<TyCtxt<'tcx>>,
-        Canonical<'tcx, QueryResponse<'tcx, R>>: ArenaAllocatable<'tcx>;
-}
-
-impl<'tcx> InferCtxtBuilderExt<'tcx> for InferCtxtBuilder<'tcx> {
+#[extension(pub trait InferCtxtBuilderExt<'tcx>)]
+impl<'tcx> InferCtxtBuilder<'tcx> {
     /// The "main method" for a canonicalized trait query. Given the
     /// canonical key `canonical_key`, this method will create a new
     /// inference context, instantiate the key, and run your operation
diff --git a/compiler/rustc_trait_selection/src/regions.rs b/compiler/rustc_trait_selection/src/regions.rs
index 756db7cc206..222d0b4d5e7 100644
--- a/compiler/rustc_trait_selection/src/regions.rs
+++ b/compiler/rustc_trait_selection/src/regions.rs
@@ -3,7 +3,8 @@ use rustc_infer::infer::{InferCtxt, RegionResolutionError};
 use rustc_middle::traits::query::NoSolution;
 use rustc_middle::traits::ObligationCause;
 
-pub trait InferCtxtRegionExt<'tcx> {
+#[extension(pub trait InferCtxtRegionExt<'tcx>)]
+impl<'tcx> InferCtxt<'tcx> {
     /// Resolve regions, using the deep normalizer to normalize any type-outlives
     /// obligations in the process. This is in `rustc_trait_selection` because
     /// we need to normalize.
@@ -13,13 +14,6 @@ pub trait InferCtxtRegionExt<'tcx> {
     fn resolve_regions(
         &self,
         outlives_env: &OutlivesEnvironment<'tcx>,
-    ) -> Vec<RegionResolutionError<'tcx>>;
-}
-
-impl<'tcx> InferCtxtRegionExt<'tcx> for InferCtxt<'tcx> {
-    fn resolve_regions(
-        &self,
-        outlives_env: &OutlivesEnvironment<'tcx>,
     ) -> Vec<RegionResolutionError<'tcx>> {
         self.resolve_regions_with_normalize(outlives_env, |ty, origin| {
             let ty = self.resolve_vars_if_possible(ty);
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
index 803379af005..5c1e8bf616f 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
@@ -131,22 +131,12 @@ pub enum GenerateProofTree {
     Never,
 }
 
-pub trait InferCtxtEvalExt<'tcx> {
+#[extension(pub trait InferCtxtEvalExt<'tcx>)]
+impl<'tcx> InferCtxt<'tcx> {
     /// Evaluates a goal from **outside** of the trait solver.
     ///
     /// Using this while inside of the solver is wrong as it uses a new
     /// search graph which would break cycle detection.
-    fn evaluate_root_goal(
-        &self,
-        goal: Goal<'tcx, ty::Predicate<'tcx>>,
-        generate_proof_tree: GenerateProofTree,
-    ) -> (
-        Result<(bool, Certainty, Vec<Goal<'tcx, ty::Predicate<'tcx>>>), NoSolution>,
-        Option<inspect::GoalEvaluation<'tcx>>,
-    );
-}
-
-impl<'tcx> InferCtxtEvalExt<'tcx> for InferCtxt<'tcx> {
     #[instrument(level = "debug", skip(self))]
     fn evaluate_root_goal(
         &self,
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
index eab59624436..7196a5af259 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
@@ -17,14 +17,8 @@ use crate::solve::inspect::ProofTreeBuilder;
 use crate::traits::StructurallyNormalizeExt;
 use crate::traits::TraitEngineExt;
 
-pub trait InferCtxtSelectExt<'tcx> {
-    fn select_in_new_trait_solver(
-        &self,
-        obligation: &PolyTraitObligation<'tcx>,
-    ) -> SelectionResult<'tcx, Selection<'tcx>>;
-}
-
-impl<'tcx> InferCtxtSelectExt<'tcx> for InferCtxt<'tcx> {
+#[extension(pub trait InferCtxtSelectExt<'tcx>)]
+impl<'tcx> InferCtxt<'tcx> {
     fn select_in_new_trait_solver(
         &self,
         obligation: &PolyTraitObligation<'tcx>,
diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
index f33d0f397ce..47f207e1d75 100644
--- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
+++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
@@ -216,15 +216,8 @@ pub trait ProofTreeVisitor<'tcx> {
     fn visit_goal(&mut self, goal: &InspectGoal<'_, 'tcx>) -> ControlFlow<Self::BreakTy>;
 }
 
-pub trait ProofTreeInferCtxtExt<'tcx> {
-    fn visit_proof_tree<V: ProofTreeVisitor<'tcx>>(
-        &self,
-        goal: Goal<'tcx, ty::Predicate<'tcx>>,
-        visitor: &mut V,
-    ) -> ControlFlow<V::BreakTy>;
-}
-
-impl<'tcx> ProofTreeInferCtxtExt<'tcx> for InferCtxt<'tcx> {
+#[extension(pub trait ProofTreeInferCtxtExt<'tcx>)]
+impl<'tcx> InferCtxt<'tcx> {
     fn visit_proof_tree<V: ProofTreeVisitor<'tcx>>(
         &self,
         goal: Goal<'tcx, ty::Predicate<'tcx>>,
diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs
index 94a3cef8ad1..8b163d47d34 100644
--- a/compiler/rustc_trait_selection/src/solve/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/mod.rs
@@ -61,11 +61,8 @@ enum GoalEvaluationKind {
     Nested { is_normalizes_to_hack: IsNormalizesToHack },
 }
 
-trait CanonicalResponseExt {
-    fn has_no_inference_or_external_constraints(&self) -> bool;
-}
-
-impl<'tcx> CanonicalResponseExt for Canonical<'tcx, Response<'tcx>> {
+#[extension(trait CanonicalResponseExt)]
+impl<'tcx> Canonical<'tcx, Response<'tcx>> {
     fn has_no_inference_or_external_constraints(&self) -> bool {
         self.value.external_constraints.region_constraints.is_empty()
             && self.value.var_values.is_identity()
diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs
index caf950037fd..1aaadf6cf04 100644
--- a/compiler/rustc_trait_selection/src/traits/engine.rs
+++ b/compiler/rustc_trait_selection/src/traits/engine.rs
@@ -27,11 +27,8 @@ use rustc_middle::ty::TypeFoldable;
 use rustc_middle::ty::Variance;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 
-pub trait TraitEngineExt<'tcx> {
-    fn new(infcx: &InferCtxt<'tcx>) -> Box<Self>;
-}
-
-impl<'tcx> TraitEngineExt<'tcx> for dyn TraitEngine<'tcx> {
+#[extension(pub trait TraitEngineExt<'tcx>)]
+impl<'tcx> dyn TraitEngine<'tcx> {
     fn new(infcx: &InferCtxt<'tcx>) -> Box<Self> {
         if infcx.next_trait_solver() {
             Box::new(NextFulfillmentCtxt::new(infcx))
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs
index 15d064d4036..4788ecbe3e2 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs
@@ -11,38 +11,8 @@ use super::ArgKind;
 
 pub use rustc_infer::traits::error_reporting::*;
 
-pub trait InferCtxtExt<'tcx> {
-    /// Given some node representing a fn-like thing in the HIR map,
-    /// returns a span and `ArgKind` information that describes the
-    /// arguments it expects. This can be supplied to
-    /// `report_arg_count_mismatch`.
-    fn get_fn_like_arguments(&self, node: Node<'_>) -> Option<(Span, Option<Span>, Vec<ArgKind>)>;
-
-    /// Reports an error when the number of arguments needed by a
-    /// trait match doesn't match the number that the expression
-    /// provides.
-    fn report_arg_count_mismatch(
-        &self,
-        span: Span,
-        found_span: Option<Span>,
-        expected_args: Vec<ArgKind>,
-        found_args: Vec<ArgKind>,
-        is_closure: bool,
-        closure_pipe_span: Option<Span>,
-    ) -> DiagnosticBuilder<'tcx>;
-
-    /// Checks if the type implements one of `Fn`, `FnMut`, or `FnOnce`
-    /// in that order, and returns the generic type corresponding to the
-    /// argument of that trait (corresponding to the closure arguments).
-    fn type_implements_fn_trait(
-        &self,
-        param_env: ty::ParamEnv<'tcx>,
-        ty: ty::Binder<'tcx, Ty<'tcx>>,
-        polarity: ty::ImplPolarity,
-    ) -> Result<(ty::ClosureKind, ty::Binder<'tcx, Ty<'tcx>>), ()>;
-}
-
-impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
+#[extension(pub trait InferCtxtExt<'tcx>)]
+impl<'tcx> InferCtxt<'tcx> {
     /// Given some node representing a fn-like thing in the HIR map,
     /// returns a span and `ArgKind` information that describes the
     /// arguments it expects. This can be supplied to
@@ -229,6 +199,9 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
         err
     }
 
+    /// Checks if the type implements one of `Fn`, `FnMut`, or `FnOnce`
+    /// in that order, and returns the generic type corresponding to the
+    /// argument of that trait (corresponding to the closure arguments).
     fn type_implements_fn_trait(
         &self,
         param_env: ty::ParamEnv<'tcx>,
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
index f0773fd1671..4ba2da95fb3 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
@@ -23,24 +23,6 @@ use crate::errors::{
 
 use crate::traits::error_reporting::type_err_ctxt_ext::InferCtxtPrivExt;
 
-pub trait TypeErrCtxtExt<'tcx> {
-    /*private*/
-    fn impl_similar_to(
-        &self,
-        trait_ref: ty::PolyTraitRef<'tcx>,
-        obligation: &PredicateObligation<'tcx>,
-    ) -> Option<(DefId, GenericArgsRef<'tcx>)>;
-
-    /*private*/
-    fn describe_enclosure(&self, def_id: LocalDefId) -> Option<&'static str>;
-
-    fn on_unimplemented_note(
-        &self,
-        trait_ref: ty::PolyTraitRef<'tcx>,
-        obligation: &PredicateObligation<'tcx>,
-    ) -> OnUnimplementedNote;
-}
-
 /// The symbols which are always allowed in a format string
 static ALLOWED_FORMAT_SYMBOLS: &[Symbol] = &[
     kw::SelfUpper,
@@ -56,7 +38,8 @@ static ALLOWED_FORMAT_SYMBOLS: &[Symbol] = &[
     sym::Trait,
 ];
 
-impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
+#[extension(pub trait TypeErrCtxtExt<'tcx>)]
+impl<'tcx> TypeErrCtxt<'_, 'tcx> {
     fn impl_similar_to(
         &self,
         trait_ref: ty::PolyTraitRef<'tcx>,
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 335e6ff2822..7de13bf0c02 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -106,279 +106,6 @@ impl<'tcx, 'a> CoroutineData<'tcx, 'a> {
     }
 }
 
-// This trait is public to expose the diagnostics methods to clippy.
-pub trait TypeErrCtxtExt<'tcx> {
-    fn suggest_restricting_param_bound(
-        &self,
-        err: &mut Diagnostic,
-        trait_pred: ty::PolyTraitPredicate<'tcx>,
-        associated_item: Option<(&'static str, Ty<'tcx>)>,
-        body_id: LocalDefId,
-    );
-
-    fn suggest_dereferences(
-        &self,
-        obligation: &PredicateObligation<'tcx>,
-        err: &mut Diagnostic,
-        trait_pred: ty::PolyTraitPredicate<'tcx>,
-    ) -> bool;
-
-    fn get_closure_name(
-        &self,
-        def_id: DefId,
-        err: &mut Diagnostic,
-        msg: Cow<'static, str>,
-    ) -> Option<Symbol>;
-
-    fn suggest_fn_call(
-        &self,
-        obligation: &PredicateObligation<'tcx>,
-        err: &mut Diagnostic,
-        trait_pred: ty::PolyTraitPredicate<'tcx>,
-    ) -> bool;
-
-    fn check_for_binding_assigned_block_without_tail_expression(
-        &self,
-        obligation: &PredicateObligation<'tcx>,
-        err: &mut Diagnostic,
-        trait_pred: ty::PolyTraitPredicate<'tcx>,
-    );
-
-    fn suggest_add_clone_to_arg(
-        &self,
-        obligation: &PredicateObligation<'tcx>,
-        err: &mut Diagnostic,
-        trait_pred: ty::PolyTraitPredicate<'tcx>,
-    ) -> bool;
-
-    fn extract_callable_info(
-        &self,
-        body_id: LocalDefId,
-        param_env: ty::ParamEnv<'tcx>,
-        found: Ty<'tcx>,
-    ) -> Option<(DefIdOrName, Ty<'tcx>, Vec<Ty<'tcx>>)>;
-
-    fn suggest_add_reference_to_arg(
-        &self,
-        obligation: &PredicateObligation<'tcx>,
-        err: &mut Diagnostic,
-        trait_pred: ty::PolyTraitPredicate<'tcx>,
-        has_custom_message: bool,
-    ) -> bool;
-
-    fn suggest_borrowing_for_object_cast(
-        &self,
-        err: &mut Diagnostic,
-        obligation: &PredicateObligation<'tcx>,
-        self_ty: Ty<'tcx>,
-        object_ty: Ty<'tcx>,
-    );
-
-    fn suggest_remove_reference(
-        &self,
-        obligation: &PredicateObligation<'tcx>,
-        err: &mut Diagnostic,
-        trait_pred: ty::PolyTraitPredicate<'tcx>,
-    ) -> bool;
-
-    fn suggest_remove_await(&self, obligation: &PredicateObligation<'tcx>, err: &mut Diagnostic);
-
-    fn suggest_change_mut(
-        &self,
-        obligation: &PredicateObligation<'tcx>,
-        err: &mut Diagnostic,
-        trait_pred: ty::PolyTraitPredicate<'tcx>,
-    );
-
-    fn suggest_semicolon_removal(
-        &self,
-        obligation: &PredicateObligation<'tcx>,
-        err: &mut Diagnostic,
-        span: Span,
-        trait_pred: ty::PolyTraitPredicate<'tcx>,
-    ) -> bool;
-
-    fn return_type_span(&self, obligation: &PredicateObligation<'tcx>) -> Option<Span>;
-
-    fn suggest_impl_trait(
-        &self,
-        err: &mut Diagnostic,
-        obligation: &PredicateObligation<'tcx>,
-        trait_pred: ty::PolyTraitPredicate<'tcx>,
-    ) -> bool;
-
-    fn point_at_returns_when_relevant(
-        &self,
-        err: &mut DiagnosticBuilder<'tcx>,
-        obligation: &PredicateObligation<'tcx>,
-    );
-
-    fn report_closure_arg_mismatch(
-        &self,
-        span: Span,
-        found_span: Option<Span>,
-        found: ty::PolyTraitRef<'tcx>,
-        expected: ty::PolyTraitRef<'tcx>,
-        cause: &ObligationCauseCode<'tcx>,
-        found_node: Option<Node<'_>>,
-        param_env: ty::ParamEnv<'tcx>,
-    ) -> DiagnosticBuilder<'tcx>;
-
-    fn note_conflicting_fn_args(
-        &self,
-        err: &mut Diagnostic,
-        cause: &ObligationCauseCode<'tcx>,
-        expected: Ty<'tcx>,
-        found: Ty<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-    );
-
-    fn note_conflicting_closure_bounds(
-        &self,
-        cause: &ObligationCauseCode<'tcx>,
-        err: &mut DiagnosticBuilder<'tcx>,
-    );
-
-    fn suggest_fully_qualified_path(
-        &self,
-        err: &mut Diagnostic,
-        item_def_id: DefId,
-        span: Span,
-        trait_ref: DefId,
-    );
-
-    fn maybe_note_obligation_cause_for_async_await(
-        &self,
-        err: &mut Diagnostic,
-        obligation: &PredicateObligation<'tcx>,
-    ) -> bool;
-
-    fn note_obligation_cause_for_async_await(
-        &self,
-        err: &mut Diagnostic,
-        interior_or_upvar_span: CoroutineInteriorOrUpvar,
-        is_async: bool,
-        outer_coroutine: Option<DefId>,
-        trait_pred: ty::TraitPredicate<'tcx>,
-        target_ty: Ty<'tcx>,
-        obligation: &PredicateObligation<'tcx>,
-        next_code: Option<&ObligationCauseCode<'tcx>>,
-    );
-
-    fn note_obligation_cause_code<T>(
-        &self,
-        body_id: LocalDefId,
-        err: &mut Diagnostic,
-        predicate: T,
-        param_env: ty::ParamEnv<'tcx>,
-        cause_code: &ObligationCauseCode<'tcx>,
-        obligated_types: &mut Vec<Ty<'tcx>>,
-        seen_requirements: &mut FxHashSet<DefId>,
-    ) where
-        T: ToPredicate<'tcx>;
-
-    /// Suggest to await before try: future? => future.await?
-    fn suggest_await_before_try(
-        &self,
-        err: &mut Diagnostic,
-        obligation: &PredicateObligation<'tcx>,
-        trait_pred: ty::PolyTraitPredicate<'tcx>,
-        span: Span,
-    );
-
-    fn suggest_floating_point_literal(
-        &self,
-        obligation: &PredicateObligation<'tcx>,
-        err: &mut Diagnostic,
-        trait_ref: &ty::PolyTraitRef<'tcx>,
-    );
-
-    fn suggest_derive(
-        &self,
-        obligation: &PredicateObligation<'tcx>,
-        err: &mut Diagnostic,
-        trait_pred: ty::PolyTraitPredicate<'tcx>,
-    );
-
-    fn suggest_dereferencing_index(
-        &self,
-        obligation: &PredicateObligation<'tcx>,
-        err: &mut Diagnostic,
-        trait_pred: ty::PolyTraitPredicate<'tcx>,
-    );
-
-    fn suggest_option_method_if_applicable(
-        &self,
-        failed_pred: ty::Predicate<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-        err: &mut Diagnostic,
-        expr: &hir::Expr<'_>,
-    );
-
-    fn note_function_argument_obligation(
-        &self,
-        body_id: LocalDefId,
-        err: &mut Diagnostic,
-        arg_hir_id: HirId,
-        parent_code: &ObligationCauseCode<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-        predicate: ty::Predicate<'tcx>,
-        call_hir_id: HirId,
-    );
-
-    fn look_for_iterator_item_mistakes(
-        &self,
-        assocs_in_this_method: &[Option<(Span, (DefId, Ty<'tcx>))>],
-        typeck_results: &TypeckResults<'tcx>,
-        type_diffs: &[TypeError<'tcx>],
-        param_env: ty::ParamEnv<'tcx>,
-        path_segment: &hir::PathSegment<'_>,
-        args: &[hir::Expr<'_>],
-        err: &mut Diagnostic,
-    );
-
-    fn point_at_chain(
-        &self,
-        expr: &hir::Expr<'_>,
-        typeck_results: &TypeckResults<'tcx>,
-        type_diffs: Vec<TypeError<'tcx>>,
-        param_env: ty::ParamEnv<'tcx>,
-        err: &mut Diagnostic,
-    );
-
-    fn probe_assoc_types_at_expr(
-        &self,
-        type_diffs: &[TypeError<'tcx>],
-        span: Span,
-        prev_ty: Ty<'tcx>,
-        body_id: hir::HirId,
-        param_env: ty::ParamEnv<'tcx>,
-    ) -> Vec<Option<(Span, (DefId, Ty<'tcx>))>>;
-
-    fn suggest_convert_to_slice(
-        &self,
-        err: &mut Diagnostic,
-        obligation: &PredicateObligation<'tcx>,
-        trait_ref: ty::PolyTraitRef<'tcx>,
-        candidate_impls: &[ImplCandidate<'tcx>],
-        span: Span,
-    );
-
-    fn explain_hrtb_projection(
-        &self,
-        diag: &mut Diagnostic,
-        pred: ty::PolyTraitPredicate<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-        cause: &ObligationCause<'tcx>,
-    );
-
-    fn suggest_desugaring_async_fn_in_trait(
-        &self,
-        err: &mut Diagnostic,
-        trait_ref: ty::PolyTraitRef<'tcx>,
-    );
-}
-
 fn predicate_constraint(generics: &hir::Generics<'_>, pred: ty::Predicate<'_>) -> (Span, String) {
     (
         generics.tail_span_for_predicate_suggestion(),
@@ -509,7 +236,8 @@ pub fn suggest_restriction<'tcx>(
     }
 }
 
-impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
+#[extension(pub trait TypeErrCtxtExt<'tcx>)]
+impl<'tcx> TypeErrCtxt<'_, 'tcx> {
     fn suggest_restricting_param_bound(
         &self,
         err: &mut Diagnostic,
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
index 661a444d049..67bd18d7404 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
@@ -57,78 +57,8 @@ use super::{
 
 pub use rustc_infer::traits::error_reporting::*;
 
-pub trait TypeErrCtxtExt<'tcx> {
-    fn build_overflow_error<T>(
-        &self,
-        predicate: &T,
-        span: Span,
-        suggest_increasing_limit: bool,
-    ) -> DiagnosticBuilder<'tcx>
-    where
-        T: fmt::Display + TypeFoldable<TyCtxt<'tcx>> + Print<'tcx, FmtPrinter<'tcx, 'tcx>>;
-
-    fn report_overflow_error<T>(
-        &self,
-        predicate: &T,
-        span: Span,
-        suggest_increasing_limit: bool,
-        mutate: impl FnOnce(&mut Diagnostic),
-    ) -> !
-    where
-        T: fmt::Display + TypeFoldable<TyCtxt<'tcx>> + Print<'tcx, FmtPrinter<'tcx, 'tcx>>;
-
-    fn report_overflow_no_abort(&self, obligation: PredicateObligation<'tcx>) -> ErrorGuaranteed;
-
-    fn report_fulfillment_errors(&self, errors: Vec<FulfillmentError<'tcx>>) -> ErrorGuaranteed;
-
-    fn report_overflow_obligation<T>(
-        &self,
-        obligation: &Obligation<'tcx, T>,
-        suggest_increasing_limit: bool,
-    ) -> !
-    where
-        T: ToPredicate<'tcx> + Clone;
-
-    fn suggest_new_overflow_limit(&self, err: &mut Diagnostic);
-
-    fn report_overflow_obligation_cycle(&self, cycle: &[PredicateObligation<'tcx>]) -> !;
-
-    /// The `root_obligation` parameter should be the `root_obligation` field
-    /// from a `FulfillmentError`. If no `FulfillmentError` is available,
-    /// then it should be the same as `obligation`.
-    fn report_selection_error(
-        &self,
-        obligation: PredicateObligation<'tcx>,
-        root_obligation: &PredicateObligation<'tcx>,
-        error: &SelectionError<'tcx>,
-    ) -> ErrorGuaranteed;
-
-    fn emit_specialized_closure_kind_error(
-        &self,
-        obligation: &PredicateObligation<'tcx>,
-        trait_ref: ty::PolyTraitRef<'tcx>,
-    ) -> Option<ErrorGuaranteed>;
-
-    fn fn_arg_obligation(
-        &self,
-        obligation: &PredicateObligation<'tcx>,
-    ) -> Result<(), ErrorGuaranteed>;
-
-    fn try_conversion_context(
-        &self,
-        obligation: &PredicateObligation<'tcx>,
-        trait_ref: ty::TraitRef<'tcx>,
-        err: &mut Diagnostic,
-    ) -> bool;
-
-    fn report_const_param_not_wf(
-        &self,
-        ty: Ty<'tcx>,
-        obligation: &PredicateObligation<'tcx>,
-    ) -> DiagnosticBuilder<'tcx>;
-}
-
-impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
+#[extension(pub trait TypeErrCtxtExt<'tcx>)]
+impl<'tcx> TypeErrCtxt<'_, 'tcx> {
     fn report_fulfillment_errors(
         &self,
         mut errors: Vec<FulfillmentError<'tcx>>,
@@ -382,6 +312,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         err.emit()
     }
 
+    /// The `root_obligation` parameter should be the `root_obligation` field
+    /// from a `FulfillmentError`. If no `FulfillmentError` is available,
+    /// then it should be the same as `obligation`.
     fn report_selection_error(
         &self,
         mut obligation: PredicateObligation<'tcx>,
@@ -1393,209 +1326,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
     }
 }
 
-pub(super) trait InferCtxtPrivExt<'tcx> {
-    // returns if `cond` not occurring implies that `error` does not occur - i.e., that
-    // `error` occurring implies that `cond` occurs.
-    fn error_implies(&self, cond: ty::Predicate<'tcx>, error: ty::Predicate<'tcx>) -> bool;
-
-    fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>) -> ErrorGuaranteed;
-
-    fn report_projection_error(
-        &self,
-        obligation: &PredicateObligation<'tcx>,
-        error: &MismatchedProjectionTypes<'tcx>,
-    ) -> ErrorGuaranteed;
-
-    fn maybe_detailed_projection_msg(
-        &self,
-        pred: ty::ProjectionPredicate<'tcx>,
-        normalized_ty: ty::Term<'tcx>,
-        expected_ty: ty::Term<'tcx>,
-    ) -> Option<String>;
-
-    fn fuzzy_match_tys(
-        &self,
-        a: Ty<'tcx>,
-        b: Ty<'tcx>,
-        ignoring_lifetimes: bool,
-    ) -> Option<CandidateSimilarity>;
-
-    fn describe_closure(&self, kind: hir::ClosureKind) -> &'static str;
-
-    fn find_similar_impl_candidates(
-        &self,
-        trait_pred: ty::PolyTraitPredicate<'tcx>,
-    ) -> Vec<ImplCandidate<'tcx>>;
-
-    fn report_similar_impl_candidates(
-        &self,
-        impl_candidates: &[ImplCandidate<'tcx>],
-        trait_ref: ty::PolyTraitRef<'tcx>,
-        body_def_id: LocalDefId,
-        err: &mut Diagnostic,
-        other: bool,
-        param_env: ty::ParamEnv<'tcx>,
-    ) -> bool;
-
-    fn report_similar_impl_candidates_for_root_obligation(
-        &self,
-        obligation: &PredicateObligation<'tcx>,
-        trait_predicate: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>,
-        body_def_id: LocalDefId,
-        err: &mut Diagnostic,
-    );
-
-    /// Gets the parent trait chain start
-    fn get_parent_trait_ref(
-        &self,
-        code: &ObligationCauseCode<'tcx>,
-    ) -> Option<(Ty<'tcx>, Option<Span>)>;
-
-    /// If the `Self` type of the unsatisfied trait `trait_ref` implements a trait
-    /// with the same path as `trait_ref`, a help message about
-    /// a probable version mismatch is added to `err`
-    fn note_version_mismatch(
-        &self,
-        err: &mut Diagnostic,
-        trait_ref: &ty::PolyTraitRef<'tcx>,
-    ) -> bool;
-
-    /// Creates a `PredicateObligation` with `new_self_ty` replacing the existing type in the
-    /// `trait_ref`.
-    ///
-    /// For this to work, `new_self_ty` must have no escaping bound variables.
-    fn mk_trait_obligation_with_new_self_ty(
-        &self,
-        param_env: ty::ParamEnv<'tcx>,
-        trait_ref_and_ty: ty::Binder<'tcx, (ty::TraitPredicate<'tcx>, Ty<'tcx>)>,
-    ) -> PredicateObligation<'tcx>;
-
-    fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>) -> ErrorGuaranteed;
-
-    fn predicate_can_apply(
-        &self,
-        param_env: ty::ParamEnv<'tcx>,
-        pred: ty::PolyTraitPredicate<'tcx>,
-    ) -> bool;
-
-    fn note_obligation_cause(&self, err: &mut Diagnostic, obligation: &PredicateObligation<'tcx>);
-
-    fn suggest_unsized_bound_if_applicable(
-        &self,
-        err: &mut Diagnostic,
-        obligation: &PredicateObligation<'tcx>,
-    );
-
-    fn annotate_source_of_ambiguity(
-        &self,
-        err: &mut Diagnostic,
-        impls: &[ambiguity::Ambiguity],
-        predicate: ty::Predicate<'tcx>,
-    );
-
-    fn maybe_suggest_unsized_generics(&self, err: &mut Diagnostic, span: Span, node: Node<'tcx>);
-
-    fn maybe_indirection_for_unsized(
-        &self,
-        err: &mut Diagnostic,
-        item: &'tcx Item<'tcx>,
-        param: &'tcx GenericParam<'tcx>,
-    ) -> bool;
-
-    fn is_recursive_obligation(
-        &self,
-        obligated_types: &mut Vec<Ty<'tcx>>,
-        cause_code: &ObligationCauseCode<'tcx>,
-    ) -> bool;
-
-    fn get_standard_error_message(
-        &self,
-        trait_predicate: &ty::PolyTraitPredicate<'tcx>,
-        message: Option<String>,
-        predicate_is_const: bool,
-        append_const_msg: Option<AppendConstMessage>,
-        post_message: String,
-    ) -> String;
-
-    fn get_safe_transmute_error_and_reason(
-        &self,
-        obligation: PredicateObligation<'tcx>,
-        trait_ref: ty::PolyTraitRef<'tcx>,
-        span: Span,
-    ) -> GetSafeTransmuteErrorAndReason;
-
-    fn add_tuple_trait_message(
-        &self,
-        obligation_cause_code: &ObligationCauseCode<'tcx>,
-        err: &mut Diagnostic,
-    );
-
-    fn try_to_add_help_message(
-        &self,
-        obligation: &PredicateObligation<'tcx>,
-        trait_ref: ty::PolyTraitRef<'tcx>,
-        trait_predicate: &ty::PolyTraitPredicate<'tcx>,
-        err: &mut Diagnostic,
-        span: Span,
-        is_fn_trait: bool,
-        suggested: bool,
-        unsatisfied_const: bool,
-    );
-
-    fn add_help_message_for_fn_trait(
-        &self,
-        trait_ref: ty::PolyTraitRef<'tcx>,
-        err: &mut Diagnostic,
-        implemented_kind: ty::ClosureKind,
-        params: ty::Binder<'tcx, Ty<'tcx>>,
-    );
-
-    fn maybe_add_note_for_unsatisfied_const(
-        &self,
-        trait_predicate: &ty::PolyTraitPredicate<'tcx>,
-        err: &mut Diagnostic,
-        span: Span,
-    ) -> UnsatisfiedConst;
-
-    fn report_closure_error(
-        &self,
-        obligation: &PredicateObligation<'tcx>,
-        closure_def_id: DefId,
-        found_kind: ty::ClosureKind,
-        kind: ty::ClosureKind,
-        trait_prefix: &'static str,
-    ) -> DiagnosticBuilder<'tcx>;
-
-    fn report_cyclic_signature_error(
-        &self,
-        obligation: &PredicateObligation<'tcx>,
-        found_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
-        expected_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
-        terr: TypeError<'tcx>,
-    ) -> DiagnosticBuilder<'tcx>;
-
-    fn report_opaque_type_auto_trait_leakage(
-        &self,
-        obligation: &PredicateObligation<'tcx>,
-        def_id: DefId,
-    ) -> DiagnosticBuilder<'tcx>;
-
-    fn report_signature_mismatch_error(
-        &self,
-        obligation: &PredicateObligation<'tcx>,
-        span: Span,
-        found_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
-        expected_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
-    ) -> Result<DiagnosticBuilder<'tcx>, ErrorGuaranteed>;
-
-    fn report_not_const_evaluatable_error(
-        &self,
-        obligation: &PredicateObligation<'tcx>,
-        span: Span,
-    ) -> Result<DiagnosticBuilder<'tcx>, ErrorGuaranteed>;
-}
-
-impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
+#[extension(pub(super) trait InferCtxtPrivExt<'tcx>)]
+impl<'tcx> TypeErrCtxt<'_, 'tcx> {
     // returns if `cond` not occurring implies that `error` does not occur - i.e., that
     // `error` occurring implies that `cond` occurs.
     fn error_implies(&self, cond: ty::Predicate<'tcx>, error: ty::Predicate<'tcx>) -> bool {
@@ -2414,6 +2146,10 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         suggested
     }
 
+    /// Creates a `PredicateObligation` with `new_self_ty` replacing the existing type in the
+    /// `trait_ref`.
+    ///
+    /// For this to work, `new_self_ty` must have no escaping bound variables.
     fn mk_trait_obligation_with_new_self_ty(
         &self,
         param_env: ty::ParamEnv<'tcx>,
diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
index 52631d4353b..6825dd4ac71 100644
--- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
+++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
@@ -11,25 +11,6 @@ pub use rustc_middle::traits::query::OutlivesBound;
 
 pub type BoundsCompat<'a, 'tcx: 'a> = impl Iterator<Item = OutlivesBound<'tcx>> + 'a;
 pub type Bounds<'a, 'tcx: 'a> = impl Iterator<Item = OutlivesBound<'tcx>> + 'a;
-pub trait InferCtxtExt<'a, 'tcx> {
-    /// Do *NOT* call this directly.
-    fn implied_bounds_tys_compat(
-        &'a self,
-        param_env: ty::ParamEnv<'tcx>,
-        body_id: LocalDefId,
-        tys: &'a FxIndexSet<Ty<'tcx>>,
-        compat: bool,
-    ) -> BoundsCompat<'a, 'tcx>;
-
-    /// If `-Z no-implied-bounds-compat` is set, calls `implied_bounds_tys_compat`
-    /// with `compat` set to `true`, otherwise `false`.
-    fn implied_bounds_tys(
-        &'a self,
-        param_env: ty::ParamEnv<'tcx>,
-        body_id: LocalDefId,
-        tys: &'a FxIndexSet<Ty<'tcx>>,
-    ) -> Bounds<'a, 'tcx>;
-}
 
 /// Implied bounds are region relationships that we deduce
 /// automatically. The idea is that (e.g.) a caller must check that a
@@ -130,7 +111,9 @@ fn implied_outlives_bounds<'a, 'tcx>(
     bounds
 }
 
-impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> {
+#[extension(pub trait InferCtxtExt<'a, 'tcx>)]
+impl<'a, 'tcx: 'a> InferCtxt<'tcx> {
+    /// Do *NOT* call this directly.
     fn implied_bounds_tys_compat(
         &'a self,
         param_env: ParamEnv<'tcx>,
@@ -142,6 +125,8 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> {
             .flat_map(move |ty| implied_outlives_bounds(self, param_env, body_id, *ty, compat))
     }
 
+    /// If `-Z no-implied-bounds-compat` is set, calls `implied_bounds_tys_compat`
+    /// with `compat` set to `true`, otherwise `false`.
     fn implied_bounds_tys(
         &'a self,
         param_env: ParamEnv<'tcx>,
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 049877bc5fe..279c0003187 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -52,12 +52,22 @@ pub type ProjectionTyObligation<'tcx> = Obligation<'tcx, ty::AliasTy<'tcx>>;
 
 pub(super) struct InProgress;
 
-pub trait NormalizeExt<'tcx> {
+#[extension(pub trait NormalizeExt<'tcx>)]
+impl<'tcx> At<'_, 'tcx> {
     /// Normalize a value using the `AssocTypeNormalizer`.
     ///
     /// This normalization should be used when the type contains inference variables or the
     /// projection may be fallible.
-    fn normalize<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> InferOk<'tcx, T>;
+    fn normalize<T: TypeFoldable<TyCtxt<'tcx>>>(&self, value: T) -> InferOk<'tcx, T> {
+        if self.infcx.next_trait_solver() {
+            InferOk { value, obligations: Vec::new() }
+        } else {
+            let mut selcx = SelectionContext::new(self.infcx);
+            let Normalized { value, obligations } =
+                normalize_with_depth(&mut selcx, self.param_env, self.cause.clone(), 0, value);
+            InferOk { value, obligations }
+        }
+    }
 
     /// Deeply normalizes `value`, replacing all aliases which can by normalized in
     /// the current environment. In the new solver this errors in case normalization
@@ -77,25 +87,6 @@ pub trait NormalizeExt<'tcx> {
         self,
         value: T,
         fulfill_cx: &mut dyn TraitEngine<'tcx>,
-    ) -> Result<T, Vec<FulfillmentError<'tcx>>>;
-}
-
-impl<'tcx> NormalizeExt<'tcx> for At<'_, 'tcx> {
-    fn normalize<T: TypeFoldable<TyCtxt<'tcx>>>(&self, value: T) -> InferOk<'tcx, T> {
-        if self.infcx.next_trait_solver() {
-            InferOk { value, obligations: Vec::new() }
-        } else {
-            let mut selcx = SelectionContext::new(self.infcx);
-            let Normalized { value, obligations } =
-                normalize_with_depth(&mut selcx, self.param_env, self.cause.clone(), 0, value);
-            InferOk { value, obligations }
-        }
-    }
-
-    fn deeply_normalize<T: TypeFoldable<TyCtxt<'tcx>>>(
-        self,
-        value: T,
-        fulfill_cx: &mut dyn TraitEngine<'tcx>,
     ) -> Result<T, Vec<FulfillmentError<'tcx>>> {
         if self.infcx.next_trait_solver() {
             crate::solve::deeply_normalize(self, value)
diff --git a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
index a050b30317a..16ee9fadab4 100644
--- a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
@@ -4,32 +4,8 @@ use crate::infer::canonical::OriginalQueryValues;
 use crate::infer::InferCtxt;
 use crate::traits::{EvaluationResult, OverflowError, PredicateObligation, SelectionContext};
 
-pub trait InferCtxtExt<'tcx> {
-    fn predicate_may_hold(&self, obligation: &PredicateObligation<'tcx>) -> bool;
-
-    fn predicate_must_hold_considering_regions(
-        &self,
-        obligation: &PredicateObligation<'tcx>,
-    ) -> bool;
-
-    fn predicate_must_hold_modulo_regions(&self, obligation: &PredicateObligation<'tcx>) -> bool;
-
-    fn evaluate_obligation(
-        &self,
-        obligation: &PredicateObligation<'tcx>,
-    ) -> Result<EvaluationResult, OverflowError>;
-
-    // Helper function that canonicalizes and runs the query. If an
-    // overflow results, we re-run it in the local context so we can
-    // report a nice error.
-    /*crate*/
-    fn evaluate_obligation_no_overflow(
-        &self,
-        obligation: &PredicateObligation<'tcx>,
-    ) -> EvaluationResult;
-}
-
-impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
+#[extension(pub trait InferCtxtExt<'tcx>)]
+impl<'tcx> InferCtxt<'tcx> {
     /// Evaluates whether the predicate can be satisfied (by any means)
     /// in the given `ParamEnv`.
     fn predicate_may_hold(&self, obligation: &PredicateObligation<'tcx>) -> bool {
@@ -114,9 +90,9 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
         }
     }
 
-    // Helper function that canonicalizes and runs the query. If an
-    // overflow results, we re-run it in the local context so we can
-    // report a nice error.
+    /// Helper function that canonicalizes and runs the query. If an
+    /// overflow results, we re-run it in the local context so we can
+    /// report a nice error.
     fn evaluate_obligation_no_overflow(
         &self,
         obligation: &PredicateObligation<'tcx>,
diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
index 0b73fefd2da..0f6c0abd280 100644
--- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
@@ -22,20 +22,8 @@ use super::NoSolution;
 
 pub use rustc_middle::traits::query::NormalizationResult;
 
-pub trait QueryNormalizeExt<'tcx> {
-    /// Normalize a value using the `QueryNormalizer`.
-    ///
-    /// This normalization should *only* be used when the projection does not
-    /// have possible ambiguity or may not be well-formed.
-    ///
-    /// After codegen, when lifetimes do not matter, it is preferable to instead
-    /// use [`TyCtxt::normalize_erasing_regions`], which wraps this procedure.
-    fn query_normalize<T>(self, value: T) -> Result<Normalized<'tcx, T>, NoSolution>
-    where
-        T: TypeFoldable<TyCtxt<'tcx>>;
-}
-
-impl<'cx, 'tcx> QueryNormalizeExt<'tcx> for At<'cx, 'tcx> {
+#[extension(pub trait QueryNormalizeExt<'tcx>)]
+impl<'cx, 'tcx> At<'cx, 'tcx> {
     /// Normalize `value` in the context of the inference context,
     /// yielding a resulting type, or an error if `value` cannot be
     /// normalized. If you don't care about regions, you should prefer
@@ -49,6 +37,12 @@ impl<'cx, 'tcx> QueryNormalizeExt<'tcx> for At<'cx, 'tcx> {
     /// normalizing, but for now should be used only when we actually
     /// know that normalization will succeed, since error reporting
     /// and other details are still "under development".
+    ///
+    /// This normalization should *only* be used when the projection does not
+    /// have possible ambiguity or may not be well-formed.
+    ///
+    /// After codegen, when lifetimes do not matter, it is preferable to instead
+    /// use [`TyCtxt::normalize_erasing_regions`], which wraps this procedure.
     fn query_normalize<T>(self, value: T) -> Result<Normalized<'tcx, T>, NoSolution>
     where
         T: TypeFoldable<TyCtxt<'tcx>>,
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
index e9a592bdee7..f3b77d68922 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
@@ -33,20 +33,8 @@ enum Inserted<'tcx> {
     ShouldRecurseOn(DefId),
 }
 
-trait ChildrenExt<'tcx> {
-    fn insert_blindly(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId);
-    fn remove_existing(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId);
-
-    fn insert(
-        &mut self,
-        tcx: TyCtxt<'tcx>,
-        impl_def_id: DefId,
-        simplified_self: Option<SimplifiedType>,
-        overlap_mode: OverlapMode,
-    ) -> Result<Inserted<'tcx>, OverlapError<'tcx>>;
-}
-
-impl<'tcx> ChildrenExt<'tcx> for Children {
+#[extension(trait ChildrenExt<'tcx>)]
+impl<'tcx> Children {
     /// Insert an impl into this set of children without comparing to any existing impls.
     fn insert_blindly(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId) {
         let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().skip_binder();
@@ -247,22 +235,8 @@ where
     }
 }
 
-pub trait GraphExt<'tcx> {
-    /// Insert a local impl into the specialization graph. If an existing impl
-    /// conflicts with it (has overlap, but neither specializes the other),
-    /// information about the area of overlap is returned in the `Err`.
-    fn insert(
-        &mut self,
-        tcx: TyCtxt<'tcx>,
-        impl_def_id: DefId,
-        overlap_mode: OverlapMode,
-    ) -> Result<Option<FutureCompatOverlapError<'tcx>>, OverlapError<'tcx>>;
-
-    /// Insert cached metadata mapping from a child impl back to its parent.
-    fn record_impl_from_cstore(&mut self, tcx: TyCtxt<'tcx>, parent: DefId, child: DefId);
-}
-
-impl<'tcx> GraphExt<'tcx> for Graph {
+#[extension(pub trait GraphExt<'tcx>)]
+impl<'tcx> Graph {
     /// Insert a local impl into the specialization graph. If an existing impl
     /// conflicts with it (has overlap, but neither specializes the other),
     /// information about the area of overlap is returned in the `Err`.
diff --git a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs
index ed5d01d7048..2f428564ae7 100644
--- a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs
@@ -5,15 +5,8 @@ use rustc_middle::ty::{self, Ty};
 
 use crate::traits::{NormalizeExt, Obligation};
 
-pub trait StructurallyNormalizeExt<'tcx> {
-    fn structurally_normalize(
-        &self,
-        ty: Ty<'tcx>,
-        fulfill_cx: &mut dyn TraitEngine<'tcx>,
-    ) -> Result<Ty<'tcx>, Vec<FulfillmentError<'tcx>>>;
-}
-
-impl<'tcx> StructurallyNormalizeExt<'tcx> for At<'_, 'tcx> {
+#[extension(pub trait StructurallyNormalizeExt<'tcx>)]
+impl<'tcx> At<'_, 'tcx> {
     fn structurally_normalize(
         &self,
         ty: Ty<'tcx>,
diff --git a/configure b/configure
index 81e2001e4a5..e8627c9f0d5 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-script="$(dirname $0)"/src/bootstrap/configure.py
+script="$(dirname "$0")"/src/bootstrap/configure.py
 
 try() {
     cmd=$1
@@ -15,4 +15,4 @@ try python3 "$@"
 try python2.7 "$@"
 try python27 "$@"
 try python2 "$@"
-exec python $script "$@"
+exec python "$script" "$@"
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index fc6c1eab803..ce1876d5a2f 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -937,52 +937,68 @@ extern "rust-intrinsic" {
     #[rustc_nounwind]
     pub fn unreachable() -> !;
 
-    /// Informs the optimizer that a condition is always true.
-    /// If the condition is false, the behavior is undefined.
-    ///
-    /// No code is generated for this intrinsic, but the optimizer will try
-    /// to preserve it (and its condition) between passes, which may interfere
-    /// with optimization of surrounding code and reduce performance. It should
-    /// not be used if the invariant can be discovered by the optimizer on its
-    /// own, or if it does not enable any significant optimizations.
-    ///
-    /// This intrinsic does not have a stable counterpart.
-    #[rustc_const_stable(feature = "const_assume", since = "1.77.0")]
-    #[rustc_nounwind]
-    pub fn assume(b: bool);
+}
 
-    /// Hints to the compiler that branch condition is likely to be true.
-    /// Returns the value passed to it.
-    ///
-    /// Any use other than with `if` statements will probably not have an effect.
-    ///
-    /// Note that, unlike most intrinsics, this is safe to call;
-    /// it does not require an `unsafe` block.
-    /// Therefore, implementations must not require the user to uphold
-    /// any safety invariants.
-    ///
-    /// This intrinsic does not have a stable counterpart.
-    #[rustc_const_unstable(feature = "const_likely", issue = "none")]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn likely(b: bool) -> bool;
+/// Informs the optimizer that a condition is always true.
+/// If the condition is false, the behavior is undefined.
+///
+/// No code is generated for this intrinsic, but the optimizer will try
+/// to preserve it (and its condition) between passes, which may interfere
+/// with optimization of surrounding code and reduce performance. It should
+/// not be used if the invariant can be discovered by the optimizer on its
+/// own, or if it does not enable any significant optimizations.
+///
+/// This intrinsic does not have a stable counterpart.
+#[rustc_const_stable(feature = "const_assume", since = "1.77.0")]
+#[rustc_nounwind]
+#[unstable(feature = "core_intrinsics", issue = "none")]
+#[cfg_attr(not(bootstrap), rustc_intrinsic)]
+pub const unsafe fn assume(b: bool) {
+    if !b {
+        // SAFETY: the caller must guarantee the argument is never `false`
+        unsafe { unreachable() }
+    }
+}
 
-    /// Hints to the compiler that branch condition is likely to be false.
-    /// Returns the value passed to it.
-    ///
-    /// Any use other than with `if` statements will probably not have an effect.
-    ///
-    /// Note that, unlike most intrinsics, this is safe to call;
-    /// it does not require an `unsafe` block.
-    /// Therefore, implementations must not require the user to uphold
-    /// any safety invariants.
-    ///
-    /// This intrinsic does not have a stable counterpart.
-    #[rustc_const_unstable(feature = "const_likely", issue = "none")]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn unlikely(b: bool) -> bool;
+/// Hints to the compiler that branch condition is likely to be true.
+/// Returns the value passed to it.
+///
+/// Any use other than with `if` statements will probably not have an effect.
+///
+/// Note that, unlike most intrinsics, this is safe to call;
+/// it does not require an `unsafe` block.
+/// Therefore, implementations must not require the user to uphold
+/// any safety invariants.
+///
+/// This intrinsic does not have a stable counterpart.
+#[rustc_const_unstable(feature = "const_likely", issue = "none")]
+#[unstable(feature = "core_intrinsics", issue = "none")]
+#[cfg_attr(not(bootstrap), rustc_intrinsic)]
+#[rustc_nounwind]
+pub const fn likely(b: bool) -> bool {
+    b
+}
+
+/// Hints to the compiler that branch condition is likely to be false.
+/// Returns the value passed to it.
+///
+/// Any use other than with `if` statements will probably not have an effect.
+///
+/// Note that, unlike most intrinsics, this is safe to call;
+/// it does not require an `unsafe` block.
+/// Therefore, implementations must not require the user to uphold
+/// any safety invariants.
+///
+/// This intrinsic does not have a stable counterpart.
+#[rustc_const_unstable(feature = "const_likely", issue = "none")]
+#[unstable(feature = "core_intrinsics", issue = "none")]
+#[cfg_attr(not(bootstrap), rustc_intrinsic)]
+#[rustc_nounwind]
+pub const fn unlikely(b: bool) -> bool {
+    b
+}
 
+extern "rust-intrinsic" {
     /// Executes a breakpoint trap, for inspection by a debugger.
     ///
     /// This intrinsic does not have a stable counterpart.
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 1d8ac6aa043..c948337ba6c 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -3016,8 +3016,13 @@ impl<T> [T] {
     /// ```
     /// let mut v = [-5i32, 4, 2, -3, 1];
     ///
-    /// // Find the median
-    /// v.select_nth_unstable(2);
+    /// // Find the items less than or equal to the median, the median, and greater than or equal to
+    /// // the median.
+    /// let (lesser, median, greater) = v.select_nth_unstable(2);
+    ///
+    /// assert!(lesser == [-3, -5] || lesser == [-5, -3]);
+    /// assert_eq!(median, &mut 1);
+    /// assert!(greater == [4, 2] || greater == [2, 4]);
     ///
     /// // We are only guaranteed the slice will be one of the following, based on the way we sort
     /// // about the specified index.
@@ -3067,8 +3072,13 @@ impl<T> [T] {
     /// ```
     /// let mut v = [-5i32, 4, 2, -3, 1];
     ///
-    /// // Find the median as if the slice were sorted in descending order.
-    /// v.select_nth_unstable_by(2, |a, b| b.cmp(a));
+    /// // Find the items less than or equal to the median, the median, and greater than or equal to
+    /// // the median as if the slice were sorted in descending order.
+    /// let (lesser, median, greater) = v.select_nth_unstable_by(2, |a, b| b.cmp(a));
+    ///
+    /// assert!(lesser == [4, 2] || lesser == [2, 4]);
+    /// assert_eq!(median, &mut 1);
+    /// assert!(greater == [-3, -5] || greater == [-5, -3]);
     ///
     /// // We are only guaranteed the slice will be one of the following, based on the way we sort
     /// // about the specified index.
@@ -3122,8 +3132,13 @@ impl<T> [T] {
     /// ```
     /// let mut v = [-5i32, 4, 1, -3, 2];
     ///
-    /// // Return the median as if the array were sorted according to absolute value.
-    /// v.select_nth_unstable_by_key(2, |a| a.abs());
+    /// // Find the items less than or equal to the median, the median, and greater than or equal to
+    /// // the median as if the slice were sorted according to absolute value.
+    /// let (lesser, median, greater) = v.select_nth_unstable_by_key(2, |a| a.abs());
+    ///
+    /// assert!(lesser == [1, 2] || lesser == [2, 1]);
+    /// assert_eq!(median, &mut -3);
+    /// assert!(greater == [4, -5] || greater == [-5, 4]);
     ///
     /// // We are only guaranteed the slice will be one of the following, based on the way we sort
     /// // about the specified index.
diff --git a/library/std/src/sys/pal/windows/os.rs b/library/std/src/sys/pal/windows/os.rs
index 829dd5eb97a..73cb2db8b79 100644
--- a/library/std/src/sys/pal/windows/os.rs
+++ b/library/std/src/sys/pal/windows/os.rs
@@ -318,13 +318,33 @@ pub fn temp_dir() -> PathBuf {
     super::fill_utf16_buf(|buf, sz| unsafe { c::GetTempPath2W(sz, buf) }, super::os2path).unwrap()
 }
 
-#[cfg(not(target_vendor = "uwp"))]
+#[cfg(all(not(target_vendor = "uwp"), not(target_vendor = "win7")))]
+fn home_dir_crt() -> Option<PathBuf> {
+    unsafe {
+        // Defined in processthreadsapi.h.
+        const CURRENT_PROCESS_TOKEN: usize = -4_isize as usize;
+
+        super::fill_utf16_buf(
+            |buf, mut sz| {
+                match c::GetUserProfileDirectoryW(
+                    ptr::invalid_mut(CURRENT_PROCESS_TOKEN),
+                    buf,
+                    &mut sz,
+                ) {
+                    0 if api::get_last_error().code != c::ERROR_INSUFFICIENT_BUFFER => 0,
+                    0 => sz,
+                    _ => sz - 1, // sz includes the null terminator
+                }
+            },
+            super::os2path,
+        )
+        .ok()
+    }
+}
+
+#[cfg(target_vendor = "win7")]
 fn home_dir_crt() -> Option<PathBuf> {
     unsafe {
-        // The magic constant -4 can be used as the token passed to GetUserProfileDirectoryW below
-        // instead of us having to go through these multiple steps to get a token. However this is
-        // not implemented on Windows 7, only Windows 8 and up. When we drop support for Windows 7
-        // we can simplify this code. See #90144 for details.
         use crate::sys::handle::Handle;
 
         let me = c::GetCurrentProcess();
diff --git a/src/tools/miri/CONTRIBUTING.md b/src/tools/miri/CONTRIBUTING.md
index 7a49ff3372f..f2f3a642e0a 100644
--- a/src/tools/miri/CONTRIBUTING.md
+++ b/src/tools/miri/CONTRIBUTING.md
@@ -78,6 +78,8 @@ custom target file, you might have to set `MIRI_NO_STD=1`.
 base directory, e.g. `./miri test fail` will run all compile-fail tests). These filters are passed
 to `cargo test`, so for multiple filers you need to use `./miri test -- FILTER1 FILTER2`.
 
+#### Fine grained logging
+
 You can get a trace of which MIR statements are being executed by setting the
 `MIRI_LOG` environment variable.  For example:
 
@@ -94,9 +96,16 @@ stacked borrows implementation:
 MIRI_LOG=rustc_mir::interpret=info,miri::stacked_borrows ./miri run tests/pass/vec.rs
 ```
 
-In addition, you can set `MIRI_BACKTRACE=1` to get a backtrace of where an
+Note that you will only get `info`, `warn` or `error` messages if you use a prebuilt compiler.
+In order to get `debug` and `trace` level messages, you need to build miri with a locally built
+compiler that has `debug=true` set in `config.toml`.
+
+#### Debugging error messages
+
+You can set `MIRI_BACKTRACE=1` to get a backtrace of where an
 evaluation error was originally raised.
 
+
 ### UI testing
 
 We use ui-testing in Miri, meaning we generate `.stderr` and `.stdout` files for the output
diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock
index 8cd996d8564..87dc51bd612 100644
--- a/src/tools/miri/Cargo.lock
+++ b/src/tools/miri/Cargo.lock
@@ -274,19 +274,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
 
 [[package]]
-name = "env_logger"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece"
-dependencies = [
- "humantime",
- "is-terminal",
- "log",
- "regex",
- "termcolor",
-]
-
-[[package]]
 name = "errno"
 version = "0.3.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -340,18 +327,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
 
 [[package]]
-name = "hermit-abi"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
-
-[[package]]
-name = "humantime"
-version = "2.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
-
-[[package]]
 name = "indenter"
 version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -389,17 +364,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "is-terminal"
-version = "0.4.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455"
-dependencies = [
- "hermit-abi",
- "rustix",
- "windows-sys 0.52.0",
-]
-
-[[package]]
 name = "itoa"
 version = "1.0.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -529,14 +493,12 @@ dependencies = [
  "aes",
  "colored",
  "ctrlc",
- "env_logger",
  "getrandom",
  "jemalloc-sys",
  "lazy_static",
  "libc",
  "libffi",
  "libloading",
- "log",
  "measureme",
  "rand",
  "regex",
@@ -876,15 +838,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "termcolor"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449"
-dependencies = [
- "winapi-util",
-]
-
-[[package]]
 name = "thiserror"
 version = "1.0.56"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1035,15 +988,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
 
 [[package]]
-name = "winapi-util"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
-dependencies = [
- "winapi",
-]
-
-[[package]]
 name = "winapi-x86_64-pc-windows-gnu"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml
index a65010b055b..39122c847ce 100644
--- a/src/tools/miri/Cargo.toml
+++ b/src/tools/miri/Cargo.toml
@@ -19,8 +19,6 @@ doctest = false # and no doc tests
 
 [dependencies]
 getrandom = { version = "0.2", features = ["std"] }
-env_logger = "0.10"
-log = "0.4"
 rand = "0.8"
 smallvec = "1.7"
 aes = { version = "0.8.3", features = ["hazmat"] }
diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md
index 6695f123c78..60bf07b1736 100644
--- a/src/tools/miri/README.md
+++ b/src/tools/miri/README.md
@@ -108,11 +108,8 @@ assume the right toolchain is pinned via `rustup override set nightly` or
 
 Now you can run your project in Miri:
 
-1. Run `cargo clean` to eliminate any cached dependencies. Miri needs your
-   dependencies to be compiled the right way, that would not happen if they have
-   previously already been compiled.
-2. To run all tests in your project through Miri, use `cargo miri test`.
-3. If you have a binary project, you can run it through Miri using `cargo miri run`.
+- To run all tests in your project through Miri, use `cargo miri test`.
+- If you have a binary project, you can run it through Miri using `cargo miri run`.
 
 The first time you run Miri, it will perform some extra setup and install some
 dependencies. It will ask you for confirmation before installing anything.
diff --git a/src/tools/miri/ci/ci.sh b/src/tools/miri/ci/ci.sh
index 6bcc68ebf7c..9d2c3f362e6 100755
--- a/src/tools/miri/ci/ci.sh
+++ b/src/tools/miri/ci/ci.sh
@@ -121,8 +121,9 @@ case $HOST_TARGET in
     MIRI_TEST_TARGET=aarch64-apple-darwin run_tests
     MIRI_TEST_TARGET=i686-pc-windows-gnu run_tests
     # Some targets are only partially supported.
-    MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple pthread-threadname libc-getentropy libc-getrandom libc-misc libc-fs atomic env align
-    MIRI_TEST_TARGET=i686-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple pthread-threadname libc-getentropy libc-getrandom libc-misc libc-fs atomic env align
+    MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple pthread-threadname libc-getentropy libc-getrandom libc-misc libc-fs atomic env align num_cpus
+    MIRI_TEST_TARGET=i686-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple pthread-threadname libc-getentropy libc-getrandom libc-misc libc-fs atomic env align num_cpus
+
     MIRI_TEST_TARGET=aarch64-linux-android run_tests_minimal hello integer vec panic/panic
     MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal no_std integer strings wasm
     MIRI_TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std integer strings wasm
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index 6624672775f..ab6f899cd3a 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-dd2559e08e1530806740931037d6bb83ef956161
+4316d0c6252cb1f833e582dfa68adb98efd5ddfb
diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs
index 095ba173671..db4c4a28deb 100644
--- a/src/tools/miri/src/bin/miri.rs
+++ b/src/tools/miri/src/bin/miri.rs
@@ -5,7 +5,7 @@
     clippy::useless_format,
     clippy::field_reassign_with_default,
     rustc::diagnostic_outside_of_impl,
-    rustc::untranslatable_diagnostic,
+    rustc::untranslatable_diagnostic
 )]
 
 extern crate rustc_data_structures;
@@ -16,14 +16,14 @@ extern crate rustc_log;
 extern crate rustc_metadata;
 extern crate rustc_middle;
 extern crate rustc_session;
+#[macro_use]
+extern crate tracing;
 
 use std::env::{self, VarError};
 use std::num::NonZero;
 use std::path::PathBuf;
 use std::str::FromStr;
 
-use log::debug;
-
 use rustc_data_structures::sync::Lrc;
 use rustc_driver::Compilation;
 use rustc_hir::{self as hir, Node};
@@ -200,7 +200,7 @@ fn rustc_logger_config() -> rustc_log::LoggerConfig {
             // CTFE-related. Otherwise, we use it verbatim for `RUSTC_LOG`.
             // This way, if you set `MIRI_LOG=trace`, you get only the right parts of
             // rustc traced, but you can also do `MIRI_LOG=miri=trace,rustc_const_eval::interpret=debug`.
-            if log::Level::from_str(&var).is_ok() {
+            if tracing::Level::from_str(&var).is_ok() {
                 cfg.filter = Ok(format!(
                     "rustc_middle::mir::interpret={var},rustc_const_eval::interpret={var}"
                 ));
@@ -218,10 +218,6 @@ fn rustc_logger_config() -> rustc_log::LoggerConfig {
 }
 
 fn init_early_loggers(early_dcx: &EarlyDiagCtxt) {
-    // Note that our `extern crate log` is *not* the same as rustc's; as a result, we have to
-    // initialize them both, and we always initialize `miri`'s first.
-    let env = env_logger::Env::new().filter("MIRI_LOG").write_style("MIRI_LOG_STYLE");
-    env_logger::init_from_env(env);
     // Now for rustc. We only initialize `rustc` if the env var is set (so the user asked for it).
     // If it is not set, we avoid initializing now so that we can initialize later with our custom
     // settings, and *not* log anything for what happens before `miri` gets started.
diff --git a/src/tools/miri/src/borrow_tracker/mod.rs b/src/tools/miri/src/borrow_tracker/mod.rs
index 45240edea45..711323b51c2 100644
--- a/src/tools/miri/src/borrow_tracker/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/mod.rs
@@ -2,7 +2,6 @@ use std::cell::RefCell;
 use std::fmt;
 use std::num::NonZero;
 
-use log::trace;
 use smallvec::SmallVec;
 
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
index 7740d383ee3..0fe422180f7 100644
--- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
@@ -9,8 +9,6 @@ use std::cmp;
 use std::fmt::Write;
 use std::mem;
 
-use log::trace;
-
 use rustc_data_structures::fx::FxHashSet;
 use rustc_middle::mir::{Mutability, RetagKind};
 use rustc_middle::ty::{self, layout::HasParamEnv, Ty};
diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs
index 291807c25ee..712c26a9afd 100644
--- a/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs
+++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs
@@ -385,7 +385,7 @@ impl<'tcx> Stack {
             let upper = unique_range.end;
             for item in &mut self.borrows[lower..upper] {
                 if item.perm() == Permission::Unique {
-                    log::trace!("access: disabling item {:?}", item);
+                    trace!("access: disabling item {:?}", item);
                     visitor(*item)?;
                     item.set_permission(Permission::Disabled);
                     // Also update all copies of this item in the cache.
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
index 0945a5292bb..cc982865341 100644
--- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
@@ -1,5 +1,3 @@
-use log::trace;
-
 use rustc_target::abi::{Abi, Size};
 
 use crate::borrow_tracker::{AccessKind, GlobalState, GlobalStateInner, ProtectorKind};
diff --git a/src/tools/miri/src/concurrency/data_race.rs b/src/tools/miri/src/concurrency/data_race.rs
index 80d0402fc87..a280448ae05 100644
--- a/src/tools/miri/src/concurrency/data_race.rs
+++ b/src/tools/miri/src/concurrency/data_race.rs
@@ -466,7 +466,7 @@ impl MemoryCellClocks {
         index: VectorIdx,
         access_size: Size,
     ) -> Result<(), DataRace> {
-        log::trace!("Atomic read with vectors: {:#?} :: {:#?}", self, thread_clocks);
+        trace!("Atomic read with vectors: {:#?} :: {:#?}", self, thread_clocks);
         let atomic = self.atomic_access(thread_clocks, access_size)?;
         atomic.read_vector.set_at_index(&thread_clocks.clock, index);
         // Make sure the last non-atomic write and all non-atomic reads were before this access.
@@ -485,7 +485,7 @@ impl MemoryCellClocks {
         index: VectorIdx,
         access_size: Size,
     ) -> Result<(), DataRace> {
-        log::trace!("Atomic write with vectors: {:#?} :: {:#?}", self, thread_clocks);
+        trace!("Atomic write with vectors: {:#?} :: {:#?}", self, thread_clocks);
         let atomic = self.atomic_access(thread_clocks, access_size)?;
         atomic.write_vector.set_at_index(&thread_clocks.clock, index);
         // Make sure the last non-atomic write and all non-atomic reads were before this access.
@@ -504,7 +504,7 @@ impl MemoryCellClocks {
         index: VectorIdx,
         current_span: Span,
     ) -> Result<(), DataRace> {
-        log::trace!("Unsynchronized read with vectors: {:#?} :: {:#?}", self, thread_clocks);
+        trace!("Unsynchronized read with vectors: {:#?} :: {:#?}", self, thread_clocks);
         if !current_span.is_dummy() {
             thread_clocks.clock[index].span = current_span;
         }
@@ -533,7 +533,7 @@ impl MemoryCellClocks {
         write_type: NaWriteType,
         current_span: Span,
     ) -> Result<(), DataRace> {
-        log::trace!("Unsynchronized write with vectors: {:#?} :: {:#?}", self, thread_clocks);
+        trace!("Unsynchronized write with vectors: {:#?} :: {:#?}", self, thread_clocks);
         if !current_span.is_dummy() {
             thread_clocks.clock[index].span = current_span;
         }
@@ -743,7 +743,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
                 &this.machine.threads,
                 current_span,
                 |index, mut clocks| {
-                    log::trace!("Atomic fence on {:?} with ordering {:?}", index, atomic);
+                    trace!("Atomic fence on {:?} with ordering {:?}", index, atomic);
 
                     // Apply data-race detection for the current fences
                     // this treats AcqRel and SeqCst as the same as an acquire
@@ -841,7 +841,7 @@ impl VClockAlloc {
     // Find an index, if one exists where the value
     // in `l` is greater than the value in `r`.
     fn find_gt_index(l: &VClock, r: &VClock) -> Option<VectorIdx> {
-        log::trace!("Find index where not {:?} <= {:?}", l, r);
+        trace!("Find index where not {:?} <= {:?}", l, r);
         let l_slice = l.as_slice();
         let r_slice = r.as_slice();
         l_slice
@@ -1270,7 +1270,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
                 // Load and log the atomic operation.
                 // Note that atomic loads are possible even from read-only allocations, so `get_alloc_extra_mut` is not an option.
                 let alloc_meta = this.get_alloc_extra(alloc_id)?.data_race.as_ref().unwrap();
-                log::trace!(
+                trace!(
                     "Atomic op({}) with ordering {:?} on {:?} (size={})",
                     access.description(),
                     &atomic,
@@ -1311,11 +1311,11 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
                 )?;
 
                 // Log changes to atomic memory.
-                if log::log_enabled!(log::Level::Trace) {
+                if tracing::enabled!(tracing::Level::TRACE) {
                     for (_offset, mem_clocks) in
                         alloc_meta.alloc_ranges.borrow().iter(base_offset, size)
                     {
-                        log::trace!(
+                        trace!(
                             "Updated atomic memory({:?}, size={}) to {:#?}",
                             place.ptr(),
                             size.bytes(),
@@ -1530,7 +1530,7 @@ impl GlobalState {
             vector_info.push(thread)
         };
 
-        log::trace!("Creating thread = {:?} with vector index = {:?}", thread, created_index);
+        trace!("Creating thread = {:?} with vector index = {:?}", thread, created_index);
 
         // Mark the chosen vector index as in use by the thread.
         thread_info[thread].vector_index = Some(created_index);
diff --git a/src/tools/miri/src/concurrency/sync.rs b/src/tools/miri/src/concurrency/sync.rs
index b948ecb8345..956a02ded0f 100644
--- a/src/tools/miri/src/concurrency/sync.rs
+++ b/src/tools/miri/src/concurrency/sync.rs
@@ -1,8 +1,6 @@
 use std::collections::{hash_map::Entry, VecDeque};
 use std::ops::Not;
 
-use log::trace;
-
 use rustc_data_structures::fx::FxHashMap;
 use rustc_index::{Idx, IndexVec};
 use rustc_middle::ty::layout::TyAndLayout;
@@ -71,7 +69,7 @@ struct Mutex {
     lock_count: usize,
     /// The queue of threads waiting for this mutex.
     queue: VecDeque<ThreadId>,
-    /// Data race handle, this tracks the happens-before
+    /// Data race handle. This tracks the happens-before
     /// relationship between each mutex access. It is
     /// released to during unlock and acquired from during
     /// locking, and therefore stores the clock of the last
@@ -93,7 +91,7 @@ struct RwLock {
     writer_queue: VecDeque<ThreadId>,
     /// The queue of reader threads waiting for this lock.
     reader_queue: VecDeque<ThreadId>,
-    /// Data race handle for writers, tracks the happens-before
+    /// Data race handle for writers. Tracks the happens-before
     /// ordering between each write access to a rwlock and is updated
     /// after a sequence of concurrent readers to track the happens-
     /// before ordering between the set of previous readers and
@@ -102,7 +100,7 @@ struct RwLock {
     /// lock or the joined clock of the set of last threads to release
     /// shared reader locks.
     data_race: VClock,
-    /// Data race handle for readers, this is temporary storage
+    /// Data race handle for readers. This is temporary storage
     /// for the combined happens-before ordering for between all
     /// concurrent readers and the next writer, and the value
     /// is stored to the main data_race variable once all
@@ -111,6 +109,7 @@ struct RwLock {
     /// must load the clock of the last write and must not
     /// add happens-before orderings between shared reader
     /// locks.
+    /// This is only relevant when there is an active reader.
     data_race_reader: VClock,
 }
 
@@ -486,6 +485,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             Entry::Vacant(_) => return false, // we did not even own this lock
         }
         if let Some(data_race) = &this.machine.data_race {
+            // Add this to the shared-release clock of all concurrent readers.
             data_race.validate_lock_release_shared(
                 &mut rwlock.data_race_reader,
                 reader,
@@ -540,20 +540,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             }
             rwlock.writer = None;
             trace!("rwlock_writer_unlock: {:?} unlocked by {:?}", id, expected_writer);
-            // Release memory to both reader and writer vector clocks
-            //  since this writer happens-before both the union of readers once they are finished
-            //  and the next writer
+            // Release memory to next lock holder.
             if let Some(data_race) = &this.machine.data_race {
                 data_race.validate_lock_release(
                     &mut rwlock.data_race,
                     current_writer,
                     current_span,
                 );
-                data_race.validate_lock_release(
-                    &mut rwlock.data_race_reader,
-                    current_writer,
-                    current_span,
-                );
             }
             // The thread was a writer.
             //
diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs
index 754cfa4d2a8..64e1f3c5b55 100644
--- a/src/tools/miri/src/concurrency/thread.rs
+++ b/src/tools/miri/src/concurrency/thread.rs
@@ -8,7 +8,6 @@ use std::task::Poll;
 use std::time::{Duration, SystemTime};
 
 use either::Either;
-use log::trace;
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def_id::DefId;
diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs
index 19b29a41819..d47f446716b 100644
--- a/src/tools/miri/src/diagnostics.rs
+++ b/src/tools/miri/src/diagnostics.rs
@@ -1,8 +1,6 @@
 use std::fmt::{self, Write};
 use std::num::NonZero;
 
-use log::trace;
-
 use rustc_errors::{DiagnosticBuilder, DiagnosticMessage, Level};
 use rustc_span::{SpanData, Symbol, DUMMY_SP};
 use rustc_target::abi::{Align, Size};
@@ -102,10 +100,7 @@ impl MachineStopType for TerminationInfo {
     }
     fn add_args(
         self: Box<Self>,
-        _: &mut dyn FnMut(
-            std::borrow::Cow<'static, str>,
-            rustc_errors::DiagnosticArgValue,
-        ),
+        _: &mut dyn FnMut(std::borrow::Cow<'static, str>, rustc_errors::DiagnosticArgValue),
     ) {
     }
 }
@@ -290,7 +285,10 @@ pub fn report_error<'tcx, 'mir>(
                 ) =>
             {
                 ecx.handle_ice(); // print interpreter backtrace
-                bug!("This validation error should be impossible in Miri: {}", format_interp_error(ecx.tcx.dcx(), e));
+                bug!(
+                    "This validation error should be impossible in Miri: {}",
+                    format_interp_error(ecx.tcx.dcx(), e)
+                );
             }
             UndefinedBehavior(_) => "Undefined Behavior",
             ResourceExhaustion(_) => "resource exhaustion",
@@ -304,7 +302,10 @@ pub fn report_error<'tcx, 'mir>(
             ) => "post-monomorphization error",
             _ => {
                 ecx.handle_ice(); // print interpreter backtrace
-                bug!("This error should be impossible in Miri: {}", format_interp_error(ecx.tcx.dcx(), e));
+                bug!(
+                    "This error should be impossible in Miri: {}",
+                    format_interp_error(ecx.tcx.dcx(), e)
+                );
             }
         };
         #[rustfmt::skip]
diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs
index 6095b8842eb..9bab9488e37 100644
--- a/src/tools/miri/src/eval.rs
+++ b/src/tools/miri/src/eval.rs
@@ -7,9 +7,6 @@ use std::path::PathBuf;
 use std::task::Poll;
 use std::thread;
 
-use log::info;
-use rustc_middle::ty::Ty;
-
 use crate::concurrency::thread::TlsAllocAction;
 use crate::diagnostics::report_leaks;
 use rustc_data_structures::fx::FxHashSet;
@@ -18,7 +15,7 @@ use rustc_hir::def_id::DefId;
 use rustc_middle::ty::{
     self,
     layout::{LayoutCx, LayoutOf},
-    TyCtxt,
+    Ty, TyCtxt,
 };
 use rustc_target::spec::abi::Abi;
 
diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs
index 3cee4df5885..d9b4363d604 100644
--- a/src/tools/miri/src/helpers.rs
+++ b/src/tools/miri/src/helpers.rs
@@ -3,8 +3,6 @@ use std::iter;
 use std::num::NonZero;
 use std::time::Duration;
 
-use log::trace;
-
 use rustc_apfloat::ieee::{Double, Single};
 use rustc_apfloat::Float;
 use rustc_hir::def::{DefKind, Namespace};
diff --git a/src/tools/miri/src/intptrcast.rs b/src/tools/miri/src/intptrcast.rs
index 68c9a7660eb..3fe127f9732 100644
--- a/src/tools/miri/src/intptrcast.rs
+++ b/src/tools/miri/src/intptrcast.rs
@@ -2,7 +2,6 @@ use std::cell::RefCell;
 use std::cmp::max;
 use std::collections::hash_map::Entry;
 
-use log::trace;
 use rand::Rng;
 
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs
index 305c71fb0f9..c567949102f 100644
--- a/src/tools/miri/src/lib.rs
+++ b/src/tools/miri/src/lib.rs
@@ -63,6 +63,8 @@ extern crate rustc_middle;
 extern crate rustc_session;
 extern crate rustc_span;
 extern crate rustc_target;
+#[macro_use]
+extern crate tracing;
 
 // Necessary to pull in object code as the rest of the rustc crates are shipped only as rmeta
 // files.
diff --git a/src/tools/miri/src/operator.rs b/src/tools/miri/src/operator.rs
index 6f19dead2e9..d99be39177b 100644
--- a/src/tools/miri/src/operator.rs
+++ b/src/tools/miri/src/operator.rs
@@ -1,7 +1,5 @@
 use std::iter;
 
-use log::trace;
-
 use rand::{seq::IteratorRandom, Rng};
 use rustc_apfloat::{Float, FloatConvert};
 use rustc_middle::mir;
diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs
index bf90d1468bb..0645c1f176e 100644
--- a/src/tools/miri/src/shims/foreign_items.rs
+++ b/src/tools/miri/src/shims/foreign_items.rs
@@ -1,7 +1,5 @@
 use std::{collections::hash_map::Entry, io::Write, iter, path::Path};
 
-use log::trace;
-
 use rustc_apfloat::Float;
 use rustc_ast::expand::allocator::AllocatorKind;
 use rustc_hir::{
diff --git a/src/tools/miri/src/shims/intrinsics/mod.rs b/src/tools/miri/src/shims/intrinsics/mod.rs
index df2761bfaf4..602e8b31b01 100644
--- a/src/tools/miri/src/shims/intrinsics/mod.rs
+++ b/src/tools/miri/src/shims/intrinsics/mod.rs
@@ -3,8 +3,6 @@ mod simd;
 
 use std::iter;
 
-use log::trace;
-
 use rand::Rng;
 use rustc_apfloat::{Float, Round};
 use rustc_middle::ty::layout::LayoutOf;
diff --git a/src/tools/miri/src/shims/panic.rs b/src/tools/miri/src/shims/panic.rs
index 28652c25c24..4c054d8dc8a 100644
--- a/src/tools/miri/src/shims/panic.rs
+++ b/src/tools/miri/src/shims/panic.rs
@@ -11,8 +11,6 @@
 //!   gets popped *during unwinding*, we take the panic payload and store it according to the extra
 //!   metadata we remembered when pushing said frame.
 
-use log::trace;
-
 use rustc_ast::Mutability;
 use rustc_middle::{mir, ty};
 use rustc_span::Symbol;
diff --git a/src/tools/miri/src/shims/tls.rs b/src/tools/miri/src/shims/tls.rs
index b319516c25b..84c1feb88e9 100644
--- a/src/tools/miri/src/shims/tls.rs
+++ b/src/tools/miri/src/shims/tls.rs
@@ -4,8 +4,6 @@ use std::collections::btree_map::Entry as BTreeEntry;
 use std::collections::BTreeMap;
 use std::task::Poll;
 
-use log::trace;
-
 use rustc_middle::ty;
 use rustc_target::abi::{HasDataLayout, Size};
 use rustc_target::spec::abi::Abi;
diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs
index 35036ce078d..b5cd18396a2 100644
--- a/src/tools/miri/src/shims/unix/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/foreign_items.rs
@@ -1,8 +1,6 @@
 use std::ffi::OsStr;
 use std::str;
 
-use log::trace;
-
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_span::Symbol;
 use rustc_target::abi::{Align, Size};
@@ -262,6 +260,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
 
             "mmap" => {
                 let [addr, length, prot, flags, fd, offset] = this.check_shim(abi, Abi::C {unwind: false}, link_name, args)?;
+                let offset = this.read_scalar(offset)?.to_int(this.libc_ty_layout("off_t").size)?;
                 let ptr = this.mmap(addr, length, prot, flags, fd, offset)?;
                 this.write_scalar(ptr, dest)?;
             }
@@ -711,6 +710,25 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 }
             }
 
+            "sched_getaffinity" => {
+                // FreeBSD supports it as well since 13.1 (as a wrapper of cpuset_getaffinity)
+                if !matches!(&*this.tcx.sess.target.os, "linux" | "freebsd") {
+                    throw_unsup_format!(
+                        "`sched_getaffinity` is not supported on {}",
+                        this.tcx.sess.target.os
+                    );
+                }
+                let [pid, cpusetsize, mask] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                this.read_scalar(pid)?.to_i32()?;
+                this.read_target_usize(cpusetsize)?;
+                this.deref_pointer_as(mask, this.libc_ty_layout("cpu_set_t"))?;
+                // FIXME: we just return an error; `num_cpus` then falls back to `sysconf`.
+                let einval = this.eval_libc("EINVAL");
+                this.set_last_error(einval)?;
+                this.write_scalar(Scalar::from_i32(-1), dest)?;
+            }
+
             // Platform-specific shims
             _ => {
                 let target_os = &*this.tcx.sess.target.os;
diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs
index 53f975baa89..b141ca4a019 100644
--- a/src/tools/miri/src/shims/unix/fs.rs
+++ b/src/tools/miri/src/shims/unix/fs.rs
@@ -8,8 +8,6 @@ use std::io::{self, ErrorKind, IsTerminal, Read, Seek, SeekFrom, Write};
 use std::path::{Path, PathBuf};
 use std::time::SystemTime;
 
-use log::trace;
-
 use rustc_data_structures::fx::FxHashMap;
 use rustc_middle::ty::TyCtxt;
 use rustc_target::abi::Size;
diff --git a/src/tools/miri/src/shims/unix/linux/foreign_items.rs b/src/tools/miri/src/shims/unix/linux/foreign_items.rs
index 6937e0f089e..b9215129674 100644
--- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs
@@ -9,6 +9,7 @@ use shims::unix::fs::EvalContextExt as _;
 use shims::unix::linux::fd::EvalContextExt as _;
 use shims::unix::linux::mem::EvalContextExt as _;
 use shims::unix::linux::sync::futex;
+use shims::unix::mem::EvalContextExt as _;
 use shims::unix::sync::EvalContextExt as _;
 use shims::unix::thread::EvalContextExt as _;
 
@@ -43,6 +44,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 let result = this.linux_readdir64(dirp)?;
                 this.write_scalar(result, dest)?;
             }
+            "mmap64" => {
+                let [addr, length, prot, flags, fd, offset] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let offset = this.read_scalar(offset)?.to_i64()?;
+                let ptr = this.mmap(addr, length, prot, flags, fd, offset.into())?;
+                this.write_scalar(ptr, dest)?;
+            }
+
             // Linux-only
             "sync_file_range" => {
                 let [fd, offset, nbytes, flags] =
@@ -197,17 +206,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                     this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
                 getrandom(this, ptr, len, flags, dest)?;
             }
-            "sched_getaffinity" => {
-                let [pid, cpusetsize, mask] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
-                this.read_scalar(pid)?.to_i32()?;
-                this.read_target_usize(cpusetsize)?;
-                this.deref_pointer_as(mask, this.libc_ty_layout("cpu_set_t"))?;
-                // FIXME: we just return an error; `num_cpus` then falls back to `sysconf`.
-                let einval = this.eval_libc("EINVAL");
-                this.set_last_error(einval)?;
-                this.write_scalar(Scalar::from_i32(-1), dest)?;
-            }
 
             // Incomplete shims that we "stub out" just to get pre-main initialization code to work.
             // These shims are enabled only when the caller is in the standard library.
diff --git a/src/tools/miri/src/shims/unix/mem.rs b/src/tools/miri/src/shims/unix/mem.rs
index d7dc17fa89f..d3470893dbb 100644
--- a/src/tools/miri/src/shims/unix/mem.rs
+++ b/src/tools/miri/src/shims/unix/mem.rs
@@ -26,7 +26,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         prot: &OpTy<'tcx, Provenance>,
         flags: &OpTy<'tcx, Provenance>,
         fd: &OpTy<'tcx, Provenance>,
-        offset: &OpTy<'tcx, Provenance>,
+        offset: i128,
     ) -> InterpResult<'tcx, Scalar<Provenance>> {
         let this = self.eval_context_mut();
 
@@ -36,7 +36,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         let prot = this.read_scalar(prot)?.to_i32()?;
         let flags = this.read_scalar(flags)?.to_i32()?;
         let fd = this.read_scalar(fd)?.to_i32()?;
-        let offset = this.read_target_usize(offset)?;
 
         let map_private = this.eval_libc_i32("MAP_PRIVATE");
         let map_anonymous = this.eval_libc_i32("MAP_ANONYMOUS");
diff --git a/src/tools/miri/src/shims/x86/avx.rs b/src/tools/miri/src/shims/x86/avx.rs
new file mode 100644
index 00000000000..65de1607595
--- /dev/null
+++ b/src/tools/miri/src/shims/x86/avx.rs
@@ -0,0 +1,417 @@
+use rustc_apfloat::{ieee::Double, ieee::Single};
+use rustc_middle::mir;
+use rustc_middle::ty::layout::LayoutOf as _;
+use rustc_middle::ty::Ty;
+use rustc_span::Symbol;
+use rustc_target::spec::abi::Abi;
+
+use super::{
+    bin_op_simd_float_all, conditional_dot_product, convert_float_to_int, horizontal_bin_op,
+    round_all, test_bits_masked, test_high_bits_masked, unary_op_ps, FloatBinOp, FloatUnaryOp,
+};
+use crate::*;
+use shims::foreign_items::EmulateForeignItemResult;
+
+impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
+pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
+    crate::MiriInterpCxExt<'mir, 'tcx>
+{
+    fn emulate_x86_avx_intrinsic(
+        &mut self,
+        link_name: Symbol,
+        abi: Abi,
+        args: &[OpTy<'tcx, Provenance>],
+        dest: &PlaceTy<'tcx, Provenance>,
+    ) -> InterpResult<'tcx, EmulateForeignItemResult> {
+        let this = self.eval_context_mut();
+        this.expect_target_feature_for_intrinsic(link_name, "avx")?;
+        // Prefix should have already been checked.
+        let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.avx.").unwrap();
+
+        match unprefixed_name {
+            // Used to implement _mm256_min_ps and _mm256_max_ps functions.
+            // Note that the semantics are a bit different from Rust simd_min
+            // and simd_max intrinsics regarding handling of NaN and -0.0: Rust
+            // matches the IEEE min/max operations, while x86 has different
+            // semantics.
+            "min.ps.256" | "max.ps.256" => {
+                let [left, right] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+
+                let which = match unprefixed_name {
+                    "min.ps.256" => FloatBinOp::Min,
+                    "max.ps.256" => FloatBinOp::Max,
+                    _ => unreachable!(),
+                };
+
+                bin_op_simd_float_all::<Single>(this, which, left, right, dest)?;
+            }
+            // Used to implement _mm256_min_pd and _mm256_max_pd functions.
+            "min.pd.256" | "max.pd.256" => {
+                let [left, right] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+
+                let which = match unprefixed_name {
+                    "min.pd.256" => FloatBinOp::Min,
+                    "max.pd.256" => FloatBinOp::Max,
+                    _ => unreachable!(),
+                };
+
+                bin_op_simd_float_all::<Double>(this, which, left, right, dest)?;
+            }
+            // Used to implement the _mm256_round_ps function.
+            // Rounds the elements of `op` according to `rounding`.
+            "round.ps.256" => {
+                let [op, rounding] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+
+                round_all::<rustc_apfloat::ieee::Single>(this, op, rounding, dest)?;
+            }
+            // Used to implement the _mm256_round_pd function.
+            // Rounds the elements of `op` according to `rounding`.
+            "round.pd.256" => {
+                let [op, rounding] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+
+                round_all::<rustc_apfloat::ieee::Double>(this, op, rounding, dest)?;
+            }
+            // Used to implement _mm256_{sqrt,rcp,rsqrt}_ps functions.
+            // Performs the operations on all components of `op`.
+            "sqrt.ps.256" | "rcp.ps.256" | "rsqrt.ps.256" => {
+                let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+
+                let which = match unprefixed_name {
+                    "sqrt.ps.256" => FloatUnaryOp::Sqrt,
+                    "rcp.ps.256" => FloatUnaryOp::Rcp,
+                    "rsqrt.ps.256" => FloatUnaryOp::Rsqrt,
+                    _ => unreachable!(),
+                };
+
+                unary_op_ps(this, which, op, dest)?;
+            }
+            // Used to implement the _mm256_dp_ps function.
+            "dp.ps.256" => {
+                let [left, right, imm] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+
+                conditional_dot_product(this, left, right, imm, dest)?;
+            }
+            // Used to implement the _mm256_h{add,sub}_p{s,d} functions.
+            // Horizontally add/subtract adjacent floating point values
+            // in `left` and `right`.
+            "hadd.ps.256" | "hadd.pd.256" | "hsub.ps.256" | "hsub.pd.256" => {
+                let [left, right] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+
+                let which = match unprefixed_name {
+                    "hadd.ps.256" | "hadd.pd.256" => mir::BinOp::Add,
+                    "hsub.ps.256" | "hsub.pd.256" => mir::BinOp::Sub,
+                    _ => unreachable!(),
+                };
+
+                horizontal_bin_op(this, which, /*saturating*/ false, left, right, dest)?;
+            }
+            // Used to implement the _mm256_cmp_ps function.
+            // Performs a comparison operation on each component of `left`
+            // and `right`. For each component, returns 0 if false or u32::MAX
+            // if true.
+            "cmp.ps.256" => {
+                let [left, right, imm] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+
+                let which =
+                    FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?;
+
+                bin_op_simd_float_all::<Single>(this, which, left, right, dest)?;
+            }
+            // Used to implement the _mm256_cmp_pd function.
+            // Performs a comparison operation on each component of `left`
+            // and `right`. For each component, returns 0 if false or u64::MAX
+            // if true.
+            "cmp.pd.256" => {
+                let [left, right, imm] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+
+                let which =
+                    FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?;
+
+                bin_op_simd_float_all::<Double>(this, which, left, right, dest)?;
+            }
+            // Used to implement the _mm256_cvtps_epi32, _mm256_cvttps_epi32, _mm256_cvtpd_epi32
+            // and _mm256_cvttpd_epi32 functions.
+            // Converts packed f32/f64 to packed i32.
+            "cvt.ps2dq.256" | "cvtt.ps2dq.256" | "cvt.pd2dq.256" | "cvtt.pd2dq.256" => {
+                let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+
+                let rnd = match unprefixed_name {
+                    // "current SSE rounding mode", assume nearest
+                    "cvt.ps2dq.256" | "cvt.pd2dq.256" => rustc_apfloat::Round::NearestTiesToEven,
+                    // always truncate
+                    "cvtt.ps2dq.256" | "cvtt.pd2dq.256" => rustc_apfloat::Round::TowardZero,
+                    _ => unreachable!(),
+                };
+
+                convert_float_to_int(this, op, rnd, dest)?;
+            }
+            // Used to implement the _mm_permutevar_ps and _mm256_permutevar_ps functions.
+            // Shuffles 32-bit floats from `data` using `control` as control. Each 128-bit
+            // chunk is shuffled independently: this means that we view the vector as a
+            // sequence of 4-element arrays, and we shuffle each of these arrays, where
+            // `control` determines which element of the current `data` array is written.
+            "vpermilvar.ps" | "vpermilvar.ps.256" => {
+                let [data, control] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+
+                let (data, data_len) = this.operand_to_simd(data)?;
+                let (control, control_len) = this.operand_to_simd(control)?;
+                let (dest, dest_len) = this.place_to_simd(dest)?;
+
+                assert_eq!(dest_len, data_len);
+                assert_eq!(dest_len, control_len);
+
+                for i in 0..dest_len {
+                    let control = this.project_index(&control, i)?;
+
+                    // Each 128-bit chunk is shuffled independently. Since each chunk contains
+                    // four 32-bit elements, only two bits from `control` are used. To read the
+                    // value from the current chunk, add the destination index truncated to a multiple
+                    // of 4.
+                    let chunk_base = i & !0b11;
+                    let src_i = u64::from(this.read_scalar(&control)?.to_u32()? & 0b11)
+                        .checked_add(chunk_base)
+                        .unwrap();
+
+                    this.copy_op(
+                        &this.project_index(&data, src_i)?,
+                        &this.project_index(&dest, i)?,
+                    )?;
+                }
+            }
+            // Used to implement the _mm_permutevar_pd and _mm256_permutevar_pd functions.
+            // Shuffles 64-bit floats from `left` using `right` as control. Each 128-bit
+            // chunk is shuffled independently: this means that we view the vector as
+            // a sequence of 2-element arrays, and we shuffle each of these arrays,
+            // where `right` determines which element of the current `left` array is
+            // written.
+            "vpermilvar.pd" | "vpermilvar.pd.256" => {
+                let [data, control] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+
+                let (data, data_len) = this.operand_to_simd(data)?;
+                let (control, control_len) = this.operand_to_simd(control)?;
+                let (dest, dest_len) = this.place_to_simd(dest)?;
+
+                assert_eq!(dest_len, data_len);
+                assert_eq!(dest_len, control_len);
+
+                for i in 0..dest_len {
+                    let control = this.project_index(&control, i)?;
+
+                    // Each 128-bit chunk is shuffled independently. Since each chunk contains
+                    // two 64-bit elements, only the second bit from `control` is used (yes, the
+                    // second instead of the first, ask Intel). To read the value from the current
+                    // chunk, add the destination index truncated to a multiple of 2.
+                    let chunk_base = i & !1;
+                    let src_i = ((this.read_scalar(&control)?.to_u64()? >> 1) & 1)
+                        .checked_add(chunk_base)
+                        .unwrap();
+
+                    this.copy_op(
+                        &this.project_index(&data, src_i)?,
+                        &this.project_index(&dest, i)?,
+                    )?;
+                }
+            }
+            // Used to implement the _mm256_permute2f128_ps, _mm256_permute2f128_pd and
+            // _mm256_permute2f128_si256 functions. Regardless of the suffix in the name
+            // thay all can be considered to operate on vectors of 128-bit elements.
+            // For each 128-bit element of `dest`, copies one from `left`, `right` or
+            // zero, according to `imm`.
+            "vperm2f128.ps.256" | "vperm2f128.pd.256" | "vperm2f128.si.256" => {
+                let [left, right, imm] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+
+                assert_eq!(dest.layout, left.layout);
+                assert_eq!(dest.layout, right.layout);
+                assert_eq!(dest.layout.size.bits(), 256);
+
+                // Transmute to `[u128; 2]` to process each 128-bit chunk independently.
+                let u128x2_layout =
+                    this.layout_of(Ty::new_array(this.tcx.tcx, this.tcx.types.u128, 2))?;
+                let left = left.transmute(u128x2_layout, this)?;
+                let right = right.transmute(u128x2_layout, this)?;
+                let dest = dest.transmute(u128x2_layout, this)?;
+
+                let imm = this.read_scalar(imm)?.to_u8()?;
+
+                for i in 0..2 {
+                    let dest = this.project_index(&dest, i)?;
+
+                    let imm = match i {
+                        0 => imm & 0xF,
+                        1 => imm >> 4,
+                        _ => unreachable!(),
+                    };
+                    if imm & 0b100 != 0 {
+                        this.write_scalar(Scalar::from_u128(0), &dest)?;
+                    } else {
+                        let src = match imm {
+                            0b00 => this.project_index(&left, 0)?,
+                            0b01 => this.project_index(&left, 1)?,
+                            0b10 => this.project_index(&right, 0)?,
+                            0b11 => this.project_index(&right, 1)?,
+                            _ => unreachable!(),
+                        };
+                        this.copy_op(&src, &dest)?;
+                    }
+                }
+            }
+            // Used to implement the _mm_maskload_ps, _mm_maskload_pd, _mm256_maskload_ps
+            // and _mm256_maskload_pd functions.
+            // For the element `i`, if the high bit of the `i`-th element of `mask`
+            // is one, it is loaded from `ptr.wrapping_add(i)`, otherwise zero is
+            // loaded.
+            "maskload.ps" | "maskload.pd" | "maskload.ps.256" | "maskload.pd.256" => {
+                let [ptr, mask] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+
+                mask_load(this, ptr, mask, dest)?;
+            }
+            // Used to implement the _mm_maskstore_ps, _mm_maskstore_pd, _mm256_maskstore_ps
+            // and _mm256_maskstore_pd functions.
+            // For the element `i`, if the high bit of the element `i`-th of `mask`
+            // is one, it is stored into `ptr.wapping_add(i)`.
+            // Unlike SSE2's _mm_maskmoveu_si128, these are not non-temporal stores.
+            "maskstore.ps" | "maskstore.pd" | "maskstore.ps.256" | "maskstore.pd.256" => {
+                let [ptr, mask, value] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+
+                mask_store(this, ptr, mask, value)?;
+            }
+            // Used to implement the _mm256_lddqu_si256 function.
+            // Reads a 256-bit vector from an unaligned pointer. This intrinsic
+            // is expected to perform better than a regular unaligned read when
+            // the data crosses a cache line, but for Miri this is just a regular
+            // unaligned read.
+            "ldu.dq.256" => {
+                let [src_ptr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let src_ptr = this.read_pointer(src_ptr)?;
+                let dest = dest.force_mplace(this)?;
+
+                // Unaligned copy, which is what we want.
+                this.mem_copy(src_ptr, dest.ptr(), dest.layout.size, /*nonoverlapping*/ true)?;
+            }
+            // Used to implement the _mm256_testz_si256, _mm256_testc_si256 and
+            // _mm256_testnzc_si256 functions.
+            // Tests `op & mask == 0`, `op & mask == mask` or
+            // `op & mask != 0 && op & mask != mask`
+            "ptestz.256" | "ptestc.256" | "ptestnzc.256" => {
+                let [op, mask] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+
+                let (all_zero, masked_set) = test_bits_masked(this, op, mask)?;
+                let res = match unprefixed_name {
+                    "ptestz.256" => all_zero,
+                    "ptestc.256" => masked_set,
+                    "ptestnzc.256" => !all_zero && !masked_set,
+                    _ => unreachable!(),
+                };
+
+                this.write_scalar(Scalar::from_i32(res.into()), dest)?;
+            }
+            // Used to implement the _mm256_testz_pd, _mm256_testc_pd, _mm256_testnzc_pd
+            // _mm_testz_pd, _mm_testc_pd, _mm_testnzc_pd, _mm256_testz_ps,
+            // _mm256_testc_ps, _mm256_testnzc_ps, _mm_testz_ps, _mm_testc_ps and
+            // _mm_testnzc_ps functions.
+            // Calculates two booleans:
+            // `direct`, which is true when the highest bit of each element of `op & mask` is zero.
+            // `negated`, which is true when the highest bit of each element of `!op & mask` is zero.
+            // Return `direct` (testz), `negated` (testc) or `!direct & !negated` (testnzc)
+            "vtestz.pd.256" | "vtestc.pd.256" | "vtestnzc.pd.256" | "vtestz.pd" | "vtestc.pd"
+            | "vtestnzc.pd" | "vtestz.ps.256" | "vtestc.ps.256" | "vtestnzc.ps.256"
+            | "vtestz.ps" | "vtestc.ps" | "vtestnzc.ps" => {
+                let [op, mask] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+
+                let (direct, negated) = test_high_bits_masked(this, op, mask)?;
+                let res = match unprefixed_name {
+                    "vtestz.pd.256" | "vtestz.pd" | "vtestz.ps.256" | "vtestz.ps" => direct,
+                    "vtestc.pd.256" | "vtestc.pd" | "vtestc.ps.256" | "vtestc.ps" => negated,
+                    "vtestnzc.pd.256" | "vtestnzc.pd" | "vtestnzc.ps.256" | "vtestnzc.ps" =>
+                        !direct && !negated,
+                    _ => unreachable!(),
+                };
+
+                this.write_scalar(Scalar::from_i32(res.into()), dest)?;
+            }
+            _ => return Ok(EmulateForeignItemResult::NotSupported),
+        }
+        Ok(EmulateForeignItemResult::NeedsJumping)
+    }
+}
+
+/// Conditionally loads from `ptr` according the high bit of each
+/// element of `mask`. `ptr` does not need to be aligned.
+fn mask_load<'tcx>(
+    this: &mut crate::MiriInterpCx<'_, 'tcx>,
+    ptr: &OpTy<'tcx, Provenance>,
+    mask: &OpTy<'tcx, Provenance>,
+    dest: &PlaceTy<'tcx, Provenance>,
+) -> InterpResult<'tcx, ()> {
+    let (mask, mask_len) = this.operand_to_simd(mask)?;
+    let (dest, dest_len) = this.place_to_simd(dest)?;
+
+    assert_eq!(dest_len, mask_len);
+
+    let mask_item_size = mask.layout.field(this, 0).size;
+    let high_bit_offset = mask_item_size.bits().checked_sub(1).unwrap();
+
+    let ptr = this.read_pointer(ptr)?;
+    for i in 0..dest_len {
+        let mask = this.project_index(&mask, i)?;
+        let dest = this.project_index(&dest, i)?;
+
+        if this.read_scalar(&mask)?.to_uint(mask_item_size)? >> high_bit_offset != 0 {
+            // Size * u64 is implemented as always checked
+            #[allow(clippy::arithmetic_side_effects)]
+            let ptr = ptr.wrapping_offset(dest.layout.size * i, &this.tcx);
+            // Unaligned copy, which is what we want.
+            this.mem_copy(ptr, dest.ptr(), dest.layout.size, /*nonoverlapping*/ true)?;
+        } else {
+            this.write_scalar(Scalar::from_int(0, dest.layout.size), &dest)?;
+        }
+    }
+
+    Ok(())
+}
+
+/// Conditionally stores into `ptr` according the high bit of each
+/// element of `mask`. `ptr` does not need to be aligned.
+fn mask_store<'tcx>(
+    this: &mut crate::MiriInterpCx<'_, 'tcx>,
+    ptr: &OpTy<'tcx, Provenance>,
+    mask: &OpTy<'tcx, Provenance>,
+    value: &OpTy<'tcx, Provenance>,
+) -> InterpResult<'tcx, ()> {
+    let (mask, mask_len) = this.operand_to_simd(mask)?;
+    let (value, value_len) = this.operand_to_simd(value)?;
+
+    assert_eq!(value_len, mask_len);
+
+    let mask_item_size = mask.layout.field(this, 0).size;
+    let high_bit_offset = mask_item_size.bits().checked_sub(1).unwrap();
+
+    let ptr = this.read_pointer(ptr)?;
+    for i in 0..value_len {
+        let mask = this.project_index(&mask, i)?;
+        let value = this.project_index(&value, i)?;
+
+        if this.read_scalar(&mask)?.to_uint(mask_item_size)? >> high_bit_offset != 0 {
+            // Size * u64 is implemented as always checked
+            #[allow(clippy::arithmetic_side_effects)]
+            let ptr = ptr.wrapping_offset(value.layout.size * i, &this.tcx);
+            // Unaligned copy, which is what we want.
+            this.mem_copy(value.ptr(), ptr, value.layout.size, /*nonoverlapping*/ true)?;
+        }
+    }
+
+    Ok(())
+}
diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs
index b24ea8aec84..9cfee20014f 100644
--- a/src/tools/miri/src/shims/x86/mod.rs
+++ b/src/tools/miri/src/shims/x86/mod.rs
@@ -1,6 +1,8 @@
 use rand::Rng as _;
 
-use rustc_apfloat::{ieee::Single, Float as _};
+use rustc_apfloat::{ieee::Single, Float};
+use rustc_middle::ty::layout::LayoutOf as _;
+use rustc_middle::ty::Ty;
 use rustc_middle::{mir, ty};
 use rustc_span::Symbol;
 use rustc_target::abi::Size;
@@ -11,6 +13,7 @@ use helpers::bool_to_simd_element;
 use shims::foreign_items::EmulateForeignItemResult;
 
 mod aesni;
+mod avx;
 mod sse;
 mod sse2;
 mod sse3;
@@ -115,6 +118,11 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
                     this, link_name, abi, args, dest,
                 );
             }
+            name if name.starts_with("avx.") => {
+                return avx::EvalContextExt::emulate_x86_avx_intrinsic(
+                    this, link_name, abi, args, dest,
+                );
+            }
 
             _ => return Ok(EmulateForeignItemResult::NotSupported),
         }
@@ -296,10 +304,7 @@ fn bin_op_simd_float_first<'tcx, F: rustc_apfloat::Float>(
     this.write_scalar(res0, &this.project_index(&dest, 0)?)?;
 
     for i in 1..dest_len {
-        this.copy_op(
-            &this.project_index(&left, i)?,
-            &this.project_index(&dest, i)?,
-        )?;
+        this.copy_op(&this.project_index(&left, i)?, &this.project_index(&dest, i)?)?;
     }
 
     Ok(())
@@ -420,10 +425,7 @@ fn unary_op_ss<'tcx>(
     this.write_scalar(res0, &this.project_index(&dest, 0)?)?;
 
     for i in 1..dest_len {
-        this.copy_op(
-            &this.project_index(&op, i)?,
-            &this.project_index(&dest, i)?,
-        )?;
+        this.copy_op(&this.project_index(&op, i)?, &this.project_index(&dest, i)?)?;
     }
 
     Ok(())
@@ -479,10 +481,7 @@ fn round_first<'tcx, F: rustc_apfloat::Float>(
     )?;
 
     for i in 1..dest_len {
-        this.copy_op(
-            &this.project_index(&left, i)?,
-            &this.project_index(&dest, i)?,
-        )?;
+        this.copy_op(&this.project_index(&left, i)?, &this.project_index(&dest, i)?)?;
     }
 
     Ok(())
@@ -572,8 +571,65 @@ fn convert_float_to_int<'tcx>(
     Ok(())
 }
 
+/// Splits `left`, `right` and `dest` (which must be SIMD vectors)
+/// into 128-bit chuncks.
+///
+/// `left`, `right` and `dest` cannot have different types.
+///
+/// Returns a tuple where:
+/// * The first element is the number of 128-bit chunks (let's call it `N`).
+/// * The second element is the number of elements per chunk (let's call it `M`).
+/// * The third element is the `left` vector split into chunks, i.e, it's
+///   type is `[[T; M]; N]`.
+/// * The fourth element is the `right` vector split into chunks.
+/// * The fifth element is the `dest` vector split into chunks.
+fn split_simd_to_128bit_chunks<'tcx>(
+    this: &mut crate::MiriInterpCx<'_, 'tcx>,
+    left: &OpTy<'tcx, Provenance>,
+    right: &OpTy<'tcx, Provenance>,
+    dest: &PlaceTy<'tcx, Provenance>,
+) -> InterpResult<
+    'tcx,
+    (u64, u64, MPlaceTy<'tcx, Provenance>, MPlaceTy<'tcx, Provenance>, MPlaceTy<'tcx, Provenance>),
+> {
+    assert_eq!(dest.layout, left.layout);
+    assert_eq!(dest.layout, right.layout);
+
+    let (left, left_len) = this.operand_to_simd(left)?;
+    let (right, right_len) = this.operand_to_simd(right)?;
+    let (dest, dest_len) = this.place_to_simd(dest)?;
+
+    assert_eq!(dest_len, left_len);
+    assert_eq!(dest_len, right_len);
+
+    assert_eq!(dest.layout.size.bits() % 128, 0);
+    let num_chunks = dest.layout.size.bits() / 128;
+    assert_eq!(dest_len.checked_rem(num_chunks), Some(0));
+    let items_per_chunk = dest_len.checked_div(num_chunks).unwrap();
+
+    // Transmute to `[[T; items_per_chunk]; num_chunks]`
+    let element_layout = left.layout.field(this, 0);
+    let chunked_layout = this.layout_of(Ty::new_array(
+        this.tcx.tcx,
+        Ty::new_array(this.tcx.tcx, element_layout.ty, items_per_chunk),
+        num_chunks,
+    ))?;
+    let left = left.transmute(chunked_layout, this)?;
+    let right = right.transmute(chunked_layout, this)?;
+    let dest = dest.transmute(chunked_layout, this)?;
+
+    Ok((num_chunks, items_per_chunk, left, right, dest))
+}
+
 /// Horizontaly performs `which` operation on adjacent values of
 /// `left` and `right` SIMD vectors and stores the result in `dest`.
+/// "Horizontal" means that the i-th output element is calculated
+/// from the elements 2*i and 2*i+1 of the concatenation of `left` and
+/// `right`.
+///
+/// Each 128-bit chunk is treated independently (i.e., the value for
+/// the is i-th 128-bit chunk of `dest` is calculated with the i-th
+/// 128-bit chunks of `left` and `right`).
 fn horizontal_bin_op<'tcx>(
     this: &mut crate::MiriInterpCx<'_, 'tcx>,
     which: mir::BinOp,
@@ -582,32 +638,34 @@ fn horizontal_bin_op<'tcx>(
     right: &OpTy<'tcx, Provenance>,
     dest: &PlaceTy<'tcx, Provenance>,
 ) -> InterpResult<'tcx, ()> {
-    let (left, left_len) = this.operand_to_simd(left)?;
-    let (right, right_len) = this.operand_to_simd(right)?;
-    let (dest, dest_len) = this.place_to_simd(dest)?;
+    let (num_chunks, items_per_chunk, left, right, dest) =
+        split_simd_to_128bit_chunks(this, left, right, dest)?;
 
-    assert_eq!(dest_len, left_len);
-    assert_eq!(dest_len, right_len);
-    assert_eq!(dest_len % 2, 0);
+    let middle = items_per_chunk / 2;
+    for i in 0..num_chunks {
+        let left = this.project_index(&left, i)?;
+        let right = this.project_index(&right, i)?;
+        let dest = this.project_index(&dest, i)?;
 
-    let middle = dest_len / 2;
-    for i in 0..dest_len {
-        // `i` is the index in `dest`
-        // `j` is the index of the 2-item chunk in `src`
-        let (j, src) =
-            if i < middle { (i, &left) } else { (i.checked_sub(middle).unwrap(), &right) };
-        // `base_i` is the index of the first item of the 2-item chunk in `src`
-        let base_i = j.checked_mul(2).unwrap();
-        let lhs = this.read_immediate(&this.project_index(src, base_i)?)?;
-        let rhs = this.read_immediate(&this.project_index(src, base_i.checked_add(1).unwrap())?)?;
-
-        let res = if saturating {
-            Immediate::from(this.saturating_arith(which, &lhs, &rhs)?)
-        } else {
-            *this.wrapping_binary_op(which, &lhs, &rhs)?
-        };
+        for j in 0..items_per_chunk {
+            // `j` is the index in `dest`
+            // `k` is the index of the 2-item chunk in `src`
+            let (k, src) =
+                if j < middle { (j, &left) } else { (j.checked_sub(middle).unwrap(), &right) };
+            // `base_i` is the index of the first item of the 2-item chunk in `src`
+            let base_i = k.checked_mul(2).unwrap();
+            let lhs = this.read_immediate(&this.project_index(src, base_i)?)?;
+            let rhs =
+                this.read_immediate(&this.project_index(src, base_i.checked_add(1).unwrap())?)?;
+
+            let res = if saturating {
+                Immediate::from(this.saturating_arith(which, &lhs, &rhs)?)
+            } else {
+                *this.wrapping_binary_op(which, &lhs, &rhs)?
+            };
 
-        this.write_immediate(res, &this.project_index(&dest, i)?)?;
+            this.write_immediate(res, &this.project_index(&dest, j)?)?;
+        }
     }
 
     Ok(())
@@ -617,6 +675,10 @@ fn horizontal_bin_op<'tcx>(
 /// `left` and `right` using the high 4 bits in `imm`, sums the calculated
 /// products (up to 4), and conditionally stores the sum in `dest` using
 /// the low 4 bits of `imm`.
+///
+/// Each 128-bit chunk is treated independently (i.e., the value for
+/// the is i-th 128-bit chunk of `dest` is calculated with the i-th
+/// 128-bit blocks of `left` and `right`).
 fn conditional_dot_product<'tcx>(
     this: &mut crate::MiriInterpCx<'_, 'tcx>,
     left: &OpTy<'tcx, Provenance>,
@@ -624,39 +686,43 @@ fn conditional_dot_product<'tcx>(
     imm: &OpTy<'tcx, Provenance>,
     dest: &PlaceTy<'tcx, Provenance>,
 ) -> InterpResult<'tcx, ()> {
-    let (left, left_len) = this.operand_to_simd(left)?;
-    let (right, right_len) = this.operand_to_simd(right)?;
-    let (dest, dest_len) = this.place_to_simd(dest)?;
+    let (num_chunks, items_per_chunk, left, right, dest) =
+        split_simd_to_128bit_chunks(this, left, right, dest)?;
 
-    assert_eq!(left_len, right_len);
-    assert!(dest_len <= 4);
+    let element_layout = left.layout.field(this, 0).field(this, 0);
+    assert!(items_per_chunk <= 4);
 
-    let imm = this.read_scalar(imm)?.to_u8()?;
+    // `imm` is a `u8` for SSE4.1 or an `i32` for AVX :/
+    let imm = this.read_scalar(imm)?.to_uint(imm.layout.size)?;
 
-    let element_layout = left.layout.field(this, 0);
+    for i in 0..num_chunks {
+        let left = this.project_index(&left, i)?;
+        let right = this.project_index(&right, i)?;
+        let dest = this.project_index(&dest, i)?;
 
-    // Calculate dot product
-    // Elements are floating point numbers, but we can use `from_int`
-    // because the representation of 0.0 is all zero bits.
-    let mut sum = ImmTy::from_int(0u8, element_layout);
-    for i in 0..left_len {
-        if imm & (1 << i.checked_add(4).unwrap()) != 0 {
-            let left = this.read_immediate(&this.project_index(&left, i)?)?;
-            let right = this.read_immediate(&this.project_index(&right, i)?)?;
-
-            let mul = this.wrapping_binary_op(mir::BinOp::Mul, &left, &right)?;
-            sum = this.wrapping_binary_op(mir::BinOp::Add, &sum, &mul)?;
+        // Calculate dot product
+        // Elements are floating point numbers, but we can use `from_int`
+        // for the initial value because the representation of 0.0 is all zero bits.
+        let mut sum = ImmTy::from_int(0u8, element_layout);
+        for j in 0..items_per_chunk {
+            if imm & (1 << j.checked_add(4).unwrap()) != 0 {
+                let left = this.read_immediate(&this.project_index(&left, j)?)?;
+                let right = this.read_immediate(&this.project_index(&right, j)?)?;
+
+                let mul = this.wrapping_binary_op(mir::BinOp::Mul, &left, &right)?;
+                sum = this.wrapping_binary_op(mir::BinOp::Add, &sum, &mul)?;
+            }
         }
-    }
 
-    // Write to destination (conditioned to imm)
-    for i in 0..dest_len {
-        let dest = this.project_index(&dest, i)?;
+        // Write to destination (conditioned to imm)
+        for j in 0..items_per_chunk {
+            let dest = this.project_index(&dest, j)?;
 
-        if imm & (1 << i) != 0 {
-            this.write_immediate(*sum, &dest)?;
-        } else {
-            this.write_scalar(Scalar::from_int(0u8, element_layout.size), &dest)?;
+            if imm & (1 << j) != 0 {
+                this.write_immediate(*sum, &dest)?;
+            } else {
+                this.write_scalar(Scalar::from_int(0u8, element_layout.size), &dest)?;
+            }
         }
     }
 
@@ -693,3 +759,36 @@ fn test_bits_masked<'tcx>(
 
     Ok((all_zero, masked_set))
 }
+
+/// Calculates two booleans.
+///
+/// The first is true when the highest bit of each element of `op & mask` is zero.
+/// The second is true when the highest bit of each element of `!op & mask` is zero.
+fn test_high_bits_masked<'tcx>(
+    this: &crate::MiriInterpCx<'_, 'tcx>,
+    op: &OpTy<'tcx, Provenance>,
+    mask: &OpTy<'tcx, Provenance>,
+) -> InterpResult<'tcx, (bool, bool)> {
+    assert_eq!(op.layout, mask.layout);
+
+    let (op, op_len) = this.operand_to_simd(op)?;
+    let (mask, mask_len) = this.operand_to_simd(mask)?;
+
+    assert_eq!(op_len, mask_len);
+
+    let high_bit_offset = op.layout.field(this, 0).size.bits().checked_sub(1).unwrap();
+
+    let mut direct = true;
+    let mut negated = true;
+    for i in 0..op_len {
+        let op = this.project_index(&op, i)?;
+        let mask = this.project_index(&mask, i)?;
+
+        let op = this.read_scalar(&op)?.to_uint(op.layout.size)?;
+        let mask = this.read_scalar(&mask)?.to_uint(mask.layout.size)?;
+        direct &= (op & mask) >> high_bit_offset == 0;
+        negated &= (!op & mask) >> high_bit_offset == 0;
+    }
+
+    Ok((direct, negated))
+}
diff --git a/src/tools/miri/src/shims/x86/sse.rs b/src/tools/miri/src/shims/x86/sse.rs
index 9fb947cb2a3..da0db92738f 100644
--- a/src/tools/miri/src/shims/x86/sse.rs
+++ b/src/tools/miri/src/shims/x86/sse.rs
@@ -208,10 +208,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
                 this.write_immediate(*res0, &dest0)?;
 
                 for i in 1..dest_len {
-                    this.copy_op(
-                        &this.project_index(&left, i)?,
-                        &this.project_index(&dest, i)?,
-                    )?;
+                    this.copy_op(&this.project_index(&left, i)?, &this.project_index(&dest, i)?)?;
                 }
             }
             _ => return Ok(EmulateForeignItemResult::NotSupported),
diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs
index e5c8267320a..b34b93e3739 100644
--- a/src/tools/miri/src/shims/x86/sse2.rs
+++ b/src/tools/miri/src/shims/x86/sse2.rs
@@ -440,10 +440,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
                 this.write_scalar(res0, &this.project_index(&dest, 0)?)?;
 
                 for i in 1..dest_len {
-                    this.copy_op(
-                        &this.project_index(&op, i)?,
-                        &this.project_index(&dest, i)?,
-                    )?;
+                    this.copy_op(&this.project_index(&op, i)?, &this.project_index(&dest, i)?)?;
                 }
             }
             // Used to implement _mm_sqrt_pd functions.
@@ -580,10 +577,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
 
                 // Copy remianing from `left`
                 for i in 1..dest_len {
-                    this.copy_op(
-                        &this.project_index(&left, i)?,
-                        &this.project_index(&dest, i)?,
-                    )?;
+                    this.copy_op(&this.project_index(&left, i)?, &this.project_index(&dest, i)?)?;
                 }
             }
             // Used to implement the `_mm_pause` function.
diff --git a/src/tools/miri/src/shims/x86/sse41.rs b/src/tools/miri/src/shims/x86/sse41.rs
index 2abd10fa7a7..32b1fe43c58 100644
--- a/src/tools/miri/src/shims/x86/sse41.rs
+++ b/src/tools/miri/src/shims/x86/sse41.rs
@@ -57,10 +57,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
                         this.write_immediate(*src_value, &dest)?;
                     } else {
                         // copy from `left`
-                        this.copy_op(
-                            &this.project_index(&left, i)?,
-                            &dest,
-                        )?;
+                        this.copy_op(&this.project_index(&left, i)?, &dest)?;
                     }
                 }
             }
diff --git a/src/tools/miri/tests/fail/enum-set-discriminant-niche-variant-wrong.rs b/src/tools/miri/tests/fail/enum-set-discriminant-niche-variant-wrong.rs
index 7097aa0c43a..428f371ca51 100644
--- a/src/tools/miri/tests/fail/enum-set-discriminant-niche-variant-wrong.rs
+++ b/src/tools/miri/tests/fail/enum-set-discriminant-niche-variant-wrong.rs
@@ -4,11 +4,11 @@
 use std::intrinsics::mir::*;
 use std::num::NonZeroI32;
 
-// We define our own option type so that we can control the varian indices.
+// We define our own option type so that we can control the variant indices.
 #[allow(unused)]
 enum Option<T> {
-    None,
-    Some(T),
+    None,    // variant 0
+    Some(T), // variant 1
 }
 use Option::*;
 
diff --git a/src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.rs b/src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.rs
index 44604074982..fef5a6cddb9 100644
--- a/src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.rs
+++ b/src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.rs
@@ -4,8 +4,7 @@ extern "C" {
     static _dispatch_queue_attr_concurrent: [u8; 0];
 }
 
-static DISPATCH_QUEUE_CONCURRENT: &'static [u8; 0] =
-    unsafe { &_dispatch_queue_attr_concurrent };
+static DISPATCH_QUEUE_CONCURRENT: &'static [u8; 0] = unsafe { &_dispatch_queue_attr_concurrent };
 
 fn main() {
     let _val = *DISPATCH_QUEUE_CONCURRENT; //~ERROR: is not supported
diff --git a/src/tools/miri/tests/pass-dep/concurrency/libc_pthread_cond.rs b/src/tools/miri/tests/pass-dep/concurrency/libc_pthread_cond.rs
index b0325f7d78e..f362caa11dc 100644
--- a/src/tools/miri/tests/pass-dep/concurrency/libc_pthread_cond.rs
+++ b/src/tools/miri/tests/pass-dep/concurrency/libc_pthread_cond.rs
@@ -22,7 +22,7 @@ fn test_timed_wait_timeout(clock_id: i32) {
         let mut now_mu: MaybeUninit<libc::timespec> = MaybeUninit::uninit();
         assert_eq!(libc::clock_gettime(clock_id, now_mu.as_mut_ptr()), 0);
         let now = now_mu.assume_init();
-        // Waiting for a second... mostly because waiting less requires mich more tricky arithmetic.
+        // Waiting for a second... mostly because waiting less requires much more tricky arithmetic.
         // FIXME: wait less.
         let timeout = libc::timespec { tv_sec: now.tv_sec + 1, tv_nsec: now.tv_nsec };
 
diff --git a/src/tools/miri/tests/pass-dep/concurrency/libc_pthread_cond_isolated.rs b/src/tools/miri/tests/pass-dep/concurrency/libc_pthread_cond_isolated.rs
index 103ce44006d..66c0895a5da 100644
--- a/src/tools/miri/tests/pass-dep/concurrency/libc_pthread_cond_isolated.rs
+++ b/src/tools/miri/tests/pass-dep/concurrency/libc_pthread_cond_isolated.rs
@@ -21,7 +21,7 @@ fn test_timed_wait_timeout(clock_id: i32) {
         let mut now_mu: MaybeUninit<libc::timespec> = MaybeUninit::uninit();
         assert_eq!(libc::clock_gettime(clock_id, now_mu.as_mut_ptr()), 0);
         let now = now_mu.assume_init();
-        // Waiting for a second... mostly because waiting less requires mich more tricky arithmetic.
+        // Waiting for a second... mostly because waiting less requires much more tricky arithmetic.
         // FIXME: wait less.
         let timeout = libc::timespec { tv_sec: now.tv_sec + 1, tv_nsec: now.tv_nsec };
 
diff --git a/src/tools/miri/tests/pass-dep/shims/mmap.rs b/src/tools/miri/tests/pass-dep/shims/mmap.rs
index e19f54d0687..7bbb9dd53cb 100644
--- a/src/tools/miri/tests/pass-dep/shims/mmap.rs
+++ b/src/tools/miri/tests/pass-dep/shims/mmap.rs
@@ -5,16 +5,25 @@
 use std::io::Error;
 use std::{ptr, slice};
 
-fn test_mmap() {
+fn test_mmap<Offset: Default>(
+    mmap: unsafe extern "C" fn(
+        *mut libc::c_void,
+        libc::size_t,
+        libc::c_int,
+        libc::c_int,
+        libc::c_int,
+        Offset,
+    ) -> *mut libc::c_void,
+) {
     let page_size = page_size::get();
     let ptr = unsafe {
-        libc::mmap(
+        mmap(
             ptr::null_mut(),
             page_size,
             libc::PROT_READ | libc::PROT_WRITE,
             libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
             -1,
-            0,
+            Default::default(),
         )
     };
     assert!(!ptr.is_null());
@@ -35,40 +44,40 @@ fn test_mmap() {
 
     // Test all of our error conditions
     let ptr = unsafe {
-        libc::mmap(
+        mmap(
             ptr::null_mut(),
             page_size,
             libc::PROT_READ | libc::PROT_WRITE,
             libc::MAP_PRIVATE | libc::MAP_SHARED, // Can't be both private and shared
             -1,
-            0,
+            Default::default(),
         )
     };
     assert_eq!(ptr, libc::MAP_FAILED);
     assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL);
 
     let ptr = unsafe {
-        libc::mmap(
+        mmap(
             ptr::null_mut(),
             0, // Can't map no memory
             libc::PROT_READ | libc::PROT_WRITE,
             libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
             -1,
-            0,
+            Default::default(),
         )
     };
     assert_eq!(ptr, libc::MAP_FAILED);
     assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL);
 
     let ptr = unsafe {
-        libc::mmap(
+        mmap(
             ptr::invalid_mut(page_size * 64),
             page_size,
             libc::PROT_READ | libc::PROT_WRITE,
             // We don't support MAP_FIXED
             libc::MAP_PRIVATE | libc::MAP_ANONYMOUS | libc::MAP_FIXED,
             -1,
-            0,
+            Default::default(),
         )
     };
     assert_eq!(ptr, libc::MAP_FAILED);
@@ -77,13 +86,13 @@ fn test_mmap() {
     // We don't support protections other than read+write
     for prot in [libc::PROT_NONE, libc::PROT_EXEC, libc::PROT_READ, libc::PROT_WRITE] {
         let ptr = unsafe {
-            libc::mmap(
+            mmap(
                 ptr::null_mut(),
                 page_size,
                 prot,
                 libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
                 -1,
-                0,
+                Default::default(),
             )
         };
         assert_eq!(ptr, libc::MAP_FAILED);
@@ -93,13 +102,13 @@ fn test_mmap() {
     // We report an error for mappings whose length cannot be rounded up to a multiple of
     // the page size.
     let ptr = unsafe {
-        libc::mmap(
+        mmap(
             ptr::null_mut(),
             usize::MAX - 1,
             libc::PROT_READ | libc::PROT_WRITE,
             libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
             -1,
-            0,
+            Default::default(),
         )
     };
     assert_eq!(ptr, libc::MAP_FAILED);
@@ -163,7 +172,9 @@ fn test_mremap() {
 }
 
 fn main() {
-    test_mmap();
+    test_mmap(libc::mmap);
+    #[cfg(target_os = "linux")]
+    test_mmap(libc::mmap64);
     #[cfg(target_os = "linux")]
     test_mremap();
 }
diff --git a/src/tools/miri/tests/pass-dep/shims/pthread-sync.rs b/src/tools/miri/tests/pass-dep/shims/pthread-sync.rs
index 4cc5b7d68a3..077bbfff164 100644
--- a/src/tools/miri/tests/pass-dep/shims/pthread-sync.rs
+++ b/src/tools/miri/tests/pass-dep/shims/pthread-sync.rs
@@ -1,24 +1,34 @@
 //@ignore-target-windows: No libc on Windows
+// We use `yield` to test specific interleavings, so disable automatic preemption.
+//@compile-flags: -Zmiri-preemption-rate=0
+#![feature(sync_unsafe_cell)]
+
+use std::cell::SyncUnsafeCell;
+use std::thread;
+use std::{mem, ptr};
 
 fn main() {
     test_mutex_libc_init_recursive();
     test_mutex_libc_init_normal();
     test_mutex_libc_init_errorcheck();
     test_rwlock_libc_static_initializer();
-
     #[cfg(target_os = "linux")]
     test_mutex_libc_static_initializer_recursive();
+
+    test_mutex();
+    check_rwlock_write();
+    check_rwlock_read_no_deadlock();
 }
 
 fn test_mutex_libc_init_recursive() {
     unsafe {
-        let mut attr: libc::pthread_mutexattr_t = std::mem::zeroed();
+        let mut attr: libc::pthread_mutexattr_t = mem::zeroed();
         assert_eq!(libc::pthread_mutexattr_init(&mut attr as *mut _), 0);
         assert_eq!(
             libc::pthread_mutexattr_settype(&mut attr as *mut _, libc::PTHREAD_MUTEX_RECURSIVE),
             0,
         );
-        let mut mutex: libc::pthread_mutex_t = std::mem::zeroed();
+        let mut mutex: libc::pthread_mutex_t = mem::zeroed();
         assert_eq!(libc::pthread_mutex_init(&mut mutex as *mut _, &mut attr as *mut _), 0);
         assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0);
         assert_eq!(libc::pthread_mutex_trylock(&mut mutex as *mut _), 0);
@@ -36,7 +46,7 @@ fn test_mutex_libc_init_recursive() {
 
 fn test_mutex_libc_init_normal() {
     unsafe {
-        let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed();
+        let mut mutexattr: libc::pthread_mutexattr_t = mem::zeroed();
         assert_eq!(
             libc::pthread_mutexattr_settype(&mut mutexattr as *mut _, 0x12345678),
             libc::EINVAL,
@@ -45,7 +55,7 @@ fn test_mutex_libc_init_normal() {
             libc::pthread_mutexattr_settype(&mut mutexattr as *mut _, libc::PTHREAD_MUTEX_NORMAL),
             0,
         );
-        let mut mutex: libc::pthread_mutex_t = std::mem::zeroed();
+        let mut mutex: libc::pthread_mutex_t = mem::zeroed();
         assert_eq!(libc::pthread_mutex_init(&mut mutex as *mut _, &mutexattr as *const _), 0);
         assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0);
         assert_eq!(libc::pthread_mutex_trylock(&mut mutex as *mut _), libc::EBUSY);
@@ -58,7 +68,7 @@ fn test_mutex_libc_init_normal() {
 
 fn test_mutex_libc_init_errorcheck() {
     unsafe {
-        let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed();
+        let mut mutexattr: libc::pthread_mutexattr_t = mem::zeroed();
         assert_eq!(
             libc::pthread_mutexattr_settype(
                 &mut mutexattr as *mut _,
@@ -66,7 +76,7 @@ fn test_mutex_libc_init_errorcheck() {
             ),
             0,
         );
-        let mut mutex: libc::pthread_mutex_t = std::mem::zeroed();
+        let mut mutex: libc::pthread_mutex_t = mem::zeroed();
         assert_eq!(libc::pthread_mutex_init(&mut mutex as *mut _, &mutexattr as *const _), 0);
         assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0);
         assert_eq!(libc::pthread_mutex_trylock(&mut mutex as *mut _), libc::EBUSY);
@@ -98,9 +108,113 @@ fn test_mutex_libc_static_initializer_recursive() {
     }
 }
 
-// Testing the behavior of std::sync::RwLock does not fully exercise the pthread rwlock shims, we
-// need to go a layer deeper and test the behavior of the libc functions, because
-// std::sys::unix::rwlock::RWLock itself keeps track of write_locked and num_readers.
+struct SendPtr<T> {
+    ptr: *mut T,
+}
+unsafe impl<T> Send for SendPtr<T> {}
+impl<T> Copy for SendPtr<T> {}
+impl<T> Clone for SendPtr<T> {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+
+fn test_mutex() {
+    // Specifically *not* using `Arc` to make sure there is no synchronization apart from the mutex.
+    unsafe {
+        let data = SyncUnsafeCell::new((libc::PTHREAD_MUTEX_INITIALIZER, 0));
+        let ptr = SendPtr { ptr: data.get() };
+        let mut threads = Vec::new();
+
+        for _ in 0..3 {
+            let thread = thread::spawn(move || {
+                let ptr = ptr; // circumvent per-field closure capture
+                let mutexptr = ptr::addr_of_mut!((*ptr.ptr).0);
+                assert_eq!(libc::pthread_mutex_lock(mutexptr), 0);
+                thread::yield_now();
+                (*ptr.ptr).1 += 1;
+                assert_eq!(libc::pthread_mutex_unlock(mutexptr), 0);
+            });
+            threads.push(thread);
+        }
+
+        for thread in threads {
+            thread.join().unwrap();
+        }
+
+        let mutexptr = ptr::addr_of_mut!((*ptr.ptr).0);
+        assert_eq!(libc::pthread_mutex_trylock(mutexptr), 0);
+        assert_eq!((*ptr.ptr).1, 3);
+    }
+}
+
+fn check_rwlock_write() {
+    unsafe {
+        let data = SyncUnsafeCell::new((libc::PTHREAD_RWLOCK_INITIALIZER, 0));
+        let ptr = SendPtr { ptr: data.get() };
+        let mut threads = Vec::new();
+
+        for _ in 0..3 {
+            let thread = thread::spawn(move || {
+                let ptr = ptr; // circumvent per-field closure capture
+                let rwlockptr = ptr::addr_of_mut!((*ptr.ptr).0);
+                assert_eq!(libc::pthread_rwlock_wrlock(rwlockptr), 0);
+                thread::yield_now();
+                (*ptr.ptr).1 += 1;
+                assert_eq!(libc::pthread_rwlock_unlock(rwlockptr), 0);
+            });
+            threads.push(thread);
+
+            let readthread = thread::spawn(move || {
+                let ptr = ptr; // circumvent per-field closure capture
+                let rwlockptr = ptr::addr_of_mut!((*ptr.ptr).0);
+                assert_eq!(libc::pthread_rwlock_rdlock(rwlockptr), 0);
+                thread::yield_now();
+                let val = (*ptr.ptr).1;
+                assert!(val >= 0 && val <= 3);
+                assert_eq!(libc::pthread_rwlock_unlock(rwlockptr), 0);
+            });
+            threads.push(readthread);
+        }
+
+        for thread in threads {
+            thread.join().unwrap();
+        }
+
+        let rwlockptr = ptr::addr_of_mut!((*ptr.ptr).0);
+        assert_eq!(libc::pthread_rwlock_tryrdlock(rwlockptr), 0);
+        assert_eq!((*ptr.ptr).1, 3);
+    }
+}
+
+fn check_rwlock_read_no_deadlock() {
+    unsafe {
+        let l1 = SyncUnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER);
+        let l1 = SendPtr { ptr: l1.get() };
+        let l2 = SyncUnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER);
+        let l2 = SendPtr { ptr: l2.get() };
+
+        // acquire l1 and hold it until after the other thread is done
+        assert_eq!(libc::pthread_rwlock_rdlock(l1.ptr), 0);
+        let handle = thread::spawn(move || {
+            let l1 = l1; // circumvent per-field closure capture
+            let l2 = l2; // circumvent per-field closure capture
+            // acquire l2 before the other thread
+            assert_eq!(libc::pthread_rwlock_rdlock(l2.ptr), 0);
+            thread::yield_now();
+            assert_eq!(libc::pthread_rwlock_rdlock(l1.ptr), 0);
+            thread::yield_now();
+            assert_eq!(libc::pthread_rwlock_unlock(l1.ptr), 0);
+            assert_eq!(libc::pthread_rwlock_unlock(l2.ptr), 0);
+        });
+        thread::yield_now();
+        assert_eq!(libc::pthread_rwlock_rdlock(l2.ptr), 0);
+        handle.join().unwrap();
+    }
+}
+
+// std::sync::RwLock does not even used pthread_rwlock any more.
+// Do some smoke testing of the API surface.
 fn test_rwlock_libc_static_initializer() {
     let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER);
     unsafe {
diff --git a/src/tools/miri/tests/pass/align_offset_symbolic.rs b/src/tools/miri/tests/pass/align_offset_symbolic.rs
index e96f11b1efa..ac28c63e081 100644
--- a/src/tools/miri/tests/pass/align_offset_symbolic.rs
+++ b/src/tools/miri/tests/pass/align_offset_symbolic.rs
@@ -113,7 +113,7 @@ fn vtable() {
 
     let ptr: &dyn Send = &0;
     let parts: (*const (), *const u8) = unsafe { mem::transmute(ptr) };
-    let vtable = parts.1 ;
+    let vtable = parts.1;
     let offset = vtable.align_offset(mem::align_of::<TWOPTR>());
     let _vtable_aligned = vtable.wrapping_add(offset) as *const [TWOPTR; 0];
     // FIXME: we can't actually do the access since vtable pointers act like zero-sized allocations.
diff --git a/src/tools/miri/tests/pass/concurrency/sync.rs b/src/tools/miri/tests/pass/concurrency/sync.rs
index e93e617fd26..1d48e5312d4 100644
--- a/src/tools/miri/tests/pass/concurrency/sync.rs
+++ b/src/tools/miri/tests/pass/concurrency/sync.rs
@@ -1,6 +1,7 @@
 //@revisions: stack tree
 //@[tree]compile-flags: -Zmiri-tree-borrows
-//@compile-flags: -Zmiri-disable-isolation -Zmiri-strict-provenance
+// We use `yield` to test specific interleavings, so disable automatic preemption.
+//@compile-flags: -Zmiri-disable-isolation -Zmiri-strict-provenance -Zmiri-preemption-rate=0
 
 use std::sync::{Arc, Barrier, Condvar, Mutex, Once, RwLock};
 use std::thread;
@@ -119,13 +120,25 @@ fn check_rwlock_write() {
     let mut threads = Vec::new();
 
     for _ in 0..3 {
-        let data = Arc::clone(&data);
-        let thread = thread::spawn(move || {
-            let mut data = data.write().unwrap();
-            thread::yield_now();
-            *data += 1;
+        let thread = thread::spawn({
+            let data = Arc::clone(&data);
+            move || {
+                let mut data = data.write().unwrap();
+                thread::yield_now();
+                *data += 1;
+            }
         });
         threads.push(thread);
+
+        let readthread = thread::spawn({
+            let data = Arc::clone(&data);
+            move || {
+                let data = data.read().unwrap();
+                thread::yield_now();
+                assert!(*data >= 0 && *data <= 3);
+            }
+        });
+        threads.push(readthread);
     }
 
     for thread in threads {
@@ -144,8 +157,10 @@ fn check_rwlock_read_no_deadlock() {
 
     let l1_copy = Arc::clone(&l1);
     let l2_copy = Arc::clone(&l2);
+    // acquire l1 and hold it until after the other thread is done
     let _guard1 = l1.read().unwrap();
     let handle = thread::spawn(move || {
+        // acquire l2 before the other thread
         let _guard2 = l2_copy.read().unwrap();
         thread::yield_now();
         let _guard1 = l1_copy.read().unwrap();
diff --git a/src/tools/miri/tests/pass/imported_main.rs b/src/tools/miri/tests/pass/imported_main.rs
new file mode 100644
index 00000000000..32b39152f78
--- /dev/null
+++ b/src/tools/miri/tests/pass/imported_main.rs
@@ -0,0 +1,8 @@
+#![feature(imported_main)]
+
+pub mod foo {
+    pub fn mymain() {
+        println!("Hello, world!");
+    }
+}
+use foo::mymain as main;
diff --git a/src/tools/miri/tests/pass/imported_main.stdout b/src/tools/miri/tests/pass/imported_main.stdout
new file mode 100644
index 00000000000..af5626b4a11
--- /dev/null
+++ b/src/tools/miri/tests/pass/imported_main.stdout
@@ -0,0 +1 @@
+Hello, world!
diff --git a/src/tools/miri/tests/pass/intrinsics-x86-avx.rs b/src/tools/miri/tests/pass/intrinsics-x86-avx.rs
index 933e3d4153a..7d43cc596ae 100644
--- a/src/tools/miri/tests/pass/intrinsics-x86-avx.rs
+++ b/src/tools/miri/tests/pass/intrinsics-x86-avx.rs
@@ -25,6 +25,528 @@ fn main() {
 
 #[target_feature(enable = "avx")]
 unsafe fn test_avx() {
+    // Mostly copied from library/stdarch/crates/core_arch/src/x86/avx.rs
+
+    macro_rules! assert_approx_eq {
+        ($a:expr, $b:expr, $eps:expr) => {{
+            let (a, b) = (&$a, &$b);
+            assert!(
+                (*a - *b).abs() < $eps,
+                "assertion failed: `(left !== right)` \
+             (left: `{:?}`, right: `{:?}`, expect diff: `{:?}`, real diff: `{:?}`)",
+                *a,
+                *b,
+                $eps,
+                (*a - *b).abs()
+            );
+        }};
+    }
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_max_pd() {
+        let a = _mm256_setr_pd(1., 4., 5., 8.);
+        let b = _mm256_setr_pd(2., 3., 6., 7.);
+        let r = _mm256_max_pd(a, b);
+        let e = _mm256_setr_pd(2., 4., 6., 8.);
+        assert_eq_m256d(r, e);
+        // > If the values being compared are both 0.0s (of either sign), the
+        // > value in the second operand (source operand) is returned.
+        let w = _mm256_max_pd(_mm256_set1_pd(0.0), _mm256_set1_pd(-0.0));
+        let x = _mm256_max_pd(_mm256_set1_pd(-0.0), _mm256_set1_pd(0.0));
+        let wu: [u64; 4] = transmute(w);
+        let xu: [u64; 4] = transmute(x);
+        assert_eq!(wu, [0x8000_0000_0000_0000u64; 4]);
+        assert_eq!(xu, [0u64; 4]);
+        // > If only one value is a NaN (SNaN or QNaN) for this instruction, the
+        // > second operand (source operand), either a NaN or a valid
+        // > floating-point value, is written to the result.
+        let y = _mm256_max_pd(_mm256_set1_pd(f64::NAN), _mm256_set1_pd(0.0));
+        let z = _mm256_max_pd(_mm256_set1_pd(0.0), _mm256_set1_pd(f64::NAN));
+        let yf: [f64; 4] = transmute(y);
+        let zf: [f64; 4] = transmute(z);
+        assert_eq!(yf, [0.0; 4]);
+        assert!(zf.iter().all(|f| f.is_nan()), "{:?}", zf);
+    }
+    test_mm256_max_pd();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_max_ps() {
+        let a = _mm256_setr_ps(1., 4., 5., 8., 9., 12., 13., 16.);
+        let b = _mm256_setr_ps(2., 3., 6., 7., 10., 11., 14., 15.);
+        let r = _mm256_max_ps(a, b);
+        let e = _mm256_setr_ps(2., 4., 6., 8., 10., 12., 14., 16.);
+        assert_eq_m256(r, e);
+        // > If the values being compared are both 0.0s (of either sign), the
+        // > value in the second operand (source operand) is returned.
+        let w = _mm256_max_ps(_mm256_set1_ps(0.0), _mm256_set1_ps(-0.0));
+        let x = _mm256_max_ps(_mm256_set1_ps(-0.0), _mm256_set1_ps(0.0));
+        let wu: [u32; 8] = transmute(w);
+        let xu: [u32; 8] = transmute(x);
+        assert_eq!(wu, [0x8000_0000u32; 8]);
+        assert_eq!(xu, [0u32; 8]);
+        // > If only one value is a NaN (SNaN or QNaN) for this instruction, the
+        // > second operand (source operand), either a NaN or a valid
+        // > floating-point value, is written to the result.
+        let y = _mm256_max_ps(_mm256_set1_ps(f32::NAN), _mm256_set1_ps(0.0));
+        let z = _mm256_max_ps(_mm256_set1_ps(0.0), _mm256_set1_ps(f32::NAN));
+        let yf: [f32; 8] = transmute(y);
+        let zf: [f32; 8] = transmute(z);
+        assert_eq!(yf, [0.0; 8]);
+        assert!(zf.iter().all(|f| f.is_nan()), "{:?}", zf);
+    }
+    test_mm256_max_ps();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_min_pd() {
+        let a = _mm256_setr_pd(1., 4., 5., 8.);
+        let b = _mm256_setr_pd(2., 3., 6., 7.);
+        let r = _mm256_min_pd(a, b);
+        let e = _mm256_setr_pd(1., 3., 5., 7.);
+        assert_eq_m256d(r, e);
+        // > If the values being compared are both 0.0s (of either sign), the
+        // > value in the second operand (source operand) is returned.
+        let w = _mm256_min_pd(_mm256_set1_pd(0.0), _mm256_set1_pd(-0.0));
+        let x = _mm256_min_pd(_mm256_set1_pd(-0.0), _mm256_set1_pd(0.0));
+        let wu: [u64; 4] = transmute(w);
+        let xu: [u64; 4] = transmute(x);
+        assert_eq!(wu, [0x8000_0000_0000_0000u64; 4]);
+        assert_eq!(xu, [0u64; 4]);
+        // > If only one value is a NaN (SNaN or QNaN) for this instruction, the
+        // > second operand (source operand), either a NaN or a valid
+        // > floating-point value, is written to the result.
+        let y = _mm256_min_pd(_mm256_set1_pd(f64::NAN), _mm256_set1_pd(0.0));
+        let z = _mm256_min_pd(_mm256_set1_pd(0.0), _mm256_set1_pd(f64::NAN));
+        let yf: [f64; 4] = transmute(y);
+        let zf: [f64; 4] = transmute(z);
+        assert_eq!(yf, [0.0; 4]);
+        assert!(zf.iter().all(|f| f.is_nan()), "{:?}", zf);
+    }
+    test_mm256_min_pd();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_min_ps() {
+        let a = _mm256_setr_ps(1., 4., 5., 8., 9., 12., 13., 16.);
+        let b = _mm256_setr_ps(2., 3., 6., 7., 10., 11., 14., 15.);
+        let r = _mm256_min_ps(a, b);
+        let e = _mm256_setr_ps(1., 3., 5., 7., 9., 11., 13., 15.);
+        assert_eq_m256(r, e);
+        // > If the values being compared are both 0.0s (of either sign), the
+        // > value in the second operand (source operand) is returned.
+        let w = _mm256_min_ps(_mm256_set1_ps(0.0), _mm256_set1_ps(-0.0));
+        let x = _mm256_min_ps(_mm256_set1_ps(-0.0), _mm256_set1_ps(0.0));
+        let wu: [u32; 8] = transmute(w);
+        let xu: [u32; 8] = transmute(x);
+        assert_eq!(wu, [0x8000_0000u32; 8]);
+        assert_eq!(xu, [0u32; 8]);
+        // > If only one value is a NaN (SNaN or QNaN) for this instruction, the
+        // > second operand (source operand), either a NaN or a valid
+        // > floating-point value, is written to the result.
+        let y = _mm256_min_ps(_mm256_set1_ps(f32::NAN), _mm256_set1_ps(0.0));
+        let z = _mm256_min_ps(_mm256_set1_ps(0.0), _mm256_set1_ps(f32::NAN));
+        let yf: [f32; 8] = transmute(y);
+        let zf: [f32; 8] = transmute(z);
+        assert_eq!(yf, [0.0; 8]);
+        assert!(zf.iter().all(|f| f.is_nan()), "{:?}", zf);
+    }
+    test_mm256_min_ps();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_round_nearest_f32() {
+        #[target_feature(enable = "avx")]
+        unsafe fn test(x: f32, res: f32) {
+            let a = _mm256_set1_ps(x);
+            let e = _mm256_set1_ps(res);
+            let r = _mm256_round_ps::<_MM_FROUND_TO_NEAREST_INT>(a);
+            assert_eq_m256(r, e);
+            // Assume round-to-nearest by default
+            let r = _mm256_round_ps::<_MM_FROUND_CUR_DIRECTION>(a);
+            assert_eq_m256(r, e);
+        }
+
+        // Test rounding direction
+        test(-2.5, -2.0);
+        test(-1.75, -2.0);
+        test(-1.5, -2.0);
+        test(-1.25, -1.0);
+        test(-1.0, -1.0);
+        test(0.0, 0.0);
+        test(1.0, 1.0);
+        test(1.25, 1.0);
+        test(1.5, 2.0);
+        test(1.75, 2.0);
+        test(2.5, 2.0);
+
+        // Test that each element is rounded
+        let a = _mm256_setr_ps(1.5, 3.5, 5.5, 7.5, 9.5, 11.5, 13.5, 15.5);
+        let e = _mm256_setr_ps(2.0, 4.0, 6.0, 8.0, 10.0, 12.0, 14.0, 16.0);
+        let r = _mm256_round_ps::<_MM_FROUND_TO_NEAREST_INT>(a);
+        assert_eq_m256(r, e);
+        // Assume round-to-nearest by default
+        let r = _mm256_round_ps::<_MM_FROUND_CUR_DIRECTION>(a);
+        assert_eq_m256(r, e);
+    }
+    test_round_nearest_f32();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_round_floor_f32() {
+        #[target_feature(enable = "avx")]
+        unsafe fn test(x: f32, res: f32) {
+            let a = _mm256_set1_ps(x);
+            let e = _mm256_set1_ps(res);
+            let r = _mm256_floor_ps(a);
+            assert_eq_m256(r, e);
+            let r = _mm256_round_ps::<_MM_FROUND_TO_NEG_INF>(a);
+            assert_eq_m256(r, e);
+        }
+
+        // Test rounding direction
+        test(-2.5, -3.0);
+        test(-1.75, -2.0);
+        test(-1.5, -2.0);
+        test(-1.25, -2.0);
+        test(-1.0, -1.0);
+        test(0.0, 0.0);
+        test(1.0, 1.0);
+        test(1.25, 1.0);
+        test(1.5, 1.0);
+        test(1.75, 1.0);
+        test(2.5, 2.0);
+
+        // Test that each element is rounded
+        let a = _mm256_setr_ps(1.5, 3.5, 5.5, 7.5, 9.5, 11.5, 13.5, 15.5);
+        let e = _mm256_setr_ps(1.0, 3.0, 5.0, 7.0, 9.0, 11.0, 13.0, 15.0);
+        let r = _mm256_floor_ps(a);
+        assert_eq_m256(r, e);
+        let r = _mm256_round_ps::<_MM_FROUND_TO_NEG_INF>(a);
+        assert_eq_m256(r, e);
+    }
+    test_round_floor_f32();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_round_ceil_f32() {
+        #[target_feature(enable = "avx")]
+        unsafe fn test(x: f32, res: f32) {
+            let a = _mm256_set1_ps(x);
+            let e = _mm256_set1_ps(res);
+            let r = _mm256_ceil_ps(a);
+            assert_eq_m256(r, e);
+            let r = _mm256_round_ps::<_MM_FROUND_TO_POS_INF>(a);
+            assert_eq_m256(r, e);
+        }
+
+        // Test rounding direction
+        test(-2.5, -2.0);
+        test(-1.75, -1.0);
+        test(-1.5, -1.0);
+        test(-1.25, -1.0);
+        test(-1.0, -1.0);
+        test(0.0, 0.0);
+        test(1.0, 1.0);
+        test(1.25, 2.0);
+        test(1.5, 2.0);
+        test(1.75, 2.0);
+        test(2.5, 3.0);
+
+        // Test that each element is rounded
+        let a = _mm256_setr_ps(1.5, 3.5, 5.5, 7.5, 9.5, 11.5, 13.5, 15.5);
+        let e = _mm256_setr_ps(2.0, 4.0, 6.0, 8.0, 10.0, 12.0, 14.0, 16.0);
+        let r = _mm256_ceil_ps(a);
+        assert_eq_m256(r, e);
+        let r = _mm256_round_ps::<_MM_FROUND_TO_POS_INF>(a);
+        assert_eq_m256(r, e);
+    }
+    test_round_ceil_f32();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_round_trunc_f32() {
+        #[target_feature(enable = "avx")]
+        unsafe fn test(x: f32, res: f32) {
+            let a = _mm256_set1_ps(x);
+            let e = _mm256_set1_ps(res);
+            let r = _mm256_round_ps::<_MM_FROUND_TO_ZERO>(a);
+            assert_eq_m256(r, e);
+        }
+
+        // Test rounding direction
+        test(-2.5, -2.0);
+        test(-1.75, -1.0);
+        test(-1.5, -1.0);
+        test(-1.25, -1.0);
+        test(-1.0, -1.0);
+        test(0.0, 0.0);
+        test(1.0, 1.0);
+        test(1.25, 1.0);
+        test(1.5, 1.0);
+        test(1.75, 1.0);
+        test(2.5, 2.0);
+
+        // Test that each element is rounded
+        let a = _mm256_setr_ps(1.5, 3.5, 5.5, 7.5, 9.5, 11.5, 13.5, 15.5);
+        let e = _mm256_setr_ps(1.0, 3.0, 5.0, 7.0, 9.0, 11.0, 13.0, 15.0);
+        let r = _mm256_round_ps::<_MM_FROUND_TO_ZERO>(a);
+        assert_eq_m256(r, e);
+    }
+    test_round_trunc_f32();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_round_nearest_f64() {
+        #[target_feature(enable = "avx")]
+        unsafe fn test(x: f64, res: f64) {
+            let a = _mm256_set1_pd(x);
+            let e = _mm256_set1_pd(res);
+            let r = _mm256_round_pd::<_MM_FROUND_TO_NEAREST_INT>(a);
+            assert_eq_m256d(r, e);
+            // Assume round-to-nearest by default
+            let r = _mm256_round_pd::<_MM_FROUND_CUR_DIRECTION>(a);
+            assert_eq_m256d(r, e);
+        }
+
+        // Test rounding direction
+        test(-2.5, -2.0);
+        test(-1.75, -2.0);
+        test(-1.5, -2.0);
+        test(-1.25, -1.0);
+        test(-1.0, -1.0);
+        test(0.0, 0.0);
+        test(1.0, 1.0);
+        test(1.25, 1.0);
+        test(1.5, 2.0);
+        test(1.75, 2.0);
+        test(2.5, 2.0);
+
+        // Test that each element is rounded
+        let a = _mm256_setr_pd(1.5, 3.5, 5.5, 7.5);
+        let e = _mm256_setr_pd(2.0, 4.0, 6.0, 8.0);
+        let r = _mm256_round_pd::<_MM_FROUND_TO_NEAREST_INT>(a);
+        assert_eq_m256d(r, e);
+        // Assume round-to-nearest by default
+        let r = _mm256_round_pd::<_MM_FROUND_CUR_DIRECTION>(a);
+        assert_eq_m256d(r, e);
+    }
+    test_round_nearest_f64();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_round_floor_f64() {
+        #[target_feature(enable = "avx")]
+        unsafe fn test(x: f64, res: f64) {
+            let a = _mm256_set1_pd(x);
+            let e = _mm256_set1_pd(res);
+            let r = _mm256_floor_pd(a);
+            assert_eq_m256d(r, e);
+            let r = _mm256_round_pd::<_MM_FROUND_TO_NEG_INF>(a);
+            assert_eq_m256d(r, e);
+        }
+
+        // Test rounding direction
+        test(-2.5, -3.0);
+        test(-1.75, -2.0);
+        test(-1.5, -2.0);
+        test(-1.25, -2.0);
+        test(-1.0, -1.0);
+        test(0.0, 0.0);
+        test(1.0, 1.0);
+        test(1.25, 1.0);
+        test(1.5, 1.0);
+        test(1.75, 1.0);
+        test(2.5, 2.0);
+
+        // Test that each element is rounded
+        let a = _mm256_setr_pd(1.5, 3.5, 5.5, 7.5);
+        let e = _mm256_setr_pd(1.0, 3.0, 5.0, 7.0);
+        let r = _mm256_floor_pd(a);
+        assert_eq_m256d(r, e);
+        let r = _mm256_round_pd::<_MM_FROUND_TO_NEG_INF>(a);
+        assert_eq_m256d(r, e);
+    }
+    test_round_floor_f64();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_round_ceil_f64() {
+        #[target_feature(enable = "avx")]
+        unsafe fn test(x: f64, res: f64) {
+            let a = _mm256_set1_pd(x);
+            let e = _mm256_set1_pd(res);
+            let r = _mm256_ceil_pd(a);
+            assert_eq_m256d(r, e);
+            let r = _mm256_round_pd::<_MM_FROUND_TO_POS_INF>(a);
+            assert_eq_m256d(r, e);
+        }
+
+        // Test rounding direction
+        test(-2.5, -2.0);
+        test(-1.75, -1.0);
+        test(-1.5, -1.0);
+        test(-1.25, -1.0);
+        test(-1.0, -1.0);
+        test(0.0, 0.0);
+        test(1.0, 1.0);
+        test(1.25, 2.0);
+        test(1.5, 2.0);
+        test(1.75, 2.0);
+        test(2.5, 3.0);
+
+        // Test that each element is rounded
+        let a = _mm256_setr_pd(1.5, 3.5, 5.5, 7.5);
+        let e = _mm256_setr_pd(2.0, 4.0, 6.0, 8.0);
+        let r = _mm256_ceil_pd(a);
+        assert_eq_m256d(r, e);
+        let r = _mm256_round_pd::<_MM_FROUND_TO_POS_INF>(a);
+        assert_eq_m256d(r, e);
+    }
+    test_round_ceil_f64();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_round_trunc_f64() {
+        #[target_feature(enable = "avx")]
+        unsafe fn test(x: f64, res: f64) {
+            let a = _mm256_set1_pd(x);
+            let e = _mm256_set1_pd(res);
+            let r = _mm256_round_pd::<_MM_FROUND_TO_ZERO>(a);
+            assert_eq_m256d(r, e);
+        }
+
+        // Test rounding direction
+        test(-2.5, -2.0);
+        test(-1.75, -1.0);
+        test(-1.5, -1.0);
+        test(-1.25, -1.0);
+        test(-1.0, -1.0);
+        test(0.0, 0.0);
+        test(1.0, 1.0);
+        test(1.25, 1.0);
+        test(1.5, 1.0);
+        test(1.75, 1.0);
+        test(2.5, 2.0);
+
+        // Test that each element is rounded
+        let a = _mm256_setr_pd(1.5, 3.5, 5.5, 7.5);
+        let e = _mm256_setr_pd(1.0, 3.0, 5.0, 7.0);
+        let r = _mm256_round_pd::<_MM_FROUND_TO_ZERO>(a);
+        assert_eq_m256d(r, e);
+    }
+    test_round_trunc_f64();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_sqrt_ps() {
+        let a = _mm256_setr_ps(4., 9., 16., 25., 4., 9., 16., 25.);
+        let r = _mm256_sqrt_ps(a);
+        let e = _mm256_setr_ps(2., 3., 4., 5., 2., 3., 4., 5.);
+        assert_eq_m256(r, e);
+    }
+    test_mm256_sqrt_ps();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_rcp_ps() {
+        let a = _mm256_setr_ps(1., 2., 3., 4., 5., 6., 7., 8.);
+        let r = _mm256_rcp_ps(a);
+        #[rustfmt::skip]
+        let e = _mm256_setr_ps(
+            0.99975586, 0.49987793, 0.33325195, 0.24993896,
+            0.19995117, 0.16662598, 0.14282227, 0.12496948,
+        );
+        let rel_err = 0.00048828125;
+
+        let r: [f32; 8] = transmute(r);
+        let e: [f32; 8] = transmute(e);
+        for i in 0..8 {
+            assert_approx_eq!(r[i], e[i], 2. * rel_err);
+        }
+    }
+    test_mm256_rcp_ps();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_rsqrt_ps() {
+        let a = _mm256_setr_ps(1., 2., 3., 4., 5., 6., 7., 8.);
+        let r = _mm256_rsqrt_ps(a);
+        #[rustfmt::skip]
+        let e = _mm256_setr_ps(
+            0.99975586, 0.7069092, 0.5772705, 0.49987793,
+            0.44714355, 0.40820313, 0.3779297, 0.3534546,
+        );
+        let rel_err = 0.00048828125;
+
+        let r: [f32; 8] = transmute(r);
+        let e: [f32; 8] = transmute(e);
+        for i in 0..8 {
+            assert_approx_eq!(r[i], e[i], 2. * rel_err);
+        }
+    }
+    test_mm256_rsqrt_ps();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_dp_ps() {
+        let a = _mm256_setr_ps(4., 9., 16., 25., 4., 9., 16., 25.);
+        let b = _mm256_setr_ps(4., 3., 2., 5., 8., 9., 64., 50.);
+        let r = _mm256_dp_ps::<0xFF>(a, b);
+        let e = _mm256_setr_ps(200., 200., 200., 200., 2387., 2387., 2387., 2387.);
+        assert_eq_m256(r, e);
+    }
+    test_mm256_dp_ps();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_hadd_pd() {
+        let a = _mm256_setr_pd(4., 9., 16., 25.);
+        let b = _mm256_setr_pd(4., 3., 2., 5.);
+        let r = _mm256_hadd_pd(a, b);
+        let e = _mm256_setr_pd(13., 7., 41., 7.);
+        assert_eq_m256d(r, e);
+
+        let a = _mm256_setr_pd(1., 2., 3., 4.);
+        let b = _mm256_setr_pd(5., 6., 7., 8.);
+        let r = _mm256_hadd_pd(a, b);
+        let e = _mm256_setr_pd(3., 11., 7., 15.);
+        assert_eq_m256d(r, e);
+    }
+    test_mm256_hadd_pd();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_hadd_ps() {
+        let a = _mm256_setr_ps(4., 9., 16., 25., 4., 9., 16., 25.);
+        let b = _mm256_setr_ps(4., 3., 2., 5., 8., 9., 64., 50.);
+        let r = _mm256_hadd_ps(a, b);
+        let e = _mm256_setr_ps(13., 41., 7., 7., 13., 41., 17., 114.);
+        assert_eq_m256(r, e);
+
+        let a = _mm256_setr_ps(1., 2., 3., 4., 1., 2., 3., 4.);
+        let b = _mm256_setr_ps(5., 6., 7., 8., 5., 6., 7., 8.);
+        let r = _mm256_hadd_ps(a, b);
+        let e = _mm256_setr_ps(3., 7., 11., 15., 3., 7., 11., 15.);
+        assert_eq_m256(r, e);
+    }
+    test_mm256_hadd_ps();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_hsub_pd() {
+        let a = _mm256_setr_pd(4., 9., 16., 25.);
+        let b = _mm256_setr_pd(4., 3., 2., 5.);
+        let r = _mm256_hsub_pd(a, b);
+        let e = _mm256_setr_pd(-5., 1., -9., -3.);
+        assert_eq_m256d(r, e);
+
+        let a = _mm256_setr_pd(1., 2., 3., 4.);
+        let b = _mm256_setr_pd(5., 6., 7., 8.);
+        let r = _mm256_hsub_pd(a, b);
+        let e = _mm256_setr_pd(-1., -1., -1., -1.);
+        assert_eq_m256d(r, e);
+    }
+    test_mm256_hsub_pd();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_hsub_ps() {
+        let a = _mm256_setr_ps(4., 9., 16., 25., 4., 9., 16., 25.);
+        let b = _mm256_setr_ps(4., 3., 2., 5., 8., 9., 64., 50.);
+        let r = _mm256_hsub_ps(a, b);
+        let e = _mm256_setr_ps(-5., -9., 1., -3., -5., -9., -1., 14.);
+        assert_eq_m256(r, e);
+
+        let a = _mm256_setr_ps(1., 2., 3., 4., 1., 2., 3., 4.);
+        let b = _mm256_setr_ps(5., 6., 7., 8., 5., 6., 7., 8.);
+        let r = _mm256_hsub_ps(a, b);
+        let e = _mm256_setr_ps(-1., -1., -1., -1., -1., -1., -1., -1.);
+        assert_eq_m256(r, e);
+    }
+    test_mm256_hsub_ps();
+
     fn expected_cmp<F: PartialOrd>(imm: i32, lhs: F, rhs: F, if_t: F, if_f: F) -> F {
         let res = match imm {
             _CMP_EQ_OQ => lhs == rhs,
@@ -136,11 +658,53 @@ unsafe fn test_avx() {
     }
 
     #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_cmp_ps<const IMM: i32>() {
+        let values = [
+            (1.0, 1.0),
+            (0.0, 1.0),
+            (1.0, 0.0),
+            (f32::NAN, 0.0),
+            (0.0, f32::NAN),
+            (f32::NAN, f32::NAN),
+        ];
+
+        for (lhs, rhs) in values {
+            let a = _mm256_set1_ps(lhs);
+            let b = _mm256_set1_ps(rhs);
+            let r: [u32; 8] = transmute(_mm256_cmp_ps::<IMM>(a, b));
+            let e: [u32; 8] = transmute(_mm256_set1_ps(expected_cmp_f32(IMM, lhs, rhs)));
+            assert_eq!(r, e);
+        }
+    }
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_cmp_pd<const IMM: i32>() {
+        let values = [
+            (1.0, 1.0),
+            (0.0, 1.0),
+            (1.0, 0.0),
+            (f64::NAN, 0.0),
+            (0.0, f64::NAN),
+            (f64::NAN, f64::NAN),
+        ];
+
+        for (lhs, rhs) in values {
+            let a = _mm256_set1_pd(lhs);
+            let b = _mm256_set1_pd(rhs);
+            let r: [u64; 4] = transmute(_mm256_cmp_pd::<IMM>(a, b));
+            let e: [u64; 4] = transmute(_mm256_set1_pd(expected_cmp_f64(IMM, lhs, rhs)));
+            assert_eq!(r, e);
+        }
+    }
+
+    #[target_feature(enable = "avx")]
     unsafe fn test_cmp<const IMM: i32>() {
         test_mm_cmp_ss::<IMM>();
         test_mm_cmp_ps::<IMM>();
         test_mm_cmp_sd::<IMM>();
         test_mm_cmp_pd::<IMM>();
+        test_mm256_cmp_ps::<IMM>();
+        test_mm256_cmp_pd::<IMM>();
     }
 
     test_cmp::<_CMP_EQ_OQ>();
@@ -159,4 +723,709 @@ unsafe fn test_avx() {
     test_cmp::<_CMP_GE_OS>();
     test_cmp::<_CMP_GT_OS>();
     test_cmp::<_CMP_TRUE_US>();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_cvtps_epi32() {
+        let a = _mm256_setr_ps(4., 9., 16., 25., 4., 9., 16., 25.);
+        let r = _mm256_cvtps_epi32(a);
+        let e = _mm256_setr_epi32(4, 9, 16, 25, 4, 9, 16, 25);
+        assert_eq_m256i(r, e);
+
+        let a = _mm256_setr_ps(
+            f32::NEG_INFINITY,
+            f32::INFINITY,
+            f32::MIN,
+            f32::MAX,
+            f32::NAN,
+            f32::NAN,
+            f32::NAN,
+            f32::NAN,
+        );
+        let r = _mm256_cvtps_epi32(a);
+        assert_eq_m256i(r, _mm256_set1_epi32(i32::MIN));
+    }
+    test_mm256_cvtps_epi32();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_cvttps_epi32() {
+        let a = _mm256_setr_ps(4., 9., 16., 25., 4., 9., 16., 25.);
+        let r = _mm256_cvttps_epi32(a);
+        let e = _mm256_setr_epi32(4, 9, 16, 25, 4, 9, 16, 25);
+        assert_eq_m256i(r, e);
+
+        let a = _mm256_setr_ps(
+            f32::NEG_INFINITY,
+            f32::INFINITY,
+            f32::MIN,
+            f32::MAX,
+            f32::NAN,
+            f32::NAN,
+            f32::NAN,
+            f32::NAN,
+        );
+        let r = _mm256_cvttps_epi32(a);
+        assert_eq_m256i(r, _mm256_set1_epi32(i32::MIN));
+    }
+    test_mm256_cvttps_epi32();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_cvtpd_epi32() {
+        let a = _mm256_setr_pd(4., 9., 16., 25.);
+        let r = _mm256_cvtpd_epi32(a);
+        let e = _mm_setr_epi32(4, 9, 16, 25);
+        assert_eq_m128i(r, e);
+
+        let a = _mm256_setr_pd(f64::NEG_INFINITY, f64::INFINITY, f64::MIN, f64::MAX);
+        let r = _mm256_cvtpd_epi32(a);
+        assert_eq_m128i(r, _mm_set1_epi32(i32::MIN));
+    }
+    test_mm256_cvtpd_epi32();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_cvttpd_epi32() {
+        let a = _mm256_setr_pd(4., 9., 16., 25.);
+        let r = _mm256_cvttpd_epi32(a);
+        let e = _mm_setr_epi32(4, 9, 16, 25);
+        assert_eq_m128i(r, e);
+
+        let a = _mm256_setr_pd(f64::NEG_INFINITY, f64::INFINITY, f64::MIN, f64::MAX);
+        let r = _mm256_cvttpd_epi32(a);
+        assert_eq_m128i(r, _mm_set1_epi32(i32::MIN));
+    }
+    test_mm256_cvttpd_epi32();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm_permutevar_ps() {
+        let a = _mm_setr_ps(4., 3., 2., 5.);
+        let b = _mm_setr_epi32(1, 2, 3, 4);
+        let r = _mm_permutevar_ps(a, b);
+        let e = _mm_setr_ps(3., 2., 5., 4.);
+        assert_eq_m128(r, e);
+    }
+    test_mm_permutevar_ps();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_permutevar_ps() {
+        let a = _mm256_setr_ps(4., 3., 2., 5., 8., 9., 64., 50.);
+        let b = _mm256_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8);
+        let r = _mm256_permutevar_ps(a, b);
+        let e = _mm256_setr_ps(3., 2., 5., 4., 9., 64., 50., 8.);
+        assert_eq_m256(r, e);
+    }
+    test_mm256_permutevar_ps();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm_permutevar_pd() {
+        let a = _mm_setr_pd(4., 3.);
+        let b = _mm_setr_epi64x(3, 0);
+        let r = _mm_permutevar_pd(a, b);
+        let e = _mm_setr_pd(3., 4.);
+        assert_eq_m128d(r, e);
+    }
+    test_mm_permutevar_pd();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_permutevar_pd() {
+        let a = _mm256_setr_pd(4., 3., 2., 5.);
+        let b = _mm256_setr_epi64x(1, 2, 3, 4);
+        let r = _mm256_permutevar_pd(a, b);
+        let e = _mm256_setr_pd(4., 3., 5., 2.);
+        assert_eq_m256d(r, e);
+    }
+    test_mm256_permutevar_pd();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_permute2f128_ps() {
+        let a = _mm256_setr_ps(1., 2., 3., 4., 1., 2., 3., 4.);
+        let b = _mm256_setr_ps(5., 6., 7., 8., 5., 6., 7., 8.);
+        let r = _mm256_permute2f128_ps::<0x13>(a, b);
+        let e = _mm256_setr_ps(5., 6., 7., 8., 1., 2., 3., 4.);
+        assert_eq_m256(r, e);
+
+        let r = _mm256_permute2f128_ps::<0x44>(a, b);
+        let e = _mm256_setr_ps(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+        assert_eq_m256(r, e);
+    }
+    test_mm256_permute2f128_ps();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_permute2f128_pd() {
+        let a = _mm256_setr_pd(1., 2., 3., 4.);
+        let b = _mm256_setr_pd(5., 6., 7., 8.);
+        let r = _mm256_permute2f128_pd::<0x31>(a, b);
+        let e = _mm256_setr_pd(3., 4., 7., 8.);
+        assert_eq_m256d(r, e);
+
+        let r = _mm256_permute2f128_pd::<0x44>(a, b);
+        let e = _mm256_setr_pd(0.0, 0.0, 0.0, 0.0);
+        assert_eq_m256d(r, e);
+    }
+    test_mm256_permute2f128_pd();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_permute2f128_si256() {
+        let a = _mm256_setr_epi32(1, 2, 3, 4, 1, 2, 3, 4);
+        let b = _mm256_setr_epi32(5, 6, 7, 8, 5, 6, 7, 8);
+        let r = _mm256_permute2f128_si256::<0x20>(a, b);
+        let e = _mm256_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8);
+        assert_eq_m256i(r, e);
+
+        let r = _mm256_permute2f128_si256::<0x44>(a, b);
+        let e = _mm256_setr_epi32(0, 0, 0, 0, 0, 0, 0, 0);
+        assert_eq_m256i(r, e);
+    }
+    test_mm256_permute2f128_si256();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm_maskload_ps() {
+        let a = &[1.0f32, 2., 3., 4.];
+        let mask = _mm_setr_epi32(0, !0, 0, !0);
+        let r = _mm_maskload_ps(a.as_ptr(), mask);
+        let e = _mm_setr_ps(0., 2., 0., 4.);
+        assert_eq_m128(r, e);
+
+        // Unaligned pointer
+        let a = Unaligned::new([1.0f32, 2., 3., 4.]);
+        let mask = _mm_setr_epi32(0, !0, 0, !0);
+        let r = _mm_maskload_ps(a.as_ptr().cast(), mask);
+        let e = _mm_setr_ps(0., 2., 0., 4.);
+        assert_eq_m128(r, e);
+
+        // Only loading first element, so slice can be short.
+        let a = &[2.0f32];
+        let mask = _mm_setr_epi32(!0, 0, 0, 0);
+        let r = _mm_maskload_ps(a.as_ptr(), mask);
+        let e = _mm_setr_ps(2.0, 0.0, 0.0, 0.0);
+        assert_eq_m128(r, e);
+
+        // Only loading last element, so slice can be short.
+        let a = &[2.0f32];
+        let mask = _mm_setr_epi32(0, 0, 0, !0);
+        let r = _mm_maskload_ps(a.as_ptr().wrapping_sub(3), mask);
+        let e = _mm_setr_ps(0.0, 0.0, 0.0, 2.0);
+        assert_eq_m128(r, e);
+    }
+    test_mm_maskload_ps();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm_maskload_pd() {
+        let a = &[1.0f64, 2.];
+        let mask = _mm_setr_epi64x(0, !0);
+        let r = _mm_maskload_pd(a.as_ptr(), mask);
+        let e = _mm_setr_pd(0., 2.);
+        assert_eq_m128d(r, e);
+
+        // Unaligned pointer
+        let a = Unaligned::new([1.0f64, 2.]);
+        let mask = _mm_setr_epi64x(0, !0);
+        let r = _mm_maskload_pd(a.as_ptr().cast(), mask);
+        let e = _mm_setr_pd(0., 2.);
+        assert_eq_m128d(r, e);
+
+        // Only loading first element, so slice can be short.
+        let a = &[2.0f64];
+        let mask = _mm_setr_epi64x(!0, 0);
+        let r = _mm_maskload_pd(a.as_ptr(), mask);
+        let e = _mm_setr_pd(2.0, 0.0);
+        assert_eq_m128d(r, e);
+
+        // Only loading last element, so slice can be short.
+        let a = &[2.0f64];
+        let mask = _mm_setr_epi64x(0, !0);
+        let r = _mm_maskload_pd(a.as_ptr().wrapping_sub(1), mask);
+        let e = _mm_setr_pd(0.0, 2.0);
+        assert_eq_m128d(r, e);
+    }
+    test_mm_maskload_pd();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_maskload_ps() {
+        let a = &[1.0f32, 2., 3., 4., 5., 6., 7., 8.];
+        let mask = _mm256_setr_epi32(0, !0, 0, !0, 0, !0, 0, !0);
+        let r = _mm256_maskload_ps(a.as_ptr(), mask);
+        let e = _mm256_setr_ps(0., 2., 0., 4., 0., 6., 0., 8.);
+        assert_eq_m256(r, e);
+
+        // Unaligned pointer
+        let a = Unaligned::new([1.0f32, 2., 3., 4., 5., 6., 7., 8.]);
+        let mask = _mm256_setr_epi32(0, !0, 0, !0, 0, !0, 0, !0);
+        let r = _mm256_maskload_ps(a.as_ptr().cast(), mask);
+        let e = _mm256_setr_ps(0., 2., 0., 4., 0., 6., 0., 8.);
+        assert_eq_m256(r, e);
+
+        // Only loading first element, so slice can be short.
+        let a = &[2.0f32];
+        let mask = _mm256_setr_epi32(!0, 0, 0, 0, 0, 0, 0, 0);
+        let r = _mm256_maskload_ps(a.as_ptr(), mask);
+        let e = _mm256_setr_ps(2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+        assert_eq_m256(r, e);
+
+        // Only loading last element, so slice can be short.
+        let a = &[2.0f32];
+        let mask = _mm256_setr_epi32(0, 0, 0, 0, 0, 0, 0, !0);
+        let r = _mm256_maskload_ps(a.as_ptr().wrapping_sub(7), mask);
+        let e = _mm256_setr_ps(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0);
+        assert_eq_m256(r, e);
+    }
+    test_mm256_maskload_ps();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_maskload_pd() {
+        let a = &[1.0f64, 2., 3., 4.];
+        let mask = _mm256_setr_epi64x(0, !0, 0, !0);
+        let r = _mm256_maskload_pd(a.as_ptr(), mask);
+        let e = _mm256_setr_pd(0., 2., 0., 4.);
+        assert_eq_m256d(r, e);
+
+        // Unaligned pointer
+        let a = Unaligned::new([1.0f64, 2., 3., 4.]);
+        let mask = _mm256_setr_epi64x(0, !0, 0, !0);
+        let r = _mm256_maskload_pd(a.as_ptr().cast(), mask);
+        let e = _mm256_setr_pd(0., 2., 0., 4.);
+        assert_eq_m256d(r, e);
+
+        // Only loading first element, so slice can be short.
+        let a = &[2.0f64];
+        let mask = _mm256_setr_epi64x(!0, 0, 0, 0);
+        let r = _mm256_maskload_pd(a.as_ptr(), mask);
+        let e = _mm256_setr_pd(2.0, 0.0, 0.0, 0.0);
+        assert_eq_m256d(r, e);
+
+        // Only loading last element, so slice can be short.
+        let a = &[2.0f64];
+        let mask = _mm256_setr_epi64x(0, 0, 0, !0);
+        let r = _mm256_maskload_pd(a.as_ptr().wrapping_sub(3), mask);
+        let e = _mm256_setr_pd(0.0, 0.0, 0.0, 2.0);
+        assert_eq_m256d(r, e);
+    }
+    test_mm256_maskload_pd();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm_maskstore_ps() {
+        let mut r = _mm_set1_ps(0.);
+        let mask = _mm_setr_epi32(0, !0, 0, !0);
+        let a = _mm_setr_ps(1., 2., 3., 4.);
+        _mm_maskstore_ps(&mut r as *mut _ as *mut f32, mask, a);
+        let e = _mm_setr_ps(0., 2., 0., 4.);
+        assert_eq_m128(r, e);
+
+        // Unaligned pointer
+        let mut r = Unaligned::new([0.0f32; 4]);
+        let mask = _mm_setr_epi32(0, !0, 0, !0);
+        let a = _mm_setr_ps(1., 2., 3., 4.);
+        _mm_maskstore_ps(r.as_mut_ptr().cast(), mask, a);
+        let e = [0., 2., 0., 4.];
+        assert_eq!(r.read(), e);
+
+        // Only storing first element, so slice can be short.
+        let mut r = [0.0f32];
+        let mask = _mm_setr_epi32(!0, 0, 0, 0);
+        let a = _mm_setr_ps(1., 2., 3., 4.);
+        _mm_maskstore_ps(r.as_mut_ptr(), mask, a);
+        let e = [1.0f32];
+        assert_eq!(r, e);
+
+        // Only storing last element, so slice can be short.
+        let mut r = [0.0f32];
+        let mask = _mm_setr_epi32(0, 0, 0, !0);
+        let a = _mm_setr_ps(1., 2., 3., 4.);
+        _mm_maskstore_ps(r.as_mut_ptr().wrapping_sub(3), mask, a);
+        let e = [4.0f32];
+        assert_eq!(r, e);
+    }
+    test_mm_maskstore_ps();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm_maskstore_pd() {
+        let mut r = _mm_set1_pd(0.);
+        let mask = _mm_setr_epi64x(0, !0);
+        let a = _mm_setr_pd(1., 2.);
+        _mm_maskstore_pd(&mut r as *mut _ as *mut f64, mask, a);
+        let e = _mm_setr_pd(0., 2.);
+        assert_eq_m128d(r, e);
+
+        // Unaligned pointer
+        let mut r = Unaligned::new([0.0f64; 2]);
+        let mask = _mm_setr_epi64x(0, !0);
+        let a = _mm_setr_pd(1., 2.);
+        _mm_maskstore_pd(r.as_mut_ptr().cast(), mask, a);
+        let e = [0., 2.];
+        assert_eq!(r.read(), e);
+
+        // Only storing first element, so slice can be short.
+        let mut r = [0.0f64];
+        let mask = _mm_setr_epi64x(!0, 0);
+        let a = _mm_setr_pd(1., 2.);
+        _mm_maskstore_pd(r.as_mut_ptr(), mask, a);
+        let e = [1.0f64];
+        assert_eq!(r, e);
+
+        // Only storing last element, so slice can be short.
+        let mut r = [0.0f64];
+        let mask = _mm_setr_epi64x(0, !0);
+        let a = _mm_setr_pd(1., 2.);
+        _mm_maskstore_pd(r.as_mut_ptr().wrapping_sub(1), mask, a);
+        let e = [2.0f64];
+        assert_eq!(r, e);
+    }
+    test_mm_maskstore_pd();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_maskstore_ps() {
+        let mut r = _mm256_set1_ps(0.);
+        let mask = _mm256_setr_epi32(0, !0, 0, !0, 0, !0, 0, !0);
+        let a = _mm256_setr_ps(1., 2., 3., 4., 5., 6., 7., 8.);
+        _mm256_maskstore_ps(&mut r as *mut _ as *mut f32, mask, a);
+        let e = _mm256_setr_ps(0., 2., 0., 4., 0., 6., 0., 8.);
+        assert_eq_m256(r, e);
+
+        // Unaligned pointer
+        let mut r = Unaligned::new([0.0f32; 8]);
+        let mask = _mm256_setr_epi32(0, !0, 0, !0, 0, !0, 0, !0);
+        let a = _mm256_setr_ps(1., 2., 3., 4., 5., 6., 7., 8.);
+        _mm256_maskstore_ps(r.as_mut_ptr().cast(), mask, a);
+        let e = [0., 2., 0., 4., 0., 6., 0., 8.];
+        assert_eq!(r.read(), e);
+
+        // Only storing first element, so slice can be short.
+        let mut r = [0.0f32];
+        let mask = _mm256_setr_epi32(!0, 0, 0, 0, 0, 0, 0, 0);
+        let a = _mm256_setr_ps(1., 2., 3., 4., 5., 6., 7., 8.);
+        _mm256_maskstore_ps(r.as_mut_ptr(), mask, a);
+        let e = [1.0f32];
+        assert_eq!(r, e);
+
+        // Only storing last element, so slice can be short.
+        let mut r = [0.0f32];
+        let mask = _mm256_setr_epi32(0, 0, 0, 0, 0, 0, 0, !0);
+        let a = _mm256_setr_ps(1., 2., 3., 4., 5., 6., 7., 8.);
+        _mm256_maskstore_ps(r.as_mut_ptr().wrapping_sub(7), mask, a);
+        let e = [8.0f32];
+        assert_eq!(r, e);
+    }
+    test_mm256_maskstore_ps();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_maskstore_pd() {
+        let mut r = _mm256_set1_pd(0.);
+        let mask = _mm256_setr_epi64x(0, !0, 0, !0);
+        let a = _mm256_setr_pd(1., 2., 3., 4.);
+        _mm256_maskstore_pd(&mut r as *mut _ as *mut f64, mask, a);
+        let e = _mm256_setr_pd(0., 2., 0., 4.);
+        assert_eq_m256d(r, e);
+
+        // Unaligned pointer
+        let mut r = Unaligned::new([0.0f64; 4]);
+        let mask = _mm256_setr_epi64x(0, !0, 0, !0);
+        let a = _mm256_setr_pd(1., 2., 3., 4.);
+        _mm256_maskstore_pd(r.as_mut_ptr().cast(), mask, a);
+        let e = [0., 2., 0., 4.];
+        assert_eq!(r.read(), e);
+
+        // Only storing first element, so slice can be short.
+        let mut r = [0.0f64];
+        let mask = _mm256_setr_epi64x(!0, 0, 0, 0);
+        let a = _mm256_setr_pd(1., 2., 3., 4.);
+        _mm256_maskstore_pd(r.as_mut_ptr(), mask, a);
+        let e = [1.0f64];
+        assert_eq!(r, e);
+
+        // Only storing last element, so slice can be short.
+        let mut r = [0.0f64];
+        let mask = _mm256_setr_epi64x(0, 0, 0, !0);
+        let a = _mm256_setr_pd(1., 2., 3., 4.);
+        _mm256_maskstore_pd(r.as_mut_ptr().wrapping_sub(3), mask, a);
+        let e = [4.0f64];
+        assert_eq!(r, e);
+    }
+    test_mm256_maskstore_pd();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_lddqu_si256() {
+        #[rustfmt::skip]
+        let a = _mm256_setr_epi8(
+            1, 2, 3, 4, 5, 6, 7, 8,
+            9, 10, 11, 12, 13, 14, 15, 16,
+            17, 18, 19, 20, 21, 22, 23, 24,
+            25, 26, 27, 28, 29, 30, 31, 32,
+        );
+        let p = &a as *const _;
+        let r = _mm256_lddqu_si256(p);
+        #[rustfmt::skip]
+        let e = _mm256_setr_epi8(
+            1, 2, 3, 4, 5, 6, 7, 8,
+            9, 10, 11, 12, 13, 14, 15, 16,
+            17, 18, 19, 20, 21, 22, 23, 24,
+            25, 26, 27, 28, 29, 30, 31, 32,
+        );
+        assert_eq_m256i(r, e);
+    }
+    test_mm256_lddqu_si256();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_testz_si256() {
+        let a = _mm256_setr_epi64x(1, 2, 3, 4);
+        let b = _mm256_setr_epi64x(5, 6, 7, 8);
+        let r = _mm256_testz_si256(a, b);
+        assert_eq!(r, 0);
+        let b = _mm256_set1_epi64x(0);
+        let r = _mm256_testz_si256(a, b);
+        assert_eq!(r, 1);
+    }
+    test_mm256_testz_si256();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_testc_si256() {
+        let a = _mm256_setr_epi64x(1, 2, 3, 4);
+        let b = _mm256_setr_epi64x(5, 6, 7, 8);
+        let r = _mm256_testc_si256(a, b);
+        assert_eq!(r, 0);
+        let b = _mm256_set1_epi64x(0);
+        let r = _mm256_testc_si256(a, b);
+        assert_eq!(r, 1);
+    }
+    test_mm256_testc_si256();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_testnzc_si256() {
+        let a = _mm256_setr_epi64x(1, 2, 3, 4);
+        let b = _mm256_setr_epi64x(5, 6, 7, 8);
+        let r = _mm256_testnzc_si256(a, b);
+        assert_eq!(r, 1);
+        let a = _mm256_setr_epi64x(0, 0, 0, 0);
+        let b = _mm256_setr_epi64x(0, 0, 0, 0);
+        let r = _mm256_testnzc_si256(a, b);
+        assert_eq!(r, 0);
+    }
+    test_mm256_testnzc_si256();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_testz_pd() {
+        let a = _mm256_setr_pd(1., 2., 3., 4.);
+        let b = _mm256_setr_pd(5., 6., 7., 8.);
+        let r = _mm256_testz_pd(a, b);
+        assert_eq!(r, 1);
+        let a = _mm256_set1_pd(-1.);
+        let r = _mm256_testz_pd(a, a);
+        assert_eq!(r, 0);
+    }
+    test_mm256_testz_pd();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_testc_pd() {
+        let a = _mm256_setr_pd(1., 2., 3., 4.);
+        let b = _mm256_setr_pd(5., 6., 7., 8.);
+        let r = _mm256_testc_pd(a, b);
+        assert_eq!(r, 1);
+        let a = _mm256_set1_pd(1.);
+        let b = _mm256_set1_pd(-1.);
+        let r = _mm256_testc_pd(a, b);
+        assert_eq!(r, 0);
+    }
+    test_mm256_testc_pd();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_testnzc_pd() {
+        let a = _mm256_setr_pd(1., 2., 3., 4.);
+        let b = _mm256_setr_pd(5., 6., 7., 8.);
+        let r = _mm256_testnzc_pd(a, b);
+        assert_eq!(r, 0);
+        let a = _mm256_setr_pd(1., -1., -1., -1.);
+        let b = _mm256_setr_pd(-1., -1., 1., 1.);
+        let r = _mm256_testnzc_pd(a, b);
+        assert_eq!(r, 1);
+    }
+    test_mm256_testnzc_pd();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm_testz_pd() {
+        let a = _mm_setr_pd(1., 2.);
+        let b = _mm_setr_pd(5., 6.);
+        let r = _mm_testz_pd(a, b);
+        assert_eq!(r, 1);
+        let a = _mm_set1_pd(-1.);
+        let r = _mm_testz_pd(a, a);
+        assert_eq!(r, 0);
+    }
+    test_mm_testz_pd();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm_testc_pd() {
+        let a = _mm_setr_pd(1., 2.);
+        let b = _mm_setr_pd(5., 6.);
+        let r = _mm_testc_pd(a, b);
+        assert_eq!(r, 1);
+        let a = _mm_set1_pd(1.);
+        let b = _mm_set1_pd(-1.);
+        let r = _mm_testc_pd(a, b);
+        assert_eq!(r, 0);
+    }
+    test_mm_testc_pd();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm_testnzc_pd() {
+        let a = _mm_setr_pd(1., 2.);
+        let b = _mm_setr_pd(5., 6.);
+        let r = _mm_testnzc_pd(a, b);
+        assert_eq!(r, 0);
+        let a = _mm_setr_pd(1., -1.);
+        let b = _mm_setr_pd(-1., -1.);
+        let r = _mm_testnzc_pd(a, b);
+        assert_eq!(r, 1);
+    }
+    test_mm_testnzc_pd();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_testz_ps() {
+        let a = _mm256_set1_ps(1.);
+        let r = _mm256_testz_ps(a, a);
+        assert_eq!(r, 1);
+        let a = _mm256_set1_ps(-1.);
+        let r = _mm256_testz_ps(a, a);
+        assert_eq!(r, 0);
+    }
+    test_mm256_testz_ps();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_testc_ps() {
+        let a = _mm256_set1_ps(1.);
+        let r = _mm256_testc_ps(a, a);
+        assert_eq!(r, 1);
+        let b = _mm256_set1_ps(-1.);
+        let r = _mm256_testc_ps(a, b);
+        assert_eq!(r, 0);
+    }
+    test_mm256_testc_ps();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm256_testnzc_ps() {
+        let a = _mm256_set1_ps(1.);
+        let r = _mm256_testnzc_ps(a, a);
+        assert_eq!(r, 0);
+        let a = _mm256_setr_ps(1., -1., -1., -1., -1., -1., -1., -1.);
+        let b = _mm256_setr_ps(-1., -1., 1., 1., 1., 1., 1., 1.);
+        let r = _mm256_testnzc_ps(a, b);
+        assert_eq!(r, 1);
+    }
+    test_mm256_testnzc_ps();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm_testz_ps() {
+        let a = _mm_set1_ps(1.);
+        let r = _mm_testz_ps(a, a);
+        assert_eq!(r, 1);
+        let a = _mm_set1_ps(-1.);
+        let r = _mm_testz_ps(a, a);
+        assert_eq!(r, 0);
+    }
+    test_mm_testz_ps();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm_testc_ps() {
+        let a = _mm_set1_ps(1.);
+        let r = _mm_testc_ps(a, a);
+        assert_eq!(r, 1);
+        let b = _mm_set1_ps(-1.);
+        let r = _mm_testc_ps(a, b);
+        assert_eq!(r, 0);
+    }
+    test_mm_testc_ps();
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm_testnzc_ps() {
+        let a = _mm_set1_ps(1.);
+        let r = _mm_testnzc_ps(a, a);
+        assert_eq!(r, 0);
+        let a = _mm_setr_ps(1., -1., -1., -1.);
+        let b = _mm_setr_ps(-1., -1., 1., 1.);
+        let r = _mm_testnzc_ps(a, b);
+        assert_eq!(r, 1);
+    }
+    test_mm_testnzc_ps();
+}
+
+#[target_feature(enable = "sse2")]
+unsafe fn _mm_setr_epi64x(a: i64, b: i64) -> __m128i {
+    _mm_set_epi64x(b, a)
+}
+
+#[track_caller]
+#[target_feature(enable = "sse")]
+unsafe fn assert_eq_m128(a: __m128, b: __m128) {
+    let r = _mm_cmpeq_ps(a, b);
+    if _mm_movemask_ps(r) != 0b1111 {
+        panic!("{:?} != {:?}", a, b);
+    }
+}
+
+#[track_caller]
+#[target_feature(enable = "sse2")]
+unsafe fn assert_eq_m128d(a: __m128d, b: __m128d) {
+    if _mm_movemask_pd(_mm_cmpeq_pd(a, b)) != 0b11 {
+        panic!("{:?} != {:?}", a, b);
+    }
+}
+
+#[track_caller]
+#[target_feature(enable = "sse2")]
+unsafe fn assert_eq_m128i(a: __m128i, b: __m128i) {
+    assert_eq!(transmute::<_, [u64; 2]>(a), transmute::<_, [u64; 2]>(b))
+}
+
+#[track_caller]
+#[target_feature(enable = "avx")]
+unsafe fn assert_eq_m256(a: __m256, b: __m256) {
+    let cmp = _mm256_cmp_ps::<_CMP_EQ_OQ>(a, b);
+    if _mm256_movemask_ps(cmp) != 0b11111111 {
+        panic!("{:?} != {:?}", a, b);
+    }
+}
+
+#[track_caller]
+#[target_feature(enable = "avx")]
+unsafe fn assert_eq_m256d(a: __m256d, b: __m256d) {
+    let cmp = _mm256_cmp_pd::<_CMP_EQ_OQ>(a, b);
+    if _mm256_movemask_pd(cmp) != 0b1111 {
+        panic!("{:?} != {:?}", a, b);
+    }
+}
+
+#[track_caller]
+#[target_feature(enable = "avx")]
+unsafe fn assert_eq_m256i(a: __m256i, b: __m256i) {
+    assert_eq!(transmute::<_, [u64; 4]>(a), transmute::<_, [u64; 4]>(b))
+}
+
+/// Stores `T` in an unaligned address
+struct Unaligned<T: Copy> {
+    buf: Vec<u8>,
+    offset: bool,
+    _marker: std::marker::PhantomData<T>,
+}
+
+impl<T: Copy> Unaligned<T> {
+    fn new(value: T) -> Self {
+        // Allocate extra byte for unalignment headroom
+        let len = std::mem::size_of::<T>();
+        let mut buf = Vec::<u8>::with_capacity(len + 1);
+        // Force the address to be a non-multiple of 2, so it is as unaligned as it can get.
+        let offset = (buf.as_ptr() as usize % 2) == 0;
+        let value_ptr: *const T = &value;
+        unsafe {
+            buf.as_mut_ptr().add(offset.into()).copy_from_nonoverlapping(value_ptr.cast(), len);
+        }
+        Self { buf, offset, _marker: std::marker::PhantomData }
+    }
+
+    fn as_ptr(&self) -> *const T {
+        unsafe { self.buf.as_ptr().add(self.offset.into()).cast() }
+    }
+
+    fn as_mut_ptr(&mut self) -> *mut T {
+        unsafe { self.buf.as_mut_ptr().add(self.offset.into()).cast() }
+    }
+
+    fn read(&self) -> T {
+        unsafe { self.as_ptr().read_unaligned() }
+    }
 }
diff --git a/src/tools/miri/tests/pass/overflow_checks_off.rs b/src/tools/miri/tests/pass/overflow_checks_off.rs
index 79aa510ef97..7b9d4f8fff5 100644
--- a/src/tools/miri/tests/pass/overflow_checks_off.rs
+++ b/src/tools/miri/tests/pass/overflow_checks_off.rs
@@ -1,12 +1,17 @@
 //@compile-flags: -C overflow-checks=off
 
 // Check that we correctly implement the intended behavior of these operators
-// when they are not being overflow-checked.
+// when they are not being overflow-checked at runtime.
 
 // FIXME: if we call the functions in `std::ops`, we still get the panics.
 // Miri does not implement the codegen-time hack that backs `#[rustc_inherit_overflow_checks]`.
 // use std::ops::*;
 
+
+// Disable _compile-time_ overflow linting
+// so that we can test runtime overflow checks
+ #![allow(arithmetic_overflow)]
+
 fn main() {
     assert_eq!(-{ -0x80i8 }, -0x80);
 
diff --git a/tests/coverage/closure_unit_return.cov-map b/tests/coverage/closure_unit_return.cov-map
new file mode 100644
index 00000000000..c97b4a44dd6
--- /dev/null
+++ b/tests/coverage/closure_unit_return.cov-map
@@ -0,0 +1,34 @@
+Function name: closure_unit_return::explicit_unit
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 07, 01, 01, 10, 01, 05, 05, 02, 02]
+Number of files: 1
+- file 0 => global file 1
+Number of expressions: 0
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 7, 1) to (start + 1, 16)
+- Code(Counter(0)) at (prev + 5, 5) to (start + 2, 2)
+
+Function name: closure_unit_return::explicit_unit::{closure#0} (unused)
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 08, 16, 02, 06]
+Number of files: 1
+- file 0 => global file 1
+Number of expressions: 0
+Number of file 0 mappings: 1
+- Code(Zero) at (prev + 8, 22) to (start + 2, 6)
+
+Function name: closure_unit_return::implicit_unit
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 10, 01, 01, 10, 01, 05, 05, 02, 02]
+Number of files: 1
+- file 0 => global file 1
+Number of expressions: 0
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 16, 1) to (start + 1, 16)
+- Code(Counter(0)) at (prev + 5, 5) to (start + 2, 2)
+
+Function name: closure_unit_return::implicit_unit::{closure#0} (unused)
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 11, 16, 02, 06]
+Number of files: 1
+- file 0 => global file 1
+Number of expressions: 0
+Number of file 0 mappings: 1
+- Code(Zero) at (prev + 17, 22) to (start + 2, 6)
+
diff --git a/tests/coverage/closure_unit_return.coverage b/tests/coverage/closure_unit_return.coverage
new file mode 100644
index 00000000000..1056baa385c
--- /dev/null
+++ b/tests/coverage/closure_unit_return.coverage
@@ -0,0 +1,30 @@
+   LL|       |#![feature(coverage_attribute)]
+   LL|       |// edition: 2021
+   LL|       |
+   LL|       |// Regression test for an inconsistency between functions that return the value
+   LL|       |// of their trailing expression, and functions that implicitly return `()`.
+   LL|       |
+   LL|      1|fn explicit_unit() {
+   LL|      1|    let closure = || {
+   LL|      0|        ();
+   LL|      0|    };
+   LL|       |
+   LL|      1|    drop(closure);
+   LL|      1|    () // explicit return of trailing value
+   LL|      1|}
+   LL|       |
+   LL|      1|fn implicit_unit() {
+   LL|      1|    let closure = || {
+   LL|      0|        ();
+   LL|      0|    };
+   LL|       |
+   LL|      1|    drop(closure);
+   LL|      1|    // implicit return of `()`
+   LL|      1|}
+   LL|       |
+   LL|       |#[coverage(off)]
+   LL|       |fn main() {
+   LL|       |    explicit_unit();
+   LL|       |    implicit_unit();
+   LL|       |}
+
diff --git a/tests/coverage/closure_unit_return.rs b/tests/coverage/closure_unit_return.rs
new file mode 100644
index 00000000000..d2b4ab8bd9f
--- /dev/null
+++ b/tests/coverage/closure_unit_return.rs
@@ -0,0 +1,29 @@
+#![feature(coverage_attribute)]
+// edition: 2021
+
+// Regression test for an inconsistency between functions that return the value
+// of their trailing expression, and functions that implicitly return `()`.
+
+fn explicit_unit() {
+    let closure = || {
+        ();
+    };
+
+    drop(closure);
+    () // explicit return of trailing value
+}
+
+fn implicit_unit() {
+    let closure = || {
+        ();
+    };
+
+    drop(closure);
+    // implicit return of `()`
+}
+
+#[coverage(off)]
+fn main() {
+    explicit_unit();
+    implicit_unit();
+}
diff --git a/tests/coverage/coverage_attr_closure.cov-map b/tests/coverage/coverage_attr_closure.cov-map
index 2208b28fd41..5d2c6b00b40 100644
--- a/tests/coverage/coverage_attr_closure.cov-map
+++ b/tests/coverage/coverage_attr_closure.cov-map
@@ -15,14 +15,14 @@ Number of file 0 mappings: 1
 - Code(Zero) at (prev + 29, 19) to (start + 2, 6)
 
 Function name: coverage_attr_closure::contains_closures_on
-Raw bytes (19): 0x[01, 01, 00, 03, 01, 0f, 01, 02, 05, 01, 04, 06, 02, 05, 01, 04, 06, 01, 02]
+Raw bytes (19): 0x[01, 01, 00, 03, 01, 0f, 01, 01, 1a, 01, 05, 09, 00, 1b, 01, 04, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 15, 1) to (start + 2, 5)
-- Code(Counter(0)) at (prev + 4, 6) to (start + 2, 5)
-- Code(Counter(0)) at (prev + 4, 6) to (start + 1, 2)
+- Code(Counter(0)) at (prev + 15, 1) to (start + 1, 26)
+- Code(Counter(0)) at (prev + 5, 9) to (start + 0, 27)
+- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 2)
 
 Function name: coverage_attr_closure::contains_closures_on::{closure#0} (unused)
 Raw bytes (9): 0x[01, 01, 00, 01, 00, 11, 13, 02, 06]
diff --git a/tests/coverage/coverage_attr_closure.coverage b/tests/coverage/coverage_attr_closure.coverage
index 32c75b40d83..3474ad65063 100644
--- a/tests/coverage/coverage_attr_closure.coverage
+++ b/tests/coverage/coverage_attr_closure.coverage
@@ -14,13 +14,13 @@
    LL|       |#[coverage(on)]
    LL|      1|fn contains_closures_on() {
    LL|      1|    let _local_closure_on = #[coverage(on)]
-   LL|      1|    |input: &str| {
+   LL|      0|    |input: &str| {
    LL|      0|        println!("{input}");
-   LL|      1|    };
+   LL|      0|    };
    LL|      1|    let _local_closure_off = #[coverage(off)]
-   LL|      1|    |input: &str| {
+   LL|       |    |input: &str| {
    LL|       |        println!("{input}");
-   LL|      1|    };
+   LL|       |    };
    LL|      1|}
    LL|       |
    LL|       |#[coverage(off)]
diff --git a/tests/coverage/inline-dead.cov-map b/tests/coverage/inline-dead.cov-map
index c669b7245ea..f77781ca028 100644
--- a/tests/coverage/inline-dead.cov-map
+++ b/tests/coverage/inline-dead.cov-map
@@ -22,13 +22,13 @@ Number of file 0 mappings: 4
     = (Zero + (c0 - Zero))
 
 Function name: inline_dead::main
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 04, 01, 03, 0d, 01, 05, 06, 02, 02]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 04, 01, 03, 0a, 01, 06, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 4, 1) to (start + 3, 13)
-- Code(Counter(0)) at (prev + 5, 6) to (start + 2, 2)
+- Code(Counter(0)) at (prev + 4, 1) to (start + 3, 10)
+- Code(Counter(0)) at (prev + 6, 5) to (start + 1, 2)
 
 Function name: inline_dead::main::{closure#0}
 Raw bytes (23): 0x[01, 01, 02, 00, 06, 01, 00, 03, 01, 07, 17, 01, 16, 00, 01, 17, 00, 18, 03, 01, 05, 00, 06]
diff --git a/tests/coverage/macro_name_span.cov-map b/tests/coverage/macro_name_span.cov-map
index a18e5f14861..f3ee44d2a5a 100644
--- a/tests/coverage/macro_name_span.cov-map
+++ b/tests/coverage/macro_name_span.cov-map
@@ -1,10 +1,10 @@
 Function name: macro_name_span::affected_function
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 16, 1c, 02, 06]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 16, 1c, 01, 40]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 22, 28) to (start + 2, 6)
+- Code(Counter(0)) at (prev + 22, 28) to (start + 1, 64)
 
 Function name: macro_name_span::main
 Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 01, 02, 02]
diff --git a/tests/coverage/macro_name_span.coverage b/tests/coverage/macro_name_span.coverage
index 28c88b1defa..0e12ce4a27c 100644
--- a/tests/coverage/macro_name_span.coverage
+++ b/tests/coverage/macro_name_span.coverage
@@ -21,6 +21,6 @@
    LL|       |macro_name_span_helper::macro_that_defines_a_function! {
    LL|      1|    fn affected_function() {
    LL|      1|        macro_with_an_unreasonably_and_egregiously_long_name!();
-   LL|      1|    }
+   LL|       |    }
    LL|       |}
 
diff --git a/tests/coverage/unicode.cov-map b/tests/coverage/unicode.cov-map
index cd40194a083..aedfb2071c1 100644
--- a/tests/coverage/unicode.cov-map
+++ b/tests/coverage/unicode.cov-map
@@ -27,14 +27,6 @@ Number of file 0 mappings: 9
 - Code(Expression(5, Add)) at (prev + 2, 5) to (start + 1, 2)
     = (c4 + ((((c0 + c1) - c1) - c2) + c3))
 
-Function name: unicode::サビ
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 1e, 14, 00, 18]
-Number of files: 1
-- file 0 => global file 1
-Number of expressions: 0
-Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 30, 20) to (start + 0, 24)
-
 Function name: unicode::他 (unused)
 Raw bytes (9): 0x[01, 01, 00, 01, 00, 1e, 19, 00, 25]
 Number of files: 1
diff --git a/tests/coverage/unicode.coverage b/tests/coverage/unicode.coverage
index b284a557d57..af586111ba3 100644
--- a/tests/coverage/unicode.coverage
+++ b/tests/coverage/unicode.coverage
@@ -29,8 +29,7 @@
    LL|       |
    LL|       |macro_rules! macro_that_defines_a_function {
    LL|       |    (fn $名:ident () $体:tt) => {
-   LL|      1|        fn $名 () $体 fn 他 () {}
-                                      ^0
+   LL|      0|        fn $名 () $体 fn 他 () {}
    LL|       |    }
    LL|       |}
    LL|       |
diff --git a/tests/ui/associated-consts/defaults-cyclic-fail.stderr b/tests/ui/associated-consts/defaults-cyclic-fail.stderr
index 9cee03041fe..31974d95561 100644
--- a/tests/ui/associated-consts/defaults-cyclic-fail.stderr
+++ b/tests/ui/associated-consts/defaults-cyclic-fail.stderr
@@ -20,7 +20,7 @@ note: ...which requires const-evaluating + checking `Tr::B`...
 LL |     const B: u8 = Self::A;
    |                   ^^^^^^^
    = note: ...which again requires simplifying constant for the type system `Tr::A`, completing the cycle
-note: cycle used when const-evaluating + checking `main::promoted[1]`
+note: cycle used when optimizing promoted MIR for `main`
   --> $DIR/defaults-cyclic-fail.rs:16:16
    |
 LL |     assert_eq!(<() as Tr>::A, 0);
diff --git a/tests/ui/associated-consts/defaults-not-assumed-fail.stderr b/tests/ui/associated-consts/defaults-not-assumed-fail.stderr
index 091a50f9463..4b53603cfe8 100644
--- a/tests/ui/associated-consts/defaults-not-assumed-fail.stderr
+++ b/tests/ui/associated-consts/defaults-not-assumed-fail.stderr
@@ -11,6 +11,14 @@ LL |     assert_eq!(<() as Tr>::B, 0);    // causes the error above
    |                ^^^^^^^^^^^^^
 
 note: erroneous constant encountered
+  --> $DIR/defaults-not-assumed-fail.rs:33:16
+   |
+LL |     assert_eq!(<() as Tr>::B, 0);    // causes the error above
+   |                ^^^^^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+note: erroneous constant encountered
   --> $DIR/defaults-not-assumed-fail.rs:33:5
    |
 LL |     assert_eq!(<() as Tr>::B, 0);    // causes the error above
diff --git a/tests/ui/consts/const-err2.noopt.stderr b/tests/ui/consts/const-err2.noopt.stderr
deleted file mode 100644
index 8b1688c4a89..00000000000
--- a/tests/ui/consts/const-err2.noopt.stderr
+++ /dev/null
@@ -1,48 +0,0 @@
-error: this arithmetic operation will overflow
-  --> $DIR/const-err2.rs:19:13
-   |
-LL |     let a = -i8::MIN;
-   |             ^^^^^^^^ attempt to negate `i8::MIN`, which would overflow
-   |
-   = note: `#[deny(arithmetic_overflow)]` on by default
-
-error: this arithmetic operation will overflow
-  --> $DIR/const-err2.rs:21:18
-   |
-LL |     let a_i128 = -i128::MIN;
-   |                  ^^^^^^^^^^ attempt to negate `i128::MIN`, which would overflow
-
-error: this arithmetic operation will overflow
-  --> $DIR/const-err2.rs:23:13
-   |
-LL |     let b = 200u8 + 200u8 + 200u8;
-   |             ^^^^^^^^^^^^^ attempt to compute `200_u8 + 200_u8`, which would overflow
-
-error: this arithmetic operation will overflow
-  --> $DIR/const-err2.rs:25:18
-   |
-LL |     let b_i128 = i128::MIN - i128::MAX;
-   |                  ^^^^^^^^^^^^^^^^^^^^^ attempt to compute `i128::MIN - i128::MAX`, which would overflow
-
-error: this arithmetic operation will overflow
-  --> $DIR/const-err2.rs:27:13
-   |
-LL |     let c = 200u8 * 4;
-   |             ^^^^^^^^^ attempt to compute `200_u8 * 4_u8`, which would overflow
-
-error: this arithmetic operation will overflow
-  --> $DIR/const-err2.rs:29:13
-   |
-LL |     let d = 42u8 - (42u8 + 1);
-   |             ^^^^^^^^^^^^^^^^^ attempt to compute `42_u8 - 43_u8`, which would overflow
-
-error: this operation will panic at runtime
-  --> $DIR/const-err2.rs:31:14
-   |
-LL |     let _e = [5u8][1];
-   |              ^^^^^^^^ index out of bounds: the length is 1 but the index is 1
-   |
-   = note: `#[deny(unconditional_panic)]` on by default
-
-error: aborting due to 7 previous errors
-
diff --git a/tests/ui/consts/const-err2.opt.stderr b/tests/ui/consts/const-err2.opt.stderr
deleted file mode 100644
index 8b1688c4a89..00000000000
--- a/tests/ui/consts/const-err2.opt.stderr
+++ /dev/null
@@ -1,48 +0,0 @@
-error: this arithmetic operation will overflow
-  --> $DIR/const-err2.rs:19:13
-   |
-LL |     let a = -i8::MIN;
-   |             ^^^^^^^^ attempt to negate `i8::MIN`, which would overflow
-   |
-   = note: `#[deny(arithmetic_overflow)]` on by default
-
-error: this arithmetic operation will overflow
-  --> $DIR/const-err2.rs:21:18
-   |
-LL |     let a_i128 = -i128::MIN;
-   |                  ^^^^^^^^^^ attempt to negate `i128::MIN`, which would overflow
-
-error: this arithmetic operation will overflow
-  --> $DIR/const-err2.rs:23:13
-   |
-LL |     let b = 200u8 + 200u8 + 200u8;
-   |             ^^^^^^^^^^^^^ attempt to compute `200_u8 + 200_u8`, which would overflow
-
-error: this arithmetic operation will overflow
-  --> $DIR/const-err2.rs:25:18
-   |
-LL |     let b_i128 = i128::MIN - i128::MAX;
-   |                  ^^^^^^^^^^^^^^^^^^^^^ attempt to compute `i128::MIN - i128::MAX`, which would overflow
-
-error: this arithmetic operation will overflow
-  --> $DIR/const-err2.rs:27:13
-   |
-LL |     let c = 200u8 * 4;
-   |             ^^^^^^^^^ attempt to compute `200_u8 * 4_u8`, which would overflow
-
-error: this arithmetic operation will overflow
-  --> $DIR/const-err2.rs:29:13
-   |
-LL |     let d = 42u8 - (42u8 + 1);
-   |             ^^^^^^^^^^^^^^^^^ attempt to compute `42_u8 - 43_u8`, which would overflow
-
-error: this operation will panic at runtime
-  --> $DIR/const-err2.rs:31:14
-   |
-LL |     let _e = [5u8][1];
-   |              ^^^^^^^^ index out of bounds: the length is 1 but the index is 1
-   |
-   = note: `#[deny(unconditional_panic)]` on by default
-
-error: aborting due to 7 previous errors
-
diff --git a/tests/ui/consts/const-err2.opt_with_overflow_checks.stderr b/tests/ui/consts/const-err2.opt_with_overflow_checks.stderr
deleted file mode 100644
index 8b1688c4a89..00000000000
--- a/tests/ui/consts/const-err2.opt_with_overflow_checks.stderr
+++ /dev/null
@@ -1,48 +0,0 @@
-error: this arithmetic operation will overflow
-  --> $DIR/const-err2.rs:19:13
-   |
-LL |     let a = -i8::MIN;
-   |             ^^^^^^^^ attempt to negate `i8::MIN`, which would overflow
-   |
-   = note: `#[deny(arithmetic_overflow)]` on by default
-
-error: this arithmetic operation will overflow
-  --> $DIR/const-err2.rs:21:18
-   |
-LL |     let a_i128 = -i128::MIN;
-   |                  ^^^^^^^^^^ attempt to negate `i128::MIN`, which would overflow
-
-error: this arithmetic operation will overflow
-  --> $DIR/const-err2.rs:23:13
-   |
-LL |     let b = 200u8 + 200u8 + 200u8;
-   |             ^^^^^^^^^^^^^ attempt to compute `200_u8 + 200_u8`, which would overflow
-
-error: this arithmetic operation will overflow
-  --> $DIR/const-err2.rs:25:18
-   |
-LL |     let b_i128 = i128::MIN - i128::MAX;
-   |                  ^^^^^^^^^^^^^^^^^^^^^ attempt to compute `i128::MIN - i128::MAX`, which would overflow
-
-error: this arithmetic operation will overflow
-  --> $DIR/const-err2.rs:27:13
-   |
-LL |     let c = 200u8 * 4;
-   |             ^^^^^^^^^ attempt to compute `200_u8 * 4_u8`, which would overflow
-
-error: this arithmetic operation will overflow
-  --> $DIR/const-err2.rs:29:13
-   |
-LL |     let d = 42u8 - (42u8 + 1);
-   |             ^^^^^^^^^^^^^^^^^ attempt to compute `42_u8 - 43_u8`, which would overflow
-
-error: this operation will panic at runtime
-  --> $DIR/const-err2.rs:31:14
-   |
-LL |     let _e = [5u8][1];
-   |              ^^^^^^^^ index out of bounds: the length is 1 but the index is 1
-   |
-   = note: `#[deny(unconditional_panic)]` on by default
-
-error: aborting due to 7 previous errors
-
diff --git a/tests/ui/consts/const-err2.rs b/tests/ui/consts/const-err2.rs
deleted file mode 100644
index 67c85d35401..00000000000
--- a/tests/ui/consts/const-err2.rs
+++ /dev/null
@@ -1,39 +0,0 @@
-// needed because negating int::MIN will behave differently between
-// optimized compilation and unoptimized compilation and thus would
-// lead to different lints being emitted
-
-//@ revisions: noopt opt opt_with_overflow_checks
-//@[noopt]compile-flags: -C opt-level=0
-//@[opt]compile-flags: -O
-//@[opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O
-
-//@ build-fail
-
-#![feature(rustc_attrs)]
-
-fn black_box<T>(_: T) {
-    unimplemented!()
-}
-
-fn main() {
-    let a = -i8::MIN;
-    //~^ ERROR arithmetic operation will overflow
-    let a_i128 = -i128::MIN;
-    //~^ ERROR arithmetic operation will overflow
-    let b = 200u8 + 200u8 + 200u8;
-    //~^ ERROR arithmetic operation will overflow
-    let b_i128 = i128::MIN - i128::MAX;
-    //~^ ERROR arithmetic operation will overflow
-    let c = 200u8 * 4;
-    //~^ ERROR arithmetic operation will overflow
-    let d = 42u8 - (42u8 + 1);
-    //~^ ERROR arithmetic operation will overflow
-    let _e = [5u8][1];
-    //~^ ERROR operation will panic
-    black_box(a);
-    black_box(a_i128);
-    black_box(b);
-    black_box(b_i128);
-    black_box(c);
-    black_box(d);
-}
diff --git a/tests/ui/consts/const-eval/issue-44578.stderr b/tests/ui/consts/const-eval/issue-44578.stderr
index 6aabe53011c..7d5cf86d396 100644
--- a/tests/ui/consts/const-eval/issue-44578.stderr
+++ b/tests/ui/consts/const-eval/issue-44578.stderr
@@ -16,6 +16,14 @@ note: erroneous constant encountered
 LL |     println!("{}", <Bar<u16, u8> as Foo>::AMT);
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+note: erroneous constant encountered
+  --> $DIR/issue-44578.rs:25:20
+   |
+LL |     println!("{}", <Bar<u16, u8> as Foo>::AMT);
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
    = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 note: erroneous constant encountered
diff --git a/tests/ui/consts/const-eval/issue-50814.rs b/tests/ui/consts/const-eval/issue-50814.rs
index ca26f51f111..27b5b39ad73 100644
--- a/tests/ui/consts/const-eval/issue-50814.rs
+++ b/tests/ui/consts/const-eval/issue-50814.rs
@@ -14,6 +14,7 @@ struct Sum<A, B>(A, B);
 impl<A: Unsigned, B: Unsigned> Unsigned for Sum<A, B> {
     const MAX: u8 = A::MAX + B::MAX;
     //~^ ERROR evaluation of `<Sum<U8, U8> as Unsigned>::MAX` failed
+    //~| ERROR evaluation of `<Sum<U8, U8> as Unsigned>::MAX` failed
 }
 
 fn foo<T>(_: T) -> &'static u8 {
diff --git a/tests/ui/consts/const-eval/issue-50814.stderr b/tests/ui/consts/const-eval/issue-50814.stderr
index 65c49956f18..8d018161401 100644
--- a/tests/ui/consts/const-eval/issue-50814.stderr
+++ b/tests/ui/consts/const-eval/issue-50814.stderr
@@ -5,17 +5,33 @@ LL |     const MAX: u8 = A::MAX + B::MAX;
    |                     ^^^^^^^^^^^^^^^ attempt to compute `u8::MAX + u8::MAX`, which would overflow
 
 note: erroneous constant encountered
-  --> $DIR/issue-50814.rs:20:6
+  --> $DIR/issue-50814.rs:21:6
    |
 LL |     &Sum::<U8, U8>::MAX
    |      ^^^^^^^^^^^^^^^^^^
 
+error[E0080]: evaluation of `<Sum<U8, U8> as Unsigned>::MAX` failed
+  --> $DIR/issue-50814.rs:15:21
+   |
+LL |     const MAX: u8 = A::MAX + B::MAX;
+   |                     ^^^^^^^^^^^^^^^ attempt to compute `u8::MAX + u8::MAX`, which would overflow
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+note: erroneous constant encountered
+  --> $DIR/issue-50814.rs:21:6
+   |
+LL |     &Sum::<U8, U8>::MAX
+   |      ^^^^^^^^^^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
 note: the above error was encountered while instantiating `fn foo::<i32>`
-  --> $DIR/issue-50814.rs:25:5
+  --> $DIR/issue-50814.rs:26:5
    |
 LL |     foo(0);
    |     ^^^^^^
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-ref-to-static-linux-vtable.rs b/tests/ui/consts/const-ref-to-static-linux-vtable.rs
new file mode 100644
index 00000000000..9325746c1e7
--- /dev/null
+++ b/tests/ui/consts/const-ref-to-static-linux-vtable.rs
@@ -0,0 +1,43 @@
+//@check-pass
+//! This is the reduced version of the "Linux kernel vtable" use-case.
+#![feature(const_mut_refs, const_refs_to_static)]
+use std::ptr::addr_of_mut;
+
+#[repr(C)]
+struct ThisModule(i32);
+
+trait Module {
+    const THIS_MODULE_PTR: *mut ThisModule;
+}
+
+struct MyModule;
+
+// Generated by a macro.
+extern "C" {
+    static mut THIS_MODULE: ThisModule;
+}
+
+// Generated by a macro.
+impl Module for MyModule {
+    const THIS_MODULE_PTR: *mut ThisModule = unsafe { addr_of_mut!(THIS_MODULE) };
+}
+
+struct Vtable {
+    module: *mut ThisModule,
+    foo_fn: fn(*mut ()) -> i32,
+}
+
+trait Foo {
+    type Mod: Module;
+
+    fn foo(&mut self) -> i32;
+}
+
+fn generate_vtable<T: Foo>() -> &'static Vtable {
+    &Vtable {
+        module: T::Mod::THIS_MODULE_PTR,
+        foo_fn: |ptr| unsafe { &mut *ptr.cast::<T>() }.foo(),
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/consts/issue-17718-const-bad-values.rs b/tests/ui/consts/issue-17718-const-bad-values.rs
index 0299bfef1b4..e112a346b65 100644
--- a/tests/ui/consts/issue-17718-const-bad-values.rs
+++ b/tests/ui/consts/issue-17718-const-bad-values.rs
@@ -6,5 +6,6 @@ const C1: &'static mut [usize] = &mut [];
 static mut S: usize = 3;
 const C2: &'static mut usize = unsafe { &mut S };
 //~^ ERROR: referencing statics in constants
+//~| ERROR: mutable references are not allowed
 
 fn main() {}
diff --git a/tests/ui/consts/issue-17718-const-bad-values.stderr b/tests/ui/consts/issue-17718-const-bad-values.stderr
index 57fcb1c7e9a..e755e5601a8 100644
--- a/tests/ui/consts/issue-17718-const-bad-values.stderr
+++ b/tests/ui/consts/issue-17718-const-bad-values.stderr
@@ -16,7 +16,17 @@ LL | const C2: &'static mut usize = unsafe { &mut S };
    = note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable.
    = help: to fix this, the value can be extracted to a `const` and then used.
 
-error: aborting due to 2 previous errors
+error[E0658]: mutable references are not allowed in constants
+  --> $DIR/issue-17718-const-bad-values.rs:7:41
+   |
+LL | const C2: &'static mut usize = unsafe { &mut S };
+   |                                         ^^^^^^
+   |
+   = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
+   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0658, E0764.
 For more information about an error, try `rustc --explain E0658`.
diff --git a/tests/ui/consts/miri_unleashed/box.stderr b/tests/ui/consts/miri_unleashed/box.stderr
index 5229f1e50cd..a0518c99cda 100644
--- a/tests/ui/consts/miri_unleashed/box.stderr
+++ b/tests/ui/consts/miri_unleashed/box.stderr
@@ -16,7 +16,7 @@ help: skipping check for `const_mut_refs` feature
    |
 LL |     &mut *(Box::new(0))
    |     ^^^^^^^^^^^^^^^^^^^
-help: skipping check that does not even have a feature gate
+help: skipping check for `const_mut_refs` feature
   --> $DIR/box.rs:8:5
    |
 LL |     &mut *(Box::new(0))
diff --git a/tests/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr b/tests/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr
index 401cf46710a..82739c08cf1 100644
--- a/tests/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr
+++ b/tests/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr
@@ -114,7 +114,7 @@ help: skipping check for `const_refs_to_static` feature
    |
 LL | const SUBTLE: &mut i32 = unsafe { &mut FOO };
    |                                        ^^^
-help: skipping check that does not even have a feature gate
+help: skipping check for `const_mut_refs` feature
   --> $DIR/mutable_references_err.rs:32:35
    |
 LL | const SUBTLE: &mut i32 = unsafe { &mut FOO };
diff --git a/tests/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr b/tests/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr
index 0eb01f5b773..844483d88e9 100644
--- a/tests/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr
+++ b/tests/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr
@@ -114,7 +114,7 @@ help: skipping check for `const_refs_to_static` feature
    |
 LL | const SUBTLE: &mut i32 = unsafe { &mut FOO };
    |                                        ^^^
-help: skipping check that does not even have a feature gate
+help: skipping check for `const_mut_refs` feature
   --> $DIR/mutable_references_err.rs:32:35
    |
 LL | const SUBTLE: &mut i32 = unsafe { &mut FOO };
diff --git a/tests/ui/consts/mut-ptr-to-static.rs b/tests/ui/consts/mut-ptr-to-static.rs
new file mode 100644
index 00000000000..d8a788bb37d
--- /dev/null
+++ b/tests/ui/consts/mut-ptr-to-static.rs
@@ -0,0 +1,40 @@
+//@run-pass
+#![feature(const_mut_refs)]
+#![feature(sync_unsafe_cell)]
+
+use std::cell::SyncUnsafeCell;
+use std::ptr;
+
+#[repr(C)]
+struct SyncPtr {
+    foo: *mut u32,
+}
+unsafe impl Sync for SyncPtr {}
+
+static mut STATIC: u32 = 42;
+
+static INTERIOR_MUTABLE_STATIC: SyncUnsafeCell<u32> = SyncUnsafeCell::new(42);
+
+// A static that mutably points to STATIC.
+static PTR: SyncPtr = SyncPtr {
+    foo: unsafe { ptr::addr_of_mut!(STATIC) },
+};
+static INTERIOR_MUTABLE_PTR: SyncPtr = SyncPtr {
+    foo: ptr::addr_of!(INTERIOR_MUTABLE_STATIC) as *mut u32,
+};
+
+fn main() {
+    let ptr = PTR.foo;
+    unsafe {
+        assert_eq!(*ptr, 42);
+        *ptr = 0;
+        assert_eq!(*PTR.foo, 0);
+    }
+
+    let ptr = INTERIOR_MUTABLE_PTR.foo;
+    unsafe {
+        assert_eq!(*ptr, 42);
+        *ptr = 0;
+        assert_eq!(*INTERIOR_MUTABLE_PTR.foo, 0);
+    }
+}
diff --git a/tests/ui/consts/overflowing-consts.noopt.stderr b/tests/ui/consts/overflowing-consts.noopt.stderr
new file mode 100644
index 00000000000..81f22944adb
--- /dev/null
+++ b/tests/ui/consts/overflowing-consts.noopt.stderr
@@ -0,0 +1,1023 @@
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:19:22
+   |
+LL | const _NI8_SHL: i8 = 1i8 << 8;
+   |                      ^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:20:26
+   |
+LL | const _NI8_SHL_P: &i8 = &(1i8 << 8);
+   |                          ^^^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:22:24
+   |
+LL | const _NI16_SHL: i16 = 1i16 << 16;
+   |                        ^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:23:28
+   |
+LL | const _NI16_SHL_P: &i16 = &(1i16 << 16);
+   |                            ^^^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:25:24
+   |
+LL | const _NI32_SHL: i32 = 1i32 << 32;
+   |                        ^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:26:28
+   |
+LL | const _NI32_SHL_P: &i32 = &(1i32 << 32);
+   |                            ^^^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:28:24
+   |
+LL | const _NI64_SHL: i64 = 1i64 << 64;
+   |                        ^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:29:28
+   |
+LL | const _NI64_SHL_P: &i64 = &(1i64 << 64);
+   |                            ^^^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:31:26
+   |
+LL | const _NI128_SHL: i128 = 1i128 << 128;
+   |                          ^^^^^^^^^^^^ attempt to shift left by `128_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:32:30
+   |
+LL | const _NI128_SHL_P: &i128 = &(1i128 << 128);
+   |                              ^^^^^^^^^^^^^^ attempt to shift left by `128_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:34:22
+   |
+LL | const _NU8_SHL: u8 = 1u8 << 8;
+   |                      ^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:35:26
+   |
+LL | const _NU8_SHL_P: &u8 = &(1u8 << 8);
+   |                          ^^^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:37:24
+   |
+LL | const _NU16_SHL: u16 = 1u16 << 16;
+   |                        ^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:38:28
+   |
+LL | const _NU16_SHL_P: &u16 = &(1u16 << 16);
+   |                            ^^^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:40:24
+   |
+LL | const _NU32_SHL: u32 = 1u32 << 32;
+   |                        ^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:41:28
+   |
+LL | const _NU32_SHL_P: &u32 = &(1u32 << 32);
+   |                            ^^^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:43:24
+   |
+LL | const _NU64_SHL: u64 = 1u64 << 64;
+   |                        ^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:44:28
+   |
+LL | const _NU64_SHL_P: &u64 = &(1u64 << 64);
+   |                            ^^^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:46:26
+   |
+LL | const _NU128_SHL: u128 = 1u128 << 128;
+   |                          ^^^^^^^^^^^^ attempt to shift left by `128_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:47:30
+   |
+LL | const _NU128_SHL_P: &u128 = &(1u128 << 128);
+   |                              ^^^^^^^^^^^^^^ attempt to shift left by `128_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:49:28
+   |
+LL | const _NISIZE_SHL: isize = 1isize << BITS;
+   |                            ^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:50:32
+   |
+LL | const _NISIZE_SHL_P: &isize = &(1isize << BITS);
+   |                                ^^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:52:28
+   |
+LL | const _NUSIZE_SHL: usize = 1usize << BITS;
+   |                            ^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:53:32
+   |
+LL | const _NUSIZE_SHL_P: &usize = &(1usize << BITS);
+   |                                ^^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:57:22
+   |
+LL | const _NI8_SHR: i8 = 1i8 >> 8;
+   |                      ^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:58:26
+   |
+LL | const _NI8_SHR_P: &i8 = &(1i8 >> 8);
+   |                          ^^^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:60:24
+   |
+LL | const _NI16_SHR: i16 = 1i16 >> 16;
+   |                        ^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:61:28
+   |
+LL | const _NI16_SHR_P: &i16 = &(1i16 >> 16);
+   |                            ^^^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:63:24
+   |
+LL | const _NI32_SHR: i32 = 1i32 >> 32;
+   |                        ^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:64:28
+   |
+LL | const _NI32_SHR_P: &i32 = &(1i32 >> 32);
+   |                            ^^^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:66:24
+   |
+LL | const _NI64_SHR: i64 = 1i64 >> 64;
+   |                        ^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:67:28
+   |
+LL | const _NI64_SHR_P: &i64 = &(1i64 >> 64);
+   |                            ^^^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:69:26
+   |
+LL | const _NI128_SHR: i128 = 1i128 >> 128;
+   |                          ^^^^^^^^^^^^ attempt to shift right by `128_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:70:30
+   |
+LL | const _NI128_SHR_P: &i128 = &(1i128 >> 128);
+   |                              ^^^^^^^^^^^^^^ attempt to shift right by `128_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:72:22
+   |
+LL | const _NU8_SHR: u8 = 1u8 >> 8;
+   |                      ^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:73:26
+   |
+LL | const _NU8_SHR_P: &u8 = &(1u8 >> 8);
+   |                          ^^^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:75:24
+   |
+LL | const _NU16_SHR: u16 = 1u16 >> 16;
+   |                        ^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:76:28
+   |
+LL | const _NU16_SHR_P: &u16 = &(1u16 >> 16);
+   |                            ^^^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:78:24
+   |
+LL | const _NU32_SHR: u32 = 1u32 >> 32;
+   |                        ^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:79:28
+   |
+LL | const _NU32_SHR_P: &u32 = &(1u32 >> 32);
+   |                            ^^^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:81:24
+   |
+LL | const _NU64_SHR: u64 = 1u64 >> 64;
+   |                        ^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:82:28
+   |
+LL | const _NU64_SHR_P: &u64 = &(1u64 >> 64);
+   |                            ^^^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:84:26
+   |
+LL | const _NU128_SHR: u128 = 1u128 >> 128;
+   |                          ^^^^^^^^^^^^ attempt to shift right by `128_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:85:30
+   |
+LL | const _NU128_SHR_P: &u128 = &(1u128 >> 128);
+   |                              ^^^^^^^^^^^^^^ attempt to shift right by `128_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:87:28
+   |
+LL | const _NISIZE_SHR: isize = 1isize >> BITS;
+   |                            ^^^^^^^^^^^^^^ attempt to shift right by `%BITS%`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:88:32
+   |
+LL | const _NISIZE_SHR_P: &isize = &(1isize >> BITS);
+   |                                ^^^^^^^^^^^^^^^^ attempt to shift right by `%BITS%`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:90:28
+   |
+LL | const _NUSIZE_SHR: usize = 1usize >> BITS;
+   |                            ^^^^^^^^^^^^^^ attempt to shift right by `%BITS%`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:91:32
+   |
+LL | const _NUSIZE_SHR_P: &usize = &(1usize >> BITS);
+   |                                ^^^^^^^^^^^^^^^^ attempt to shift right by `%BITS%`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:95:22
+   |
+LL | const _NI8_ADD: i8 = 1i8 + i8::MAX;
+   |                      ^^^^^^^^^^^^^ attempt to compute `1_i8 + i8::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:96:26
+   |
+LL | const _NI8_ADD_P: &i8 = &(1i8 + i8::MAX);
+   |                          ^^^^^^^^^^^^^^^ attempt to compute `1_i8 + i8::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:98:24
+   |
+LL | const _NI16_ADD: i16 = 1i16 + i16::MAX;
+   |                        ^^^^^^^^^^^^^^^ attempt to compute `1_i16 + i16::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:99:28
+   |
+LL | const _NI16_ADD_P: &i16 = &(1i16 + i16::MAX);
+   |                            ^^^^^^^^^^^^^^^^^ attempt to compute `1_i16 + i16::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:101:24
+   |
+LL | const _NI32_ADD: i32 = 1i32 + i32::MAX;
+   |                        ^^^^^^^^^^^^^^^ attempt to compute `1_i32 + i32::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:102:28
+   |
+LL | const _NI32_ADD_P: &i32 = &(1i32 + i32::MAX);
+   |                            ^^^^^^^^^^^^^^^^^ attempt to compute `1_i32 + i32::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:104:24
+   |
+LL | const _NI64_ADD: i64 = 1i64 + i64::MAX;
+   |                        ^^^^^^^^^^^^^^^ attempt to compute `1_i64 + i64::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:105:28
+   |
+LL | const _NI64_ADD_P: &i64 = &(1i64 + i64::MAX);
+   |                            ^^^^^^^^^^^^^^^^^ attempt to compute `1_i64 + i64::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:107:26
+   |
+LL | const _NI128_ADD: i128 = 1i128 + i128::MAX;
+   |                          ^^^^^^^^^^^^^^^^^ attempt to compute `1_i128 + i128::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:108:30
+   |
+LL | const _NI128_ADD_P: &i128 = &(1i128 + i128::MAX);
+   |                              ^^^^^^^^^^^^^^^^^^^ attempt to compute `1_i128 + i128::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:110:22
+   |
+LL | const _NU8_ADD: u8 = 1u8 + u8::MAX;
+   |                      ^^^^^^^^^^^^^ attempt to compute `1_u8 + u8::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:111:26
+   |
+LL | const _NU8_ADD_P: &u8 = &(1u8 + u8::MAX);
+   |                          ^^^^^^^^^^^^^^^ attempt to compute `1_u8 + u8::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:113:24
+   |
+LL | const _NU16_ADD: u16 = 1u16 + u16::MAX;
+   |                        ^^^^^^^^^^^^^^^ attempt to compute `1_u16 + u16::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:114:28
+   |
+LL | const _NU16_ADD_P: &u16 = &(1u16 + u16::MAX);
+   |                            ^^^^^^^^^^^^^^^^^ attempt to compute `1_u16 + u16::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:116:24
+   |
+LL | const _NU32_ADD: u32 = 1u32 + u32::MAX;
+   |                        ^^^^^^^^^^^^^^^ attempt to compute `1_u32 + u32::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:117:28
+   |
+LL | const _NU32_ADD_P: &u32 = &(1u32 + u32::MAX);
+   |                            ^^^^^^^^^^^^^^^^^ attempt to compute `1_u32 + u32::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:119:24
+   |
+LL | const _NU64_ADD: u64 = 1u64 + u64::MAX;
+   |                        ^^^^^^^^^^^^^^^ attempt to compute `1_u64 + u64::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:120:28
+   |
+LL | const _NU64_ADD_P: &u64 = &(1u64 + u64::MAX);
+   |                            ^^^^^^^^^^^^^^^^^ attempt to compute `1_u64 + u64::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:122:26
+   |
+LL | const _NU128_ADD: u128 = 1u128 + u128::MAX;
+   |                          ^^^^^^^^^^^^^^^^^ attempt to compute `1_u128 + u128::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:123:30
+   |
+LL | const _NU128_ADD_P: &u128 = &(1u128 + u128::MAX);
+   |                              ^^^^^^^^^^^^^^^^^^^ attempt to compute `1_u128 + u128::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:125:28
+   |
+LL | const _NISIZE_ADD: isize = 1isize + isize::MAX;
+   |                            ^^^^^^^^^^^^^^^^^^^ attempt to compute `1_isize + isize::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:126:32
+   |
+LL | const _NISIZE_ADD_P: &isize = &(1isize + isize::MAX);
+   |                                ^^^^^^^^^^^^^^^^^^^^^ attempt to compute `1_isize + isize::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:128:28
+   |
+LL | const _NUSIZE_ADD: usize = 1usize + usize::MAX;
+   |                            ^^^^^^^^^^^^^^^^^^^ attempt to compute `1_usize + usize::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:129:32
+   |
+LL | const _NUSIZE_ADD_P: &usize = &(1usize + usize::MAX);
+   |                                ^^^^^^^^^^^^^^^^^^^^^ attempt to compute `1_usize + usize::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:133:22
+   |
+LL | const _NI8_SUB: i8 = -5i8 - i8::MAX;
+   |                      ^^^^^^^^^^^^^^ attempt to compute `-5_i8 - i8::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:134:26
+   |
+LL | const _NI8_SUB_P: &i8 = &(-5i8 - i8::MAX);
+   |                          ^^^^^^^^^^^^^^^^ attempt to compute `-5_i8 - i8::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:136:24
+   |
+LL | const _NI16_SUB: i16 = -5i16 - i16::MAX;
+   |                        ^^^^^^^^^^^^^^^^ attempt to compute `-5_i16 - i16::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:137:28
+   |
+LL | const _NI16_SUB_P: &i16 = &(-5i16 - i16::MAX);
+   |                            ^^^^^^^^^^^^^^^^^^ attempt to compute `-5_i16 - i16::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:139:24
+   |
+LL | const _NI32_SUB: i32 = -5i32 - i32::MAX;
+   |                        ^^^^^^^^^^^^^^^^ attempt to compute `-5_i32 - i32::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:140:28
+   |
+LL | const _NI32_SUB_P: &i32 = &(-5i32 - i32::MAX);
+   |                            ^^^^^^^^^^^^^^^^^^ attempt to compute `-5_i32 - i32::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:142:24
+   |
+LL | const _NI64_SUB: i64 = -5i64 - i64::MAX;
+   |                        ^^^^^^^^^^^^^^^^ attempt to compute `-5_i64 - i64::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:143:28
+   |
+LL | const _NI64_SUB_P: &i64 = &(-5i64 - i64::MAX);
+   |                            ^^^^^^^^^^^^^^^^^^ attempt to compute `-5_i64 - i64::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:145:26
+   |
+LL | const _NI128_SUB: i128 = -5i128 - i128::MAX;
+   |                          ^^^^^^^^^^^^^^^^^^ attempt to compute `-5_i128 - i128::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:146:30
+   |
+LL | const _NI128_SUB_P: &i128 = &(-5i128 - i128::MAX);
+   |                              ^^^^^^^^^^^^^^^^^^^^ attempt to compute `-5_i128 - i128::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:148:22
+   |
+LL | const _NU8_SUB: u8 = 1u8 - 5;
+   |                      ^^^^^^^ attempt to compute `1_u8 - 5_u8`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:149:26
+   |
+LL | const _NU8_SUB_P: &u8 = &(1u8 - 5);
+   |                          ^^^^^^^^^ attempt to compute `1_u8 - 5_u8`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:151:24
+   |
+LL | const _NU16_SUB: u16 = 1u16 - 5;
+   |                        ^^^^^^^^ attempt to compute `1_u16 - 5_u16`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:152:28
+   |
+LL | const _NU16_SUB_P: &u16 = &(1u16 - 5);
+   |                            ^^^^^^^^^^ attempt to compute `1_u16 - 5_u16`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:154:24
+   |
+LL | const _NU32_SUB: u32 = 1u32 - 5;
+   |                        ^^^^^^^^ attempt to compute `1_u32 - 5_u32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:155:28
+   |
+LL | const _NU32_SUB_P: &u32 = &(1u32 - 5);
+   |                            ^^^^^^^^^^ attempt to compute `1_u32 - 5_u32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:157:24
+   |
+LL | const _NU64_SUB: u64 = 1u64 - 5;
+   |                        ^^^^^^^^ attempt to compute `1_u64 - 5_u64`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:158:28
+   |
+LL | const _NU64_SUB_P: &u64 = &(1u64 - 5);
+   |                            ^^^^^^^^^^ attempt to compute `1_u64 - 5_u64`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:160:26
+   |
+LL | const _NU128_SUB: u128 = 1u128 - 5;
+   |                          ^^^^^^^^^ attempt to compute `1_u128 - 5_u128`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:161:30
+   |
+LL | const _NU128_SUB_P: &u128 = &(1u128 - 5);
+   |                              ^^^^^^^^^^^ attempt to compute `1_u128 - 5_u128`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:163:28
+   |
+LL | const _NISIZE_SUB: isize = -5isize - isize::MAX;
+   |                            ^^^^^^^^^^^^^^^^^^^^ attempt to compute `-5_isize - isize::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:164:32
+   |
+LL | const _NISIZE_SUB_P: &isize = &(-5isize - isize::MAX);
+   |                                ^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `-5_isize - isize::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:166:28
+   |
+LL | const _NUSIZE_SUB: usize = 1usize - 5 ;
+   |                            ^^^^^^^^^^ attempt to compute `1_usize - 5_usize`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:167:32
+   |
+LL | const _NUSIZE_SUB_P: &usize = &(1usize - 5 );
+   |                                ^^^^^^^^^^^^^ attempt to compute `1_usize - 5_usize`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:171:22
+   |
+LL | const _NI8_MUL: i8 = i8::MAX * 5;
+   |                      ^^^^^^^^^^^ attempt to compute `i8::MAX * 5_i8`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:172:26
+   |
+LL | const _NI8_MUL_P: &i8 = &(i8::MAX * 5);
+   |                          ^^^^^^^^^^^^^ attempt to compute `i8::MAX * 5_i8`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:174:24
+   |
+LL | const _NI16_MUL: i16 = i16::MAX * 5;
+   |                        ^^^^^^^^^^^^ attempt to compute `i16::MAX * 5_i16`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:175:28
+   |
+LL | const _NI16_MUL_P: &i16 = &(i16::MAX * 5);
+   |                            ^^^^^^^^^^^^^^ attempt to compute `i16::MAX * 5_i16`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:177:24
+   |
+LL | const _NI32_MUL: i32 = i32::MAX * 5;
+   |                        ^^^^^^^^^^^^ attempt to compute `i32::MAX * 5_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:178:28
+   |
+LL | const _NI32_MUL_P: &i32 = &(i32::MAX * 5);
+   |                            ^^^^^^^^^^^^^^ attempt to compute `i32::MAX * 5_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:180:24
+   |
+LL | const _NI64_MUL: i64 = i64::MAX * 5;
+   |                        ^^^^^^^^^^^^ attempt to compute `i64::MAX * 5_i64`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:181:28
+   |
+LL | const _NI64_MUL_P: &i64 = &(i64::MAX * 5);
+   |                            ^^^^^^^^^^^^^^ attempt to compute `i64::MAX * 5_i64`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:183:26
+   |
+LL | const _NI128_MUL: i128 = i128::MAX * 5;
+   |                          ^^^^^^^^^^^^^ attempt to compute `i128::MAX * 5_i128`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:184:30
+   |
+LL | const _NI128_MUL_P: &i128 = &(i128::MAX * 5);
+   |                              ^^^^^^^^^^^^^^^ attempt to compute `i128::MAX * 5_i128`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:186:22
+   |
+LL | const _NU8_MUL: u8 = u8::MAX * 5;
+   |                      ^^^^^^^^^^^ attempt to compute `u8::MAX * 5_u8`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:187:26
+   |
+LL | const _NU8_MUL_P: &u8 = &(u8::MAX * 5);
+   |                          ^^^^^^^^^^^^^ attempt to compute `u8::MAX * 5_u8`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:189:24
+   |
+LL | const _NU16_MUL: u16 = u16::MAX * 5;
+   |                        ^^^^^^^^^^^^ attempt to compute `u16::MAX * 5_u16`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:190:28
+   |
+LL | const _NU16_MUL_P: &u16 = &(u16::MAX * 5);
+   |                            ^^^^^^^^^^^^^^ attempt to compute `u16::MAX * 5_u16`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:192:24
+   |
+LL | const _NU32_MUL: u32 = u32::MAX * 5;
+   |                        ^^^^^^^^^^^^ attempt to compute `u32::MAX * 5_u32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:193:28
+   |
+LL | const _NU32_MUL_P: &u32 = &(u32::MAX * 5);
+   |                            ^^^^^^^^^^^^^^ attempt to compute `u32::MAX * 5_u32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:195:24
+   |
+LL | const _NU64_MUL: u64 = u64::MAX * 5;
+   |                        ^^^^^^^^^^^^ attempt to compute `u64::MAX * 5_u64`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:196:28
+   |
+LL | const _NU64_MUL_P: &u64 = &(u64::MAX * 5);
+   |                            ^^^^^^^^^^^^^^ attempt to compute `u64::MAX * 5_u64`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:198:26
+   |
+LL | const _NU128_MUL: u128 = u128::MAX * 5;
+   |                          ^^^^^^^^^^^^^ attempt to compute `u128::MAX * 5_u128`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:199:30
+   |
+LL | const _NU128_MUL_P: &u128 = &(u128::MAX * 5);
+   |                              ^^^^^^^^^^^^^^^ attempt to compute `u128::MAX * 5_u128`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:201:28
+   |
+LL | const _NISIZE_MUL: isize = isize::MAX * 5;
+   |                            ^^^^^^^^^^^^^^ attempt to compute `isize::MAX * 5_isize`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:202:32
+   |
+LL | const _NISIZE_MUL_P: &isize = &(isize::MAX * 5);
+   |                                ^^^^^^^^^^^^^^^^ attempt to compute `isize::MAX * 5_isize`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:204:28
+   |
+LL | const _NUSIZE_MUL: usize = usize::MAX * 5;
+   |                            ^^^^^^^^^^^^^^ attempt to compute `usize::MAX * 5_usize`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:205:32
+   |
+LL | const _NUSIZE_MUL_P: &usize = &(usize::MAX * 5);
+   |                                ^^^^^^^^^^^^^^^^ attempt to compute `usize::MAX * 5_usize`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:209:22
+   |
+LL | const _NI8_DIV: i8 = 1i8 / 0;
+   |                      ^^^^^^^ attempt to divide `1_i8` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:210:26
+   |
+LL | const _NI8_DIV_P: &i8 = &(1i8 / 0);
+   |                          ^^^^^^^^^ attempt to divide `1_i8` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:212:24
+   |
+LL | const _NI16_DIV: i16 = 1i16 / 0;
+   |                        ^^^^^^^^ attempt to divide `1_i16` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:213:28
+   |
+LL | const _NI16_DIV_P: &i16 = &(1i16 / 0);
+   |                            ^^^^^^^^^^ attempt to divide `1_i16` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:215:24
+   |
+LL | const _NI32_DIV: i32 = 1i32 / 0;
+   |                        ^^^^^^^^ attempt to divide `1_i32` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:216:28
+   |
+LL | const _NI32_DIV_P: &i32 = &(1i32 / 0);
+   |                            ^^^^^^^^^^ attempt to divide `1_i32` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:218:24
+   |
+LL | const _NI64_DIV: i64 = 1i64 / 0;
+   |                        ^^^^^^^^ attempt to divide `1_i64` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:219:28
+   |
+LL | const _NI64_DIV_P: &i64 = &(1i64 / 0);
+   |                            ^^^^^^^^^^ attempt to divide `1_i64` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:221:26
+   |
+LL | const _NI128_DIV: i128 = 1i128 / 0;
+   |                          ^^^^^^^^^ attempt to divide `1_i128` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:222:30
+   |
+LL | const _NI128_DIV_P: &i128 = &(1i128 / 0);
+   |                              ^^^^^^^^^^^ attempt to divide `1_i128` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:224:22
+   |
+LL | const _NU8_DIV: u8 = 1u8 / 0;
+   |                      ^^^^^^^ attempt to divide `1_u8` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:225:26
+   |
+LL | const _NU8_DIV_P: &u8 = &(1u8 / 0);
+   |                          ^^^^^^^^^ attempt to divide `1_u8` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:227:24
+   |
+LL | const _NU16_DIV: u16 = 1u16 / 0;
+   |                        ^^^^^^^^ attempt to divide `1_u16` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:228:28
+   |
+LL | const _NU16_DIV_P: &u16 = &(1u16 / 0);
+   |                            ^^^^^^^^^^ attempt to divide `1_u16` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:230:24
+   |
+LL | const _NU32_DIV: u32 = 1u32 / 0;
+   |                        ^^^^^^^^ attempt to divide `1_u32` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:231:28
+   |
+LL | const _NU32_DIV_P: &u32 = &(1u32 / 0);
+   |                            ^^^^^^^^^^ attempt to divide `1_u32` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:233:24
+   |
+LL | const _NU64_DIV: u64 = 1u64 / 0;
+   |                        ^^^^^^^^ attempt to divide `1_u64` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:234:28
+   |
+LL | const _NU64_DIV_P: &u64 = &(1u64 / 0);
+   |                            ^^^^^^^^^^ attempt to divide `1_u64` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:236:26
+   |
+LL | const _NU128_DIV: u128 = 1u128 / 0;
+   |                          ^^^^^^^^^ attempt to divide `1_u128` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:237:30
+   |
+LL | const _NU128_DIV_P: &u128 = &(1u128 / 0);
+   |                              ^^^^^^^^^^^ attempt to divide `1_u128` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:239:28
+   |
+LL | const _NISIZE_DIV: isize = 1isize / 0;
+   |                            ^^^^^^^^^^ attempt to divide `1_isize` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:240:32
+   |
+LL | const _NISIZE_DIV_P: &isize = &(1isize / 0);
+   |                                ^^^^^^^^^^^^ attempt to divide `1_isize` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:242:28
+   |
+LL | const _NUSIZE_DIV: usize = 1usize / 0;
+   |                            ^^^^^^^^^^ attempt to divide `1_usize` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:243:32
+   |
+LL | const _NUSIZE_DIV_P: &usize = &(1usize / 0);
+   |                                ^^^^^^^^^^^^ attempt to divide `1_usize` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:246:22
+   |
+LL | const _NI8_MOD: i8 = 1i8 % 0;
+   |                      ^^^^^^^ attempt to calculate the remainder of `1_i8` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:247:26
+   |
+LL | const _NI8_MOD_P: &i8 = &(1i8 % 0);
+   |                          ^^^^^^^^^ attempt to calculate the remainder of `1_i8` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:249:24
+   |
+LL | const _NI16_MOD: i16 = 1i16 % 0;
+   |                        ^^^^^^^^ attempt to calculate the remainder of `1_i16` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:250:28
+   |
+LL | const _NI16_MOD_P: &i16 = &(1i16 % 0);
+   |                            ^^^^^^^^^^ attempt to calculate the remainder of `1_i16` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:252:24
+   |
+LL | const _NI32_MOD: i32 = 1i32 % 0;
+   |                        ^^^^^^^^ attempt to calculate the remainder of `1_i32` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:253:28
+   |
+LL | const _NI32_MOD_P: &i32 = &(1i32 % 0);
+   |                            ^^^^^^^^^^ attempt to calculate the remainder of `1_i32` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:255:24
+   |
+LL | const _NI64_MOD: i64 = 1i64 % 0;
+   |                        ^^^^^^^^ attempt to calculate the remainder of `1_i64` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:256:28
+   |
+LL | const _NI64_MOD_P: &i64 = &(1i64 % 0);
+   |                            ^^^^^^^^^^ attempt to calculate the remainder of `1_i64` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:258:26
+   |
+LL | const _NI128_MOD: i128 = 1i128 % 0;
+   |                          ^^^^^^^^^ attempt to calculate the remainder of `1_i128` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:259:30
+   |
+LL | const _NI128_MOD_P: &i128 = &(1i128 % 0);
+   |                              ^^^^^^^^^^^ attempt to calculate the remainder of `1_i128` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:261:22
+   |
+LL | const _NU8_MOD: u8 = 1u8 % 0;
+   |                      ^^^^^^^ attempt to calculate the remainder of `1_u8` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:262:26
+   |
+LL | const _NU8_MOD_P: &u8 = &(1u8 % 0);
+   |                          ^^^^^^^^^ attempt to calculate the remainder of `1_u8` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:264:24
+   |
+LL | const _NU16_MOD: u16 = 1u16 % 0;
+   |                        ^^^^^^^^ attempt to calculate the remainder of `1_u16` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:265:28
+   |
+LL | const _NU16_MOD_P: &u16 = &(1u16 % 0);
+   |                            ^^^^^^^^^^ attempt to calculate the remainder of `1_u16` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:267:24
+   |
+LL | const _NU32_MOD: u32 = 1u32 % 0;
+   |                        ^^^^^^^^ attempt to calculate the remainder of `1_u32` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:268:28
+   |
+LL | const _NU32_MOD_P: &u32 = &(1u32 % 0);
+   |                            ^^^^^^^^^^ attempt to calculate the remainder of `1_u32` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:270:24
+   |
+LL | const _NU64_MOD: u64 = 1u64 % 0;
+   |                        ^^^^^^^^ attempt to calculate the remainder of `1_u64` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:271:28
+   |
+LL | const _NU64_MOD_P: &u64 = &(1u64 % 0);
+   |                            ^^^^^^^^^^ attempt to calculate the remainder of `1_u64` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:273:26
+   |
+LL | const _NU128_MOD: u128 = 1u128 % 0;
+   |                          ^^^^^^^^^ attempt to calculate the remainder of `1_u128` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:274:30
+   |
+LL | const _NU128_MOD_P: &u128 = &(1u128 % 0);
+   |                              ^^^^^^^^^^^ attempt to calculate the remainder of `1_u128` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:276:28
+   |
+LL | const _NISIZE_MOD: isize = 1isize % 0;
+   |                            ^^^^^^^^^^ attempt to calculate the remainder of `1_isize` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:277:32
+   |
+LL | const _NISIZE_MOD_P: &isize = &(1isize % 0);
+   |                                ^^^^^^^^^^^^ attempt to calculate the remainder of `1_isize` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:279:28
+   |
+LL | const _NUSIZE_MOD: usize = 1usize % 0;
+   |                            ^^^^^^^^^^ attempt to calculate the remainder of `1_usize` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:280:32
+   |
+LL | const _NUSIZE_MOD_P: &usize = &(1usize % 0);
+   |                                ^^^^^^^^^^^^ attempt to calculate the remainder of `1_usize` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:284:24
+   |
+LL | const _NI32_OOB: i32 = [1, 2, 3][4];
+   |                        ^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 4
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:285:28
+   |
+LL | const _NI32_OOB_P: &i32 = &([1, 2, 3][4]);
+   |                            ^^^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 4
+
+error: aborting due to 170 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/overflowing-consts.opt.stderr b/tests/ui/consts/overflowing-consts.opt.stderr
new file mode 100644
index 00000000000..81f22944adb
--- /dev/null
+++ b/tests/ui/consts/overflowing-consts.opt.stderr
@@ -0,0 +1,1023 @@
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:19:22
+   |
+LL | const _NI8_SHL: i8 = 1i8 << 8;
+   |                      ^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:20:26
+   |
+LL | const _NI8_SHL_P: &i8 = &(1i8 << 8);
+   |                          ^^^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:22:24
+   |
+LL | const _NI16_SHL: i16 = 1i16 << 16;
+   |                        ^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:23:28
+   |
+LL | const _NI16_SHL_P: &i16 = &(1i16 << 16);
+   |                            ^^^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:25:24
+   |
+LL | const _NI32_SHL: i32 = 1i32 << 32;
+   |                        ^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:26:28
+   |
+LL | const _NI32_SHL_P: &i32 = &(1i32 << 32);
+   |                            ^^^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:28:24
+   |
+LL | const _NI64_SHL: i64 = 1i64 << 64;
+   |                        ^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:29:28
+   |
+LL | const _NI64_SHL_P: &i64 = &(1i64 << 64);
+   |                            ^^^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:31:26
+   |
+LL | const _NI128_SHL: i128 = 1i128 << 128;
+   |                          ^^^^^^^^^^^^ attempt to shift left by `128_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:32:30
+   |
+LL | const _NI128_SHL_P: &i128 = &(1i128 << 128);
+   |                              ^^^^^^^^^^^^^^ attempt to shift left by `128_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:34:22
+   |
+LL | const _NU8_SHL: u8 = 1u8 << 8;
+   |                      ^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:35:26
+   |
+LL | const _NU8_SHL_P: &u8 = &(1u8 << 8);
+   |                          ^^^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:37:24
+   |
+LL | const _NU16_SHL: u16 = 1u16 << 16;
+   |                        ^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:38:28
+   |
+LL | const _NU16_SHL_P: &u16 = &(1u16 << 16);
+   |                            ^^^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:40:24
+   |
+LL | const _NU32_SHL: u32 = 1u32 << 32;
+   |                        ^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:41:28
+   |
+LL | const _NU32_SHL_P: &u32 = &(1u32 << 32);
+   |                            ^^^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:43:24
+   |
+LL | const _NU64_SHL: u64 = 1u64 << 64;
+   |                        ^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:44:28
+   |
+LL | const _NU64_SHL_P: &u64 = &(1u64 << 64);
+   |                            ^^^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:46:26
+   |
+LL | const _NU128_SHL: u128 = 1u128 << 128;
+   |                          ^^^^^^^^^^^^ attempt to shift left by `128_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:47:30
+   |
+LL | const _NU128_SHL_P: &u128 = &(1u128 << 128);
+   |                              ^^^^^^^^^^^^^^ attempt to shift left by `128_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:49:28
+   |
+LL | const _NISIZE_SHL: isize = 1isize << BITS;
+   |                            ^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:50:32
+   |
+LL | const _NISIZE_SHL_P: &isize = &(1isize << BITS);
+   |                                ^^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:52:28
+   |
+LL | const _NUSIZE_SHL: usize = 1usize << BITS;
+   |                            ^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:53:32
+   |
+LL | const _NUSIZE_SHL_P: &usize = &(1usize << BITS);
+   |                                ^^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:57:22
+   |
+LL | const _NI8_SHR: i8 = 1i8 >> 8;
+   |                      ^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:58:26
+   |
+LL | const _NI8_SHR_P: &i8 = &(1i8 >> 8);
+   |                          ^^^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:60:24
+   |
+LL | const _NI16_SHR: i16 = 1i16 >> 16;
+   |                        ^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:61:28
+   |
+LL | const _NI16_SHR_P: &i16 = &(1i16 >> 16);
+   |                            ^^^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:63:24
+   |
+LL | const _NI32_SHR: i32 = 1i32 >> 32;
+   |                        ^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:64:28
+   |
+LL | const _NI32_SHR_P: &i32 = &(1i32 >> 32);
+   |                            ^^^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:66:24
+   |
+LL | const _NI64_SHR: i64 = 1i64 >> 64;
+   |                        ^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:67:28
+   |
+LL | const _NI64_SHR_P: &i64 = &(1i64 >> 64);
+   |                            ^^^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:69:26
+   |
+LL | const _NI128_SHR: i128 = 1i128 >> 128;
+   |                          ^^^^^^^^^^^^ attempt to shift right by `128_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:70:30
+   |
+LL | const _NI128_SHR_P: &i128 = &(1i128 >> 128);
+   |                              ^^^^^^^^^^^^^^ attempt to shift right by `128_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:72:22
+   |
+LL | const _NU8_SHR: u8 = 1u8 >> 8;
+   |                      ^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:73:26
+   |
+LL | const _NU8_SHR_P: &u8 = &(1u8 >> 8);
+   |                          ^^^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:75:24
+   |
+LL | const _NU16_SHR: u16 = 1u16 >> 16;
+   |                        ^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:76:28
+   |
+LL | const _NU16_SHR_P: &u16 = &(1u16 >> 16);
+   |                            ^^^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:78:24
+   |
+LL | const _NU32_SHR: u32 = 1u32 >> 32;
+   |                        ^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:79:28
+   |
+LL | const _NU32_SHR_P: &u32 = &(1u32 >> 32);
+   |                            ^^^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:81:24
+   |
+LL | const _NU64_SHR: u64 = 1u64 >> 64;
+   |                        ^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:82:28
+   |
+LL | const _NU64_SHR_P: &u64 = &(1u64 >> 64);
+   |                            ^^^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:84:26
+   |
+LL | const _NU128_SHR: u128 = 1u128 >> 128;
+   |                          ^^^^^^^^^^^^ attempt to shift right by `128_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:85:30
+   |
+LL | const _NU128_SHR_P: &u128 = &(1u128 >> 128);
+   |                              ^^^^^^^^^^^^^^ attempt to shift right by `128_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:87:28
+   |
+LL | const _NISIZE_SHR: isize = 1isize >> BITS;
+   |                            ^^^^^^^^^^^^^^ attempt to shift right by `%BITS%`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:88:32
+   |
+LL | const _NISIZE_SHR_P: &isize = &(1isize >> BITS);
+   |                                ^^^^^^^^^^^^^^^^ attempt to shift right by `%BITS%`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:90:28
+   |
+LL | const _NUSIZE_SHR: usize = 1usize >> BITS;
+   |                            ^^^^^^^^^^^^^^ attempt to shift right by `%BITS%`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:91:32
+   |
+LL | const _NUSIZE_SHR_P: &usize = &(1usize >> BITS);
+   |                                ^^^^^^^^^^^^^^^^ attempt to shift right by `%BITS%`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:95:22
+   |
+LL | const _NI8_ADD: i8 = 1i8 + i8::MAX;
+   |                      ^^^^^^^^^^^^^ attempt to compute `1_i8 + i8::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:96:26
+   |
+LL | const _NI8_ADD_P: &i8 = &(1i8 + i8::MAX);
+   |                          ^^^^^^^^^^^^^^^ attempt to compute `1_i8 + i8::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:98:24
+   |
+LL | const _NI16_ADD: i16 = 1i16 + i16::MAX;
+   |                        ^^^^^^^^^^^^^^^ attempt to compute `1_i16 + i16::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:99:28
+   |
+LL | const _NI16_ADD_P: &i16 = &(1i16 + i16::MAX);
+   |                            ^^^^^^^^^^^^^^^^^ attempt to compute `1_i16 + i16::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:101:24
+   |
+LL | const _NI32_ADD: i32 = 1i32 + i32::MAX;
+   |                        ^^^^^^^^^^^^^^^ attempt to compute `1_i32 + i32::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:102:28
+   |
+LL | const _NI32_ADD_P: &i32 = &(1i32 + i32::MAX);
+   |                            ^^^^^^^^^^^^^^^^^ attempt to compute `1_i32 + i32::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:104:24
+   |
+LL | const _NI64_ADD: i64 = 1i64 + i64::MAX;
+   |                        ^^^^^^^^^^^^^^^ attempt to compute `1_i64 + i64::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:105:28
+   |
+LL | const _NI64_ADD_P: &i64 = &(1i64 + i64::MAX);
+   |                            ^^^^^^^^^^^^^^^^^ attempt to compute `1_i64 + i64::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:107:26
+   |
+LL | const _NI128_ADD: i128 = 1i128 + i128::MAX;
+   |                          ^^^^^^^^^^^^^^^^^ attempt to compute `1_i128 + i128::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:108:30
+   |
+LL | const _NI128_ADD_P: &i128 = &(1i128 + i128::MAX);
+   |                              ^^^^^^^^^^^^^^^^^^^ attempt to compute `1_i128 + i128::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:110:22
+   |
+LL | const _NU8_ADD: u8 = 1u8 + u8::MAX;
+   |                      ^^^^^^^^^^^^^ attempt to compute `1_u8 + u8::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:111:26
+   |
+LL | const _NU8_ADD_P: &u8 = &(1u8 + u8::MAX);
+   |                          ^^^^^^^^^^^^^^^ attempt to compute `1_u8 + u8::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:113:24
+   |
+LL | const _NU16_ADD: u16 = 1u16 + u16::MAX;
+   |                        ^^^^^^^^^^^^^^^ attempt to compute `1_u16 + u16::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:114:28
+   |
+LL | const _NU16_ADD_P: &u16 = &(1u16 + u16::MAX);
+   |                            ^^^^^^^^^^^^^^^^^ attempt to compute `1_u16 + u16::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:116:24
+   |
+LL | const _NU32_ADD: u32 = 1u32 + u32::MAX;
+   |                        ^^^^^^^^^^^^^^^ attempt to compute `1_u32 + u32::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:117:28
+   |
+LL | const _NU32_ADD_P: &u32 = &(1u32 + u32::MAX);
+   |                            ^^^^^^^^^^^^^^^^^ attempt to compute `1_u32 + u32::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:119:24
+   |
+LL | const _NU64_ADD: u64 = 1u64 + u64::MAX;
+   |                        ^^^^^^^^^^^^^^^ attempt to compute `1_u64 + u64::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:120:28
+   |
+LL | const _NU64_ADD_P: &u64 = &(1u64 + u64::MAX);
+   |                            ^^^^^^^^^^^^^^^^^ attempt to compute `1_u64 + u64::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:122:26
+   |
+LL | const _NU128_ADD: u128 = 1u128 + u128::MAX;
+   |                          ^^^^^^^^^^^^^^^^^ attempt to compute `1_u128 + u128::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:123:30
+   |
+LL | const _NU128_ADD_P: &u128 = &(1u128 + u128::MAX);
+   |                              ^^^^^^^^^^^^^^^^^^^ attempt to compute `1_u128 + u128::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:125:28
+   |
+LL | const _NISIZE_ADD: isize = 1isize + isize::MAX;
+   |                            ^^^^^^^^^^^^^^^^^^^ attempt to compute `1_isize + isize::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:126:32
+   |
+LL | const _NISIZE_ADD_P: &isize = &(1isize + isize::MAX);
+   |                                ^^^^^^^^^^^^^^^^^^^^^ attempt to compute `1_isize + isize::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:128:28
+   |
+LL | const _NUSIZE_ADD: usize = 1usize + usize::MAX;
+   |                            ^^^^^^^^^^^^^^^^^^^ attempt to compute `1_usize + usize::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:129:32
+   |
+LL | const _NUSIZE_ADD_P: &usize = &(1usize + usize::MAX);
+   |                                ^^^^^^^^^^^^^^^^^^^^^ attempt to compute `1_usize + usize::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:133:22
+   |
+LL | const _NI8_SUB: i8 = -5i8 - i8::MAX;
+   |                      ^^^^^^^^^^^^^^ attempt to compute `-5_i8 - i8::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:134:26
+   |
+LL | const _NI8_SUB_P: &i8 = &(-5i8 - i8::MAX);
+   |                          ^^^^^^^^^^^^^^^^ attempt to compute `-5_i8 - i8::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:136:24
+   |
+LL | const _NI16_SUB: i16 = -5i16 - i16::MAX;
+   |                        ^^^^^^^^^^^^^^^^ attempt to compute `-5_i16 - i16::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:137:28
+   |
+LL | const _NI16_SUB_P: &i16 = &(-5i16 - i16::MAX);
+   |                            ^^^^^^^^^^^^^^^^^^ attempt to compute `-5_i16 - i16::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:139:24
+   |
+LL | const _NI32_SUB: i32 = -5i32 - i32::MAX;
+   |                        ^^^^^^^^^^^^^^^^ attempt to compute `-5_i32 - i32::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:140:28
+   |
+LL | const _NI32_SUB_P: &i32 = &(-5i32 - i32::MAX);
+   |                            ^^^^^^^^^^^^^^^^^^ attempt to compute `-5_i32 - i32::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:142:24
+   |
+LL | const _NI64_SUB: i64 = -5i64 - i64::MAX;
+   |                        ^^^^^^^^^^^^^^^^ attempt to compute `-5_i64 - i64::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:143:28
+   |
+LL | const _NI64_SUB_P: &i64 = &(-5i64 - i64::MAX);
+   |                            ^^^^^^^^^^^^^^^^^^ attempt to compute `-5_i64 - i64::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:145:26
+   |
+LL | const _NI128_SUB: i128 = -5i128 - i128::MAX;
+   |                          ^^^^^^^^^^^^^^^^^^ attempt to compute `-5_i128 - i128::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:146:30
+   |
+LL | const _NI128_SUB_P: &i128 = &(-5i128 - i128::MAX);
+   |                              ^^^^^^^^^^^^^^^^^^^^ attempt to compute `-5_i128 - i128::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:148:22
+   |
+LL | const _NU8_SUB: u8 = 1u8 - 5;
+   |                      ^^^^^^^ attempt to compute `1_u8 - 5_u8`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:149:26
+   |
+LL | const _NU8_SUB_P: &u8 = &(1u8 - 5);
+   |                          ^^^^^^^^^ attempt to compute `1_u8 - 5_u8`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:151:24
+   |
+LL | const _NU16_SUB: u16 = 1u16 - 5;
+   |                        ^^^^^^^^ attempt to compute `1_u16 - 5_u16`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:152:28
+   |
+LL | const _NU16_SUB_P: &u16 = &(1u16 - 5);
+   |                            ^^^^^^^^^^ attempt to compute `1_u16 - 5_u16`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:154:24
+   |
+LL | const _NU32_SUB: u32 = 1u32 - 5;
+   |                        ^^^^^^^^ attempt to compute `1_u32 - 5_u32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:155:28
+   |
+LL | const _NU32_SUB_P: &u32 = &(1u32 - 5);
+   |                            ^^^^^^^^^^ attempt to compute `1_u32 - 5_u32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:157:24
+   |
+LL | const _NU64_SUB: u64 = 1u64 - 5;
+   |                        ^^^^^^^^ attempt to compute `1_u64 - 5_u64`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:158:28
+   |
+LL | const _NU64_SUB_P: &u64 = &(1u64 - 5);
+   |                            ^^^^^^^^^^ attempt to compute `1_u64 - 5_u64`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:160:26
+   |
+LL | const _NU128_SUB: u128 = 1u128 - 5;
+   |                          ^^^^^^^^^ attempt to compute `1_u128 - 5_u128`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:161:30
+   |
+LL | const _NU128_SUB_P: &u128 = &(1u128 - 5);
+   |                              ^^^^^^^^^^^ attempt to compute `1_u128 - 5_u128`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:163:28
+   |
+LL | const _NISIZE_SUB: isize = -5isize - isize::MAX;
+   |                            ^^^^^^^^^^^^^^^^^^^^ attempt to compute `-5_isize - isize::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:164:32
+   |
+LL | const _NISIZE_SUB_P: &isize = &(-5isize - isize::MAX);
+   |                                ^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `-5_isize - isize::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:166:28
+   |
+LL | const _NUSIZE_SUB: usize = 1usize - 5 ;
+   |                            ^^^^^^^^^^ attempt to compute `1_usize - 5_usize`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:167:32
+   |
+LL | const _NUSIZE_SUB_P: &usize = &(1usize - 5 );
+   |                                ^^^^^^^^^^^^^ attempt to compute `1_usize - 5_usize`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:171:22
+   |
+LL | const _NI8_MUL: i8 = i8::MAX * 5;
+   |                      ^^^^^^^^^^^ attempt to compute `i8::MAX * 5_i8`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:172:26
+   |
+LL | const _NI8_MUL_P: &i8 = &(i8::MAX * 5);
+   |                          ^^^^^^^^^^^^^ attempt to compute `i8::MAX * 5_i8`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:174:24
+   |
+LL | const _NI16_MUL: i16 = i16::MAX * 5;
+   |                        ^^^^^^^^^^^^ attempt to compute `i16::MAX * 5_i16`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:175:28
+   |
+LL | const _NI16_MUL_P: &i16 = &(i16::MAX * 5);
+   |                            ^^^^^^^^^^^^^^ attempt to compute `i16::MAX * 5_i16`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:177:24
+   |
+LL | const _NI32_MUL: i32 = i32::MAX * 5;
+   |                        ^^^^^^^^^^^^ attempt to compute `i32::MAX * 5_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:178:28
+   |
+LL | const _NI32_MUL_P: &i32 = &(i32::MAX * 5);
+   |                            ^^^^^^^^^^^^^^ attempt to compute `i32::MAX * 5_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:180:24
+   |
+LL | const _NI64_MUL: i64 = i64::MAX * 5;
+   |                        ^^^^^^^^^^^^ attempt to compute `i64::MAX * 5_i64`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:181:28
+   |
+LL | const _NI64_MUL_P: &i64 = &(i64::MAX * 5);
+   |                            ^^^^^^^^^^^^^^ attempt to compute `i64::MAX * 5_i64`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:183:26
+   |
+LL | const _NI128_MUL: i128 = i128::MAX * 5;
+   |                          ^^^^^^^^^^^^^ attempt to compute `i128::MAX * 5_i128`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:184:30
+   |
+LL | const _NI128_MUL_P: &i128 = &(i128::MAX * 5);
+   |                              ^^^^^^^^^^^^^^^ attempt to compute `i128::MAX * 5_i128`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:186:22
+   |
+LL | const _NU8_MUL: u8 = u8::MAX * 5;
+   |                      ^^^^^^^^^^^ attempt to compute `u8::MAX * 5_u8`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:187:26
+   |
+LL | const _NU8_MUL_P: &u8 = &(u8::MAX * 5);
+   |                          ^^^^^^^^^^^^^ attempt to compute `u8::MAX * 5_u8`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:189:24
+   |
+LL | const _NU16_MUL: u16 = u16::MAX * 5;
+   |                        ^^^^^^^^^^^^ attempt to compute `u16::MAX * 5_u16`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:190:28
+   |
+LL | const _NU16_MUL_P: &u16 = &(u16::MAX * 5);
+   |                            ^^^^^^^^^^^^^^ attempt to compute `u16::MAX * 5_u16`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:192:24
+   |
+LL | const _NU32_MUL: u32 = u32::MAX * 5;
+   |                        ^^^^^^^^^^^^ attempt to compute `u32::MAX * 5_u32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:193:28
+   |
+LL | const _NU32_MUL_P: &u32 = &(u32::MAX * 5);
+   |                            ^^^^^^^^^^^^^^ attempt to compute `u32::MAX * 5_u32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:195:24
+   |
+LL | const _NU64_MUL: u64 = u64::MAX * 5;
+   |                        ^^^^^^^^^^^^ attempt to compute `u64::MAX * 5_u64`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:196:28
+   |
+LL | const _NU64_MUL_P: &u64 = &(u64::MAX * 5);
+   |                            ^^^^^^^^^^^^^^ attempt to compute `u64::MAX * 5_u64`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:198:26
+   |
+LL | const _NU128_MUL: u128 = u128::MAX * 5;
+   |                          ^^^^^^^^^^^^^ attempt to compute `u128::MAX * 5_u128`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:199:30
+   |
+LL | const _NU128_MUL_P: &u128 = &(u128::MAX * 5);
+   |                              ^^^^^^^^^^^^^^^ attempt to compute `u128::MAX * 5_u128`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:201:28
+   |
+LL | const _NISIZE_MUL: isize = isize::MAX * 5;
+   |                            ^^^^^^^^^^^^^^ attempt to compute `isize::MAX * 5_isize`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:202:32
+   |
+LL | const _NISIZE_MUL_P: &isize = &(isize::MAX * 5);
+   |                                ^^^^^^^^^^^^^^^^ attempt to compute `isize::MAX * 5_isize`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:204:28
+   |
+LL | const _NUSIZE_MUL: usize = usize::MAX * 5;
+   |                            ^^^^^^^^^^^^^^ attempt to compute `usize::MAX * 5_usize`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:205:32
+   |
+LL | const _NUSIZE_MUL_P: &usize = &(usize::MAX * 5);
+   |                                ^^^^^^^^^^^^^^^^ attempt to compute `usize::MAX * 5_usize`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:209:22
+   |
+LL | const _NI8_DIV: i8 = 1i8 / 0;
+   |                      ^^^^^^^ attempt to divide `1_i8` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:210:26
+   |
+LL | const _NI8_DIV_P: &i8 = &(1i8 / 0);
+   |                          ^^^^^^^^^ attempt to divide `1_i8` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:212:24
+   |
+LL | const _NI16_DIV: i16 = 1i16 / 0;
+   |                        ^^^^^^^^ attempt to divide `1_i16` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:213:28
+   |
+LL | const _NI16_DIV_P: &i16 = &(1i16 / 0);
+   |                            ^^^^^^^^^^ attempt to divide `1_i16` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:215:24
+   |
+LL | const _NI32_DIV: i32 = 1i32 / 0;
+   |                        ^^^^^^^^ attempt to divide `1_i32` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:216:28
+   |
+LL | const _NI32_DIV_P: &i32 = &(1i32 / 0);
+   |                            ^^^^^^^^^^ attempt to divide `1_i32` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:218:24
+   |
+LL | const _NI64_DIV: i64 = 1i64 / 0;
+   |                        ^^^^^^^^ attempt to divide `1_i64` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:219:28
+   |
+LL | const _NI64_DIV_P: &i64 = &(1i64 / 0);
+   |                            ^^^^^^^^^^ attempt to divide `1_i64` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:221:26
+   |
+LL | const _NI128_DIV: i128 = 1i128 / 0;
+   |                          ^^^^^^^^^ attempt to divide `1_i128` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:222:30
+   |
+LL | const _NI128_DIV_P: &i128 = &(1i128 / 0);
+   |                              ^^^^^^^^^^^ attempt to divide `1_i128` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:224:22
+   |
+LL | const _NU8_DIV: u8 = 1u8 / 0;
+   |                      ^^^^^^^ attempt to divide `1_u8` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:225:26
+   |
+LL | const _NU8_DIV_P: &u8 = &(1u8 / 0);
+   |                          ^^^^^^^^^ attempt to divide `1_u8` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:227:24
+   |
+LL | const _NU16_DIV: u16 = 1u16 / 0;
+   |                        ^^^^^^^^ attempt to divide `1_u16` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:228:28
+   |
+LL | const _NU16_DIV_P: &u16 = &(1u16 / 0);
+   |                            ^^^^^^^^^^ attempt to divide `1_u16` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:230:24
+   |
+LL | const _NU32_DIV: u32 = 1u32 / 0;
+   |                        ^^^^^^^^ attempt to divide `1_u32` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:231:28
+   |
+LL | const _NU32_DIV_P: &u32 = &(1u32 / 0);
+   |                            ^^^^^^^^^^ attempt to divide `1_u32` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:233:24
+   |
+LL | const _NU64_DIV: u64 = 1u64 / 0;
+   |                        ^^^^^^^^ attempt to divide `1_u64` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:234:28
+   |
+LL | const _NU64_DIV_P: &u64 = &(1u64 / 0);
+   |                            ^^^^^^^^^^ attempt to divide `1_u64` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:236:26
+   |
+LL | const _NU128_DIV: u128 = 1u128 / 0;
+   |                          ^^^^^^^^^ attempt to divide `1_u128` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:237:30
+   |
+LL | const _NU128_DIV_P: &u128 = &(1u128 / 0);
+   |                              ^^^^^^^^^^^ attempt to divide `1_u128` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:239:28
+   |
+LL | const _NISIZE_DIV: isize = 1isize / 0;
+   |                            ^^^^^^^^^^ attempt to divide `1_isize` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:240:32
+   |
+LL | const _NISIZE_DIV_P: &isize = &(1isize / 0);
+   |                                ^^^^^^^^^^^^ attempt to divide `1_isize` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:242:28
+   |
+LL | const _NUSIZE_DIV: usize = 1usize / 0;
+   |                            ^^^^^^^^^^ attempt to divide `1_usize` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:243:32
+   |
+LL | const _NUSIZE_DIV_P: &usize = &(1usize / 0);
+   |                                ^^^^^^^^^^^^ attempt to divide `1_usize` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:246:22
+   |
+LL | const _NI8_MOD: i8 = 1i8 % 0;
+   |                      ^^^^^^^ attempt to calculate the remainder of `1_i8` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:247:26
+   |
+LL | const _NI8_MOD_P: &i8 = &(1i8 % 0);
+   |                          ^^^^^^^^^ attempt to calculate the remainder of `1_i8` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:249:24
+   |
+LL | const _NI16_MOD: i16 = 1i16 % 0;
+   |                        ^^^^^^^^ attempt to calculate the remainder of `1_i16` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:250:28
+   |
+LL | const _NI16_MOD_P: &i16 = &(1i16 % 0);
+   |                            ^^^^^^^^^^ attempt to calculate the remainder of `1_i16` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:252:24
+   |
+LL | const _NI32_MOD: i32 = 1i32 % 0;
+   |                        ^^^^^^^^ attempt to calculate the remainder of `1_i32` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:253:28
+   |
+LL | const _NI32_MOD_P: &i32 = &(1i32 % 0);
+   |                            ^^^^^^^^^^ attempt to calculate the remainder of `1_i32` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:255:24
+   |
+LL | const _NI64_MOD: i64 = 1i64 % 0;
+   |                        ^^^^^^^^ attempt to calculate the remainder of `1_i64` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:256:28
+   |
+LL | const _NI64_MOD_P: &i64 = &(1i64 % 0);
+   |                            ^^^^^^^^^^ attempt to calculate the remainder of `1_i64` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:258:26
+   |
+LL | const _NI128_MOD: i128 = 1i128 % 0;
+   |                          ^^^^^^^^^ attempt to calculate the remainder of `1_i128` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:259:30
+   |
+LL | const _NI128_MOD_P: &i128 = &(1i128 % 0);
+   |                              ^^^^^^^^^^^ attempt to calculate the remainder of `1_i128` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:261:22
+   |
+LL | const _NU8_MOD: u8 = 1u8 % 0;
+   |                      ^^^^^^^ attempt to calculate the remainder of `1_u8` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:262:26
+   |
+LL | const _NU8_MOD_P: &u8 = &(1u8 % 0);
+   |                          ^^^^^^^^^ attempt to calculate the remainder of `1_u8` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:264:24
+   |
+LL | const _NU16_MOD: u16 = 1u16 % 0;
+   |                        ^^^^^^^^ attempt to calculate the remainder of `1_u16` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:265:28
+   |
+LL | const _NU16_MOD_P: &u16 = &(1u16 % 0);
+   |                            ^^^^^^^^^^ attempt to calculate the remainder of `1_u16` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:267:24
+   |
+LL | const _NU32_MOD: u32 = 1u32 % 0;
+   |                        ^^^^^^^^ attempt to calculate the remainder of `1_u32` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:268:28
+   |
+LL | const _NU32_MOD_P: &u32 = &(1u32 % 0);
+   |                            ^^^^^^^^^^ attempt to calculate the remainder of `1_u32` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:270:24
+   |
+LL | const _NU64_MOD: u64 = 1u64 % 0;
+   |                        ^^^^^^^^ attempt to calculate the remainder of `1_u64` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:271:28
+   |
+LL | const _NU64_MOD_P: &u64 = &(1u64 % 0);
+   |                            ^^^^^^^^^^ attempt to calculate the remainder of `1_u64` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:273:26
+   |
+LL | const _NU128_MOD: u128 = 1u128 % 0;
+   |                          ^^^^^^^^^ attempt to calculate the remainder of `1_u128` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:274:30
+   |
+LL | const _NU128_MOD_P: &u128 = &(1u128 % 0);
+   |                              ^^^^^^^^^^^ attempt to calculate the remainder of `1_u128` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:276:28
+   |
+LL | const _NISIZE_MOD: isize = 1isize % 0;
+   |                            ^^^^^^^^^^ attempt to calculate the remainder of `1_isize` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:277:32
+   |
+LL | const _NISIZE_MOD_P: &isize = &(1isize % 0);
+   |                                ^^^^^^^^^^^^ attempt to calculate the remainder of `1_isize` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:279:28
+   |
+LL | const _NUSIZE_MOD: usize = 1usize % 0;
+   |                            ^^^^^^^^^^ attempt to calculate the remainder of `1_usize` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:280:32
+   |
+LL | const _NUSIZE_MOD_P: &usize = &(1usize % 0);
+   |                                ^^^^^^^^^^^^ attempt to calculate the remainder of `1_usize` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:284:24
+   |
+LL | const _NI32_OOB: i32 = [1, 2, 3][4];
+   |                        ^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 4
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:285:28
+   |
+LL | const _NI32_OOB_P: &i32 = &([1, 2, 3][4]);
+   |                            ^^^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 4
+
+error: aborting due to 170 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/overflowing-consts.opt_with_overflow_checks.stderr b/tests/ui/consts/overflowing-consts.opt_with_overflow_checks.stderr
new file mode 100644
index 00000000000..81f22944adb
--- /dev/null
+++ b/tests/ui/consts/overflowing-consts.opt_with_overflow_checks.stderr
@@ -0,0 +1,1023 @@
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:19:22
+   |
+LL | const _NI8_SHL: i8 = 1i8 << 8;
+   |                      ^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:20:26
+   |
+LL | const _NI8_SHL_P: &i8 = &(1i8 << 8);
+   |                          ^^^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:22:24
+   |
+LL | const _NI16_SHL: i16 = 1i16 << 16;
+   |                        ^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:23:28
+   |
+LL | const _NI16_SHL_P: &i16 = &(1i16 << 16);
+   |                            ^^^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:25:24
+   |
+LL | const _NI32_SHL: i32 = 1i32 << 32;
+   |                        ^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:26:28
+   |
+LL | const _NI32_SHL_P: &i32 = &(1i32 << 32);
+   |                            ^^^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:28:24
+   |
+LL | const _NI64_SHL: i64 = 1i64 << 64;
+   |                        ^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:29:28
+   |
+LL | const _NI64_SHL_P: &i64 = &(1i64 << 64);
+   |                            ^^^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:31:26
+   |
+LL | const _NI128_SHL: i128 = 1i128 << 128;
+   |                          ^^^^^^^^^^^^ attempt to shift left by `128_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:32:30
+   |
+LL | const _NI128_SHL_P: &i128 = &(1i128 << 128);
+   |                              ^^^^^^^^^^^^^^ attempt to shift left by `128_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:34:22
+   |
+LL | const _NU8_SHL: u8 = 1u8 << 8;
+   |                      ^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:35:26
+   |
+LL | const _NU8_SHL_P: &u8 = &(1u8 << 8);
+   |                          ^^^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:37:24
+   |
+LL | const _NU16_SHL: u16 = 1u16 << 16;
+   |                        ^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:38:28
+   |
+LL | const _NU16_SHL_P: &u16 = &(1u16 << 16);
+   |                            ^^^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:40:24
+   |
+LL | const _NU32_SHL: u32 = 1u32 << 32;
+   |                        ^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:41:28
+   |
+LL | const _NU32_SHL_P: &u32 = &(1u32 << 32);
+   |                            ^^^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:43:24
+   |
+LL | const _NU64_SHL: u64 = 1u64 << 64;
+   |                        ^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:44:28
+   |
+LL | const _NU64_SHL_P: &u64 = &(1u64 << 64);
+   |                            ^^^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:46:26
+   |
+LL | const _NU128_SHL: u128 = 1u128 << 128;
+   |                          ^^^^^^^^^^^^ attempt to shift left by `128_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:47:30
+   |
+LL | const _NU128_SHL_P: &u128 = &(1u128 << 128);
+   |                              ^^^^^^^^^^^^^^ attempt to shift left by `128_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:49:28
+   |
+LL | const _NISIZE_SHL: isize = 1isize << BITS;
+   |                            ^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:50:32
+   |
+LL | const _NISIZE_SHL_P: &isize = &(1isize << BITS);
+   |                                ^^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:52:28
+   |
+LL | const _NUSIZE_SHL: usize = 1usize << BITS;
+   |                            ^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:53:32
+   |
+LL | const _NUSIZE_SHL_P: &usize = &(1usize << BITS);
+   |                                ^^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:57:22
+   |
+LL | const _NI8_SHR: i8 = 1i8 >> 8;
+   |                      ^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:58:26
+   |
+LL | const _NI8_SHR_P: &i8 = &(1i8 >> 8);
+   |                          ^^^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:60:24
+   |
+LL | const _NI16_SHR: i16 = 1i16 >> 16;
+   |                        ^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:61:28
+   |
+LL | const _NI16_SHR_P: &i16 = &(1i16 >> 16);
+   |                            ^^^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:63:24
+   |
+LL | const _NI32_SHR: i32 = 1i32 >> 32;
+   |                        ^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:64:28
+   |
+LL | const _NI32_SHR_P: &i32 = &(1i32 >> 32);
+   |                            ^^^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:66:24
+   |
+LL | const _NI64_SHR: i64 = 1i64 >> 64;
+   |                        ^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:67:28
+   |
+LL | const _NI64_SHR_P: &i64 = &(1i64 >> 64);
+   |                            ^^^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:69:26
+   |
+LL | const _NI128_SHR: i128 = 1i128 >> 128;
+   |                          ^^^^^^^^^^^^ attempt to shift right by `128_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:70:30
+   |
+LL | const _NI128_SHR_P: &i128 = &(1i128 >> 128);
+   |                              ^^^^^^^^^^^^^^ attempt to shift right by `128_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:72:22
+   |
+LL | const _NU8_SHR: u8 = 1u8 >> 8;
+   |                      ^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:73:26
+   |
+LL | const _NU8_SHR_P: &u8 = &(1u8 >> 8);
+   |                          ^^^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:75:24
+   |
+LL | const _NU16_SHR: u16 = 1u16 >> 16;
+   |                        ^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:76:28
+   |
+LL | const _NU16_SHR_P: &u16 = &(1u16 >> 16);
+   |                            ^^^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:78:24
+   |
+LL | const _NU32_SHR: u32 = 1u32 >> 32;
+   |                        ^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:79:28
+   |
+LL | const _NU32_SHR_P: &u32 = &(1u32 >> 32);
+   |                            ^^^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:81:24
+   |
+LL | const _NU64_SHR: u64 = 1u64 >> 64;
+   |                        ^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:82:28
+   |
+LL | const _NU64_SHR_P: &u64 = &(1u64 >> 64);
+   |                            ^^^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:84:26
+   |
+LL | const _NU128_SHR: u128 = 1u128 >> 128;
+   |                          ^^^^^^^^^^^^ attempt to shift right by `128_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:85:30
+   |
+LL | const _NU128_SHR_P: &u128 = &(1u128 >> 128);
+   |                              ^^^^^^^^^^^^^^ attempt to shift right by `128_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:87:28
+   |
+LL | const _NISIZE_SHR: isize = 1isize >> BITS;
+   |                            ^^^^^^^^^^^^^^ attempt to shift right by `%BITS%`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:88:32
+   |
+LL | const _NISIZE_SHR_P: &isize = &(1isize >> BITS);
+   |                                ^^^^^^^^^^^^^^^^ attempt to shift right by `%BITS%`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:90:28
+   |
+LL | const _NUSIZE_SHR: usize = 1usize >> BITS;
+   |                            ^^^^^^^^^^^^^^ attempt to shift right by `%BITS%`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:91:32
+   |
+LL | const _NUSIZE_SHR_P: &usize = &(1usize >> BITS);
+   |                                ^^^^^^^^^^^^^^^^ attempt to shift right by `%BITS%`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:95:22
+   |
+LL | const _NI8_ADD: i8 = 1i8 + i8::MAX;
+   |                      ^^^^^^^^^^^^^ attempt to compute `1_i8 + i8::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:96:26
+   |
+LL | const _NI8_ADD_P: &i8 = &(1i8 + i8::MAX);
+   |                          ^^^^^^^^^^^^^^^ attempt to compute `1_i8 + i8::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:98:24
+   |
+LL | const _NI16_ADD: i16 = 1i16 + i16::MAX;
+   |                        ^^^^^^^^^^^^^^^ attempt to compute `1_i16 + i16::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:99:28
+   |
+LL | const _NI16_ADD_P: &i16 = &(1i16 + i16::MAX);
+   |                            ^^^^^^^^^^^^^^^^^ attempt to compute `1_i16 + i16::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:101:24
+   |
+LL | const _NI32_ADD: i32 = 1i32 + i32::MAX;
+   |                        ^^^^^^^^^^^^^^^ attempt to compute `1_i32 + i32::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:102:28
+   |
+LL | const _NI32_ADD_P: &i32 = &(1i32 + i32::MAX);
+   |                            ^^^^^^^^^^^^^^^^^ attempt to compute `1_i32 + i32::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:104:24
+   |
+LL | const _NI64_ADD: i64 = 1i64 + i64::MAX;
+   |                        ^^^^^^^^^^^^^^^ attempt to compute `1_i64 + i64::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:105:28
+   |
+LL | const _NI64_ADD_P: &i64 = &(1i64 + i64::MAX);
+   |                            ^^^^^^^^^^^^^^^^^ attempt to compute `1_i64 + i64::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:107:26
+   |
+LL | const _NI128_ADD: i128 = 1i128 + i128::MAX;
+   |                          ^^^^^^^^^^^^^^^^^ attempt to compute `1_i128 + i128::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:108:30
+   |
+LL | const _NI128_ADD_P: &i128 = &(1i128 + i128::MAX);
+   |                              ^^^^^^^^^^^^^^^^^^^ attempt to compute `1_i128 + i128::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:110:22
+   |
+LL | const _NU8_ADD: u8 = 1u8 + u8::MAX;
+   |                      ^^^^^^^^^^^^^ attempt to compute `1_u8 + u8::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:111:26
+   |
+LL | const _NU8_ADD_P: &u8 = &(1u8 + u8::MAX);
+   |                          ^^^^^^^^^^^^^^^ attempt to compute `1_u8 + u8::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:113:24
+   |
+LL | const _NU16_ADD: u16 = 1u16 + u16::MAX;
+   |                        ^^^^^^^^^^^^^^^ attempt to compute `1_u16 + u16::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:114:28
+   |
+LL | const _NU16_ADD_P: &u16 = &(1u16 + u16::MAX);
+   |                            ^^^^^^^^^^^^^^^^^ attempt to compute `1_u16 + u16::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:116:24
+   |
+LL | const _NU32_ADD: u32 = 1u32 + u32::MAX;
+   |                        ^^^^^^^^^^^^^^^ attempt to compute `1_u32 + u32::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:117:28
+   |
+LL | const _NU32_ADD_P: &u32 = &(1u32 + u32::MAX);
+   |                            ^^^^^^^^^^^^^^^^^ attempt to compute `1_u32 + u32::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:119:24
+   |
+LL | const _NU64_ADD: u64 = 1u64 + u64::MAX;
+   |                        ^^^^^^^^^^^^^^^ attempt to compute `1_u64 + u64::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:120:28
+   |
+LL | const _NU64_ADD_P: &u64 = &(1u64 + u64::MAX);
+   |                            ^^^^^^^^^^^^^^^^^ attempt to compute `1_u64 + u64::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:122:26
+   |
+LL | const _NU128_ADD: u128 = 1u128 + u128::MAX;
+   |                          ^^^^^^^^^^^^^^^^^ attempt to compute `1_u128 + u128::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:123:30
+   |
+LL | const _NU128_ADD_P: &u128 = &(1u128 + u128::MAX);
+   |                              ^^^^^^^^^^^^^^^^^^^ attempt to compute `1_u128 + u128::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:125:28
+   |
+LL | const _NISIZE_ADD: isize = 1isize + isize::MAX;
+   |                            ^^^^^^^^^^^^^^^^^^^ attempt to compute `1_isize + isize::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:126:32
+   |
+LL | const _NISIZE_ADD_P: &isize = &(1isize + isize::MAX);
+   |                                ^^^^^^^^^^^^^^^^^^^^^ attempt to compute `1_isize + isize::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:128:28
+   |
+LL | const _NUSIZE_ADD: usize = 1usize + usize::MAX;
+   |                            ^^^^^^^^^^^^^^^^^^^ attempt to compute `1_usize + usize::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:129:32
+   |
+LL | const _NUSIZE_ADD_P: &usize = &(1usize + usize::MAX);
+   |                                ^^^^^^^^^^^^^^^^^^^^^ attempt to compute `1_usize + usize::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:133:22
+   |
+LL | const _NI8_SUB: i8 = -5i8 - i8::MAX;
+   |                      ^^^^^^^^^^^^^^ attempt to compute `-5_i8 - i8::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:134:26
+   |
+LL | const _NI8_SUB_P: &i8 = &(-5i8 - i8::MAX);
+   |                          ^^^^^^^^^^^^^^^^ attempt to compute `-5_i8 - i8::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:136:24
+   |
+LL | const _NI16_SUB: i16 = -5i16 - i16::MAX;
+   |                        ^^^^^^^^^^^^^^^^ attempt to compute `-5_i16 - i16::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:137:28
+   |
+LL | const _NI16_SUB_P: &i16 = &(-5i16 - i16::MAX);
+   |                            ^^^^^^^^^^^^^^^^^^ attempt to compute `-5_i16 - i16::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:139:24
+   |
+LL | const _NI32_SUB: i32 = -5i32 - i32::MAX;
+   |                        ^^^^^^^^^^^^^^^^ attempt to compute `-5_i32 - i32::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:140:28
+   |
+LL | const _NI32_SUB_P: &i32 = &(-5i32 - i32::MAX);
+   |                            ^^^^^^^^^^^^^^^^^^ attempt to compute `-5_i32 - i32::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:142:24
+   |
+LL | const _NI64_SUB: i64 = -5i64 - i64::MAX;
+   |                        ^^^^^^^^^^^^^^^^ attempt to compute `-5_i64 - i64::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:143:28
+   |
+LL | const _NI64_SUB_P: &i64 = &(-5i64 - i64::MAX);
+   |                            ^^^^^^^^^^^^^^^^^^ attempt to compute `-5_i64 - i64::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:145:26
+   |
+LL | const _NI128_SUB: i128 = -5i128 - i128::MAX;
+   |                          ^^^^^^^^^^^^^^^^^^ attempt to compute `-5_i128 - i128::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:146:30
+   |
+LL | const _NI128_SUB_P: &i128 = &(-5i128 - i128::MAX);
+   |                              ^^^^^^^^^^^^^^^^^^^^ attempt to compute `-5_i128 - i128::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:148:22
+   |
+LL | const _NU8_SUB: u8 = 1u8 - 5;
+   |                      ^^^^^^^ attempt to compute `1_u8 - 5_u8`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:149:26
+   |
+LL | const _NU8_SUB_P: &u8 = &(1u8 - 5);
+   |                          ^^^^^^^^^ attempt to compute `1_u8 - 5_u8`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:151:24
+   |
+LL | const _NU16_SUB: u16 = 1u16 - 5;
+   |                        ^^^^^^^^ attempt to compute `1_u16 - 5_u16`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:152:28
+   |
+LL | const _NU16_SUB_P: &u16 = &(1u16 - 5);
+   |                            ^^^^^^^^^^ attempt to compute `1_u16 - 5_u16`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:154:24
+   |
+LL | const _NU32_SUB: u32 = 1u32 - 5;
+   |                        ^^^^^^^^ attempt to compute `1_u32 - 5_u32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:155:28
+   |
+LL | const _NU32_SUB_P: &u32 = &(1u32 - 5);
+   |                            ^^^^^^^^^^ attempt to compute `1_u32 - 5_u32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:157:24
+   |
+LL | const _NU64_SUB: u64 = 1u64 - 5;
+   |                        ^^^^^^^^ attempt to compute `1_u64 - 5_u64`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:158:28
+   |
+LL | const _NU64_SUB_P: &u64 = &(1u64 - 5);
+   |                            ^^^^^^^^^^ attempt to compute `1_u64 - 5_u64`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:160:26
+   |
+LL | const _NU128_SUB: u128 = 1u128 - 5;
+   |                          ^^^^^^^^^ attempt to compute `1_u128 - 5_u128`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:161:30
+   |
+LL | const _NU128_SUB_P: &u128 = &(1u128 - 5);
+   |                              ^^^^^^^^^^^ attempt to compute `1_u128 - 5_u128`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:163:28
+   |
+LL | const _NISIZE_SUB: isize = -5isize - isize::MAX;
+   |                            ^^^^^^^^^^^^^^^^^^^^ attempt to compute `-5_isize - isize::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:164:32
+   |
+LL | const _NISIZE_SUB_P: &isize = &(-5isize - isize::MAX);
+   |                                ^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `-5_isize - isize::MAX`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:166:28
+   |
+LL | const _NUSIZE_SUB: usize = 1usize - 5 ;
+   |                            ^^^^^^^^^^ attempt to compute `1_usize - 5_usize`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:167:32
+   |
+LL | const _NUSIZE_SUB_P: &usize = &(1usize - 5 );
+   |                                ^^^^^^^^^^^^^ attempt to compute `1_usize - 5_usize`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:171:22
+   |
+LL | const _NI8_MUL: i8 = i8::MAX * 5;
+   |                      ^^^^^^^^^^^ attempt to compute `i8::MAX * 5_i8`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:172:26
+   |
+LL | const _NI8_MUL_P: &i8 = &(i8::MAX * 5);
+   |                          ^^^^^^^^^^^^^ attempt to compute `i8::MAX * 5_i8`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:174:24
+   |
+LL | const _NI16_MUL: i16 = i16::MAX * 5;
+   |                        ^^^^^^^^^^^^ attempt to compute `i16::MAX * 5_i16`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:175:28
+   |
+LL | const _NI16_MUL_P: &i16 = &(i16::MAX * 5);
+   |                            ^^^^^^^^^^^^^^ attempt to compute `i16::MAX * 5_i16`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:177:24
+   |
+LL | const _NI32_MUL: i32 = i32::MAX * 5;
+   |                        ^^^^^^^^^^^^ attempt to compute `i32::MAX * 5_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:178:28
+   |
+LL | const _NI32_MUL_P: &i32 = &(i32::MAX * 5);
+   |                            ^^^^^^^^^^^^^^ attempt to compute `i32::MAX * 5_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:180:24
+   |
+LL | const _NI64_MUL: i64 = i64::MAX * 5;
+   |                        ^^^^^^^^^^^^ attempt to compute `i64::MAX * 5_i64`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:181:28
+   |
+LL | const _NI64_MUL_P: &i64 = &(i64::MAX * 5);
+   |                            ^^^^^^^^^^^^^^ attempt to compute `i64::MAX * 5_i64`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:183:26
+   |
+LL | const _NI128_MUL: i128 = i128::MAX * 5;
+   |                          ^^^^^^^^^^^^^ attempt to compute `i128::MAX * 5_i128`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:184:30
+   |
+LL | const _NI128_MUL_P: &i128 = &(i128::MAX * 5);
+   |                              ^^^^^^^^^^^^^^^ attempt to compute `i128::MAX * 5_i128`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:186:22
+   |
+LL | const _NU8_MUL: u8 = u8::MAX * 5;
+   |                      ^^^^^^^^^^^ attempt to compute `u8::MAX * 5_u8`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:187:26
+   |
+LL | const _NU8_MUL_P: &u8 = &(u8::MAX * 5);
+   |                          ^^^^^^^^^^^^^ attempt to compute `u8::MAX * 5_u8`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:189:24
+   |
+LL | const _NU16_MUL: u16 = u16::MAX * 5;
+   |                        ^^^^^^^^^^^^ attempt to compute `u16::MAX * 5_u16`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:190:28
+   |
+LL | const _NU16_MUL_P: &u16 = &(u16::MAX * 5);
+   |                            ^^^^^^^^^^^^^^ attempt to compute `u16::MAX * 5_u16`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:192:24
+   |
+LL | const _NU32_MUL: u32 = u32::MAX * 5;
+   |                        ^^^^^^^^^^^^ attempt to compute `u32::MAX * 5_u32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:193:28
+   |
+LL | const _NU32_MUL_P: &u32 = &(u32::MAX * 5);
+   |                            ^^^^^^^^^^^^^^ attempt to compute `u32::MAX * 5_u32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:195:24
+   |
+LL | const _NU64_MUL: u64 = u64::MAX * 5;
+   |                        ^^^^^^^^^^^^ attempt to compute `u64::MAX * 5_u64`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:196:28
+   |
+LL | const _NU64_MUL_P: &u64 = &(u64::MAX * 5);
+   |                            ^^^^^^^^^^^^^^ attempt to compute `u64::MAX * 5_u64`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:198:26
+   |
+LL | const _NU128_MUL: u128 = u128::MAX * 5;
+   |                          ^^^^^^^^^^^^^ attempt to compute `u128::MAX * 5_u128`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:199:30
+   |
+LL | const _NU128_MUL_P: &u128 = &(u128::MAX * 5);
+   |                              ^^^^^^^^^^^^^^^ attempt to compute `u128::MAX * 5_u128`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:201:28
+   |
+LL | const _NISIZE_MUL: isize = isize::MAX * 5;
+   |                            ^^^^^^^^^^^^^^ attempt to compute `isize::MAX * 5_isize`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:202:32
+   |
+LL | const _NISIZE_MUL_P: &isize = &(isize::MAX * 5);
+   |                                ^^^^^^^^^^^^^^^^ attempt to compute `isize::MAX * 5_isize`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:204:28
+   |
+LL | const _NUSIZE_MUL: usize = usize::MAX * 5;
+   |                            ^^^^^^^^^^^^^^ attempt to compute `usize::MAX * 5_usize`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:205:32
+   |
+LL | const _NUSIZE_MUL_P: &usize = &(usize::MAX * 5);
+   |                                ^^^^^^^^^^^^^^^^ attempt to compute `usize::MAX * 5_usize`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:209:22
+   |
+LL | const _NI8_DIV: i8 = 1i8 / 0;
+   |                      ^^^^^^^ attempt to divide `1_i8` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:210:26
+   |
+LL | const _NI8_DIV_P: &i8 = &(1i8 / 0);
+   |                          ^^^^^^^^^ attempt to divide `1_i8` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:212:24
+   |
+LL | const _NI16_DIV: i16 = 1i16 / 0;
+   |                        ^^^^^^^^ attempt to divide `1_i16` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:213:28
+   |
+LL | const _NI16_DIV_P: &i16 = &(1i16 / 0);
+   |                            ^^^^^^^^^^ attempt to divide `1_i16` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:215:24
+   |
+LL | const _NI32_DIV: i32 = 1i32 / 0;
+   |                        ^^^^^^^^ attempt to divide `1_i32` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:216:28
+   |
+LL | const _NI32_DIV_P: &i32 = &(1i32 / 0);
+   |                            ^^^^^^^^^^ attempt to divide `1_i32` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:218:24
+   |
+LL | const _NI64_DIV: i64 = 1i64 / 0;
+   |                        ^^^^^^^^ attempt to divide `1_i64` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:219:28
+   |
+LL | const _NI64_DIV_P: &i64 = &(1i64 / 0);
+   |                            ^^^^^^^^^^ attempt to divide `1_i64` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:221:26
+   |
+LL | const _NI128_DIV: i128 = 1i128 / 0;
+   |                          ^^^^^^^^^ attempt to divide `1_i128` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:222:30
+   |
+LL | const _NI128_DIV_P: &i128 = &(1i128 / 0);
+   |                              ^^^^^^^^^^^ attempt to divide `1_i128` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:224:22
+   |
+LL | const _NU8_DIV: u8 = 1u8 / 0;
+   |                      ^^^^^^^ attempt to divide `1_u8` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:225:26
+   |
+LL | const _NU8_DIV_P: &u8 = &(1u8 / 0);
+   |                          ^^^^^^^^^ attempt to divide `1_u8` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:227:24
+   |
+LL | const _NU16_DIV: u16 = 1u16 / 0;
+   |                        ^^^^^^^^ attempt to divide `1_u16` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:228:28
+   |
+LL | const _NU16_DIV_P: &u16 = &(1u16 / 0);
+   |                            ^^^^^^^^^^ attempt to divide `1_u16` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:230:24
+   |
+LL | const _NU32_DIV: u32 = 1u32 / 0;
+   |                        ^^^^^^^^ attempt to divide `1_u32` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:231:28
+   |
+LL | const _NU32_DIV_P: &u32 = &(1u32 / 0);
+   |                            ^^^^^^^^^^ attempt to divide `1_u32` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:233:24
+   |
+LL | const _NU64_DIV: u64 = 1u64 / 0;
+   |                        ^^^^^^^^ attempt to divide `1_u64` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:234:28
+   |
+LL | const _NU64_DIV_P: &u64 = &(1u64 / 0);
+   |                            ^^^^^^^^^^ attempt to divide `1_u64` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:236:26
+   |
+LL | const _NU128_DIV: u128 = 1u128 / 0;
+   |                          ^^^^^^^^^ attempt to divide `1_u128` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:237:30
+   |
+LL | const _NU128_DIV_P: &u128 = &(1u128 / 0);
+   |                              ^^^^^^^^^^^ attempt to divide `1_u128` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:239:28
+   |
+LL | const _NISIZE_DIV: isize = 1isize / 0;
+   |                            ^^^^^^^^^^ attempt to divide `1_isize` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:240:32
+   |
+LL | const _NISIZE_DIV_P: &isize = &(1isize / 0);
+   |                                ^^^^^^^^^^^^ attempt to divide `1_isize` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:242:28
+   |
+LL | const _NUSIZE_DIV: usize = 1usize / 0;
+   |                            ^^^^^^^^^^ attempt to divide `1_usize` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:243:32
+   |
+LL | const _NUSIZE_DIV_P: &usize = &(1usize / 0);
+   |                                ^^^^^^^^^^^^ attempt to divide `1_usize` by zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:246:22
+   |
+LL | const _NI8_MOD: i8 = 1i8 % 0;
+   |                      ^^^^^^^ attempt to calculate the remainder of `1_i8` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:247:26
+   |
+LL | const _NI8_MOD_P: &i8 = &(1i8 % 0);
+   |                          ^^^^^^^^^ attempt to calculate the remainder of `1_i8` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:249:24
+   |
+LL | const _NI16_MOD: i16 = 1i16 % 0;
+   |                        ^^^^^^^^ attempt to calculate the remainder of `1_i16` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:250:28
+   |
+LL | const _NI16_MOD_P: &i16 = &(1i16 % 0);
+   |                            ^^^^^^^^^^ attempt to calculate the remainder of `1_i16` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:252:24
+   |
+LL | const _NI32_MOD: i32 = 1i32 % 0;
+   |                        ^^^^^^^^ attempt to calculate the remainder of `1_i32` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:253:28
+   |
+LL | const _NI32_MOD_P: &i32 = &(1i32 % 0);
+   |                            ^^^^^^^^^^ attempt to calculate the remainder of `1_i32` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:255:24
+   |
+LL | const _NI64_MOD: i64 = 1i64 % 0;
+   |                        ^^^^^^^^ attempt to calculate the remainder of `1_i64` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:256:28
+   |
+LL | const _NI64_MOD_P: &i64 = &(1i64 % 0);
+   |                            ^^^^^^^^^^ attempt to calculate the remainder of `1_i64` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:258:26
+   |
+LL | const _NI128_MOD: i128 = 1i128 % 0;
+   |                          ^^^^^^^^^ attempt to calculate the remainder of `1_i128` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:259:30
+   |
+LL | const _NI128_MOD_P: &i128 = &(1i128 % 0);
+   |                              ^^^^^^^^^^^ attempt to calculate the remainder of `1_i128` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:261:22
+   |
+LL | const _NU8_MOD: u8 = 1u8 % 0;
+   |                      ^^^^^^^ attempt to calculate the remainder of `1_u8` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:262:26
+   |
+LL | const _NU8_MOD_P: &u8 = &(1u8 % 0);
+   |                          ^^^^^^^^^ attempt to calculate the remainder of `1_u8` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:264:24
+   |
+LL | const _NU16_MOD: u16 = 1u16 % 0;
+   |                        ^^^^^^^^ attempt to calculate the remainder of `1_u16` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:265:28
+   |
+LL | const _NU16_MOD_P: &u16 = &(1u16 % 0);
+   |                            ^^^^^^^^^^ attempt to calculate the remainder of `1_u16` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:267:24
+   |
+LL | const _NU32_MOD: u32 = 1u32 % 0;
+   |                        ^^^^^^^^ attempt to calculate the remainder of `1_u32` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:268:28
+   |
+LL | const _NU32_MOD_P: &u32 = &(1u32 % 0);
+   |                            ^^^^^^^^^^ attempt to calculate the remainder of `1_u32` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:270:24
+   |
+LL | const _NU64_MOD: u64 = 1u64 % 0;
+   |                        ^^^^^^^^ attempt to calculate the remainder of `1_u64` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:271:28
+   |
+LL | const _NU64_MOD_P: &u64 = &(1u64 % 0);
+   |                            ^^^^^^^^^^ attempt to calculate the remainder of `1_u64` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:273:26
+   |
+LL | const _NU128_MOD: u128 = 1u128 % 0;
+   |                          ^^^^^^^^^ attempt to calculate the remainder of `1_u128` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:274:30
+   |
+LL | const _NU128_MOD_P: &u128 = &(1u128 % 0);
+   |                              ^^^^^^^^^^^ attempt to calculate the remainder of `1_u128` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:276:28
+   |
+LL | const _NISIZE_MOD: isize = 1isize % 0;
+   |                            ^^^^^^^^^^ attempt to calculate the remainder of `1_isize` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:277:32
+   |
+LL | const _NISIZE_MOD_P: &isize = &(1isize % 0);
+   |                                ^^^^^^^^^^^^ attempt to calculate the remainder of `1_isize` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:279:28
+   |
+LL | const _NUSIZE_MOD: usize = 1usize % 0;
+   |                            ^^^^^^^^^^ attempt to calculate the remainder of `1_usize` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:280:32
+   |
+LL | const _NUSIZE_MOD_P: &usize = &(1usize % 0);
+   |                                ^^^^^^^^^^^^ attempt to calculate the remainder of `1_usize` with a divisor of zero
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:284:24
+   |
+LL | const _NI32_OOB: i32 = [1, 2, 3][4];
+   |                        ^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 4
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/overflowing-consts.rs:285:28
+   |
+LL | const _NI32_OOB_P: &i32 = &([1, 2, 3][4]);
+   |                            ^^^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 4
+
+error: aborting due to 170 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/overflowing-consts.rs b/tests/ui/consts/overflowing-consts.rs
new file mode 100644
index 00000000000..52c0623f2c0
--- /dev/null
+++ b/tests/ui/consts/overflowing-consts.rs
@@ -0,0 +1,288 @@
+// Tests that overflowing or bound-exceeding operations
+// for compile-time consts raise errors
+
+//@ revisions: noopt opt opt_with_overflow_checks
+//@ [noopt]compile-flags: -C opt-level=0
+//@ [opt]compile-flags: -O
+//@ [opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O
+//@ ignore-pass (test tests codegen-time behaviour)
+//@ normalize-stderr-test "shift left by `(64|32)_usize`, which" -> "shift left by `%BITS%`, which"
+//@ normalize-stderr-test "shift right by `(64|32)_usize`, which" -> "shift right by `%BITS%`, which"
+
+
+#[cfg(target_pointer_width = "32")]
+const BITS: usize = 32;
+#[cfg(target_pointer_width = "64")]
+const BITS: usize = 64;
+
+// Shift left
+const _NI8_SHL: i8 = 1i8 << 8; //~ ERROR: evaluation of constant value failed
+const _NI8_SHL_P: &i8 = &(1i8 << 8); //~ ERROR: evaluation of constant value failed
+
+const _NI16_SHL: i16 = 1i16 << 16; //~ ERROR: evaluation of constant value failed
+const _NI16_SHL_P: &i16 = &(1i16 << 16); //~ ERROR: evaluation of constant value failed
+
+const _NI32_SHL: i32 = 1i32 << 32; //~ ERROR: evaluation of constant value failed
+const _NI32_SHL_P: &i32 = &(1i32 << 32); //~ ERROR: evaluation of constant value failed
+
+const _NI64_SHL: i64 = 1i64 << 64; //~ ERROR: evaluation of constant value failed
+const _NI64_SHL_P: &i64 = &(1i64 << 64); //~ ERROR: evaluation of constant value failed
+
+const _NI128_SHL: i128 = 1i128 << 128; //~ ERROR: evaluation of constant value failed
+const _NI128_SHL_P: &i128 = &(1i128 << 128); //~ ERROR: evaluation of constant value failed
+
+const _NU8_SHL: u8 = 1u8 << 8; //~ ERROR: evaluation of constant value failed
+const _NU8_SHL_P: &u8 = &(1u8 << 8); //~ ERROR: evaluation of constant value failed
+
+const _NU16_SHL: u16 = 1u16 << 16; //~ ERROR: evaluation of constant value failed
+const _NU16_SHL_P: &u16 = &(1u16 << 16); //~ ERROR: evaluation of constant value failed
+
+const _NU32_SHL: u32 = 1u32 << 32; //~ ERROR: evaluation of constant value failed
+const _NU32_SHL_P: &u32 = &(1u32 << 32); //~ ERROR: evaluation of constant value failed
+
+const _NU64_SHL: u64 = 1u64 << 64; //~ ERROR: evaluation of constant value failed
+const _NU64_SHL_P: &u64 = &(1u64 << 64); //~ ERROR: evaluation of constant value failed
+
+const _NU128_SHL: u128 = 1u128 << 128; //~ ERROR: evaluation of constant value failed
+const _NU128_SHL_P: &u128 = &(1u128 << 128); //~ ERROR: evaluation of constant value failed
+
+const _NISIZE_SHL: isize = 1isize << BITS; //~ ERROR: evaluation of constant value failed
+const _NISIZE_SHL_P: &isize = &(1isize << BITS); //~ ERROR: evaluation of constant value failed
+
+const _NUSIZE_SHL: usize = 1usize << BITS; //~ ERROR: evaluation of constant value failed
+const _NUSIZE_SHL_P: &usize = &(1usize << BITS); //~ ERROR: evaluation of constant value failed
+
+
+// Shift right
+const _NI8_SHR: i8 = 1i8 >> 8; //~ ERROR: evaluation of constant value failed
+const _NI8_SHR_P: &i8 = &(1i8 >> 8); //~ ERROR: evaluation of constant value failed
+
+const _NI16_SHR: i16 = 1i16 >> 16; //~ ERROR: evaluation of constant value failed
+const _NI16_SHR_P: &i16 = &(1i16 >> 16); //~ ERROR: evaluation of constant value failed
+
+const _NI32_SHR: i32 = 1i32 >> 32; //~ ERROR: evaluation of constant value failed
+const _NI32_SHR_P: &i32 = &(1i32 >> 32); //~ ERROR: evaluation of constant value failed
+
+const _NI64_SHR: i64 = 1i64 >> 64; //~ ERROR: evaluation of constant value failed
+const _NI64_SHR_P: &i64 = &(1i64 >> 64); //~ ERROR: evaluation of constant value failed
+
+const _NI128_SHR: i128 = 1i128 >> 128; //~ ERROR: evaluation of constant value failed
+const _NI128_SHR_P: &i128 = &(1i128 >> 128); //~ ERROR: evaluation of constant value failed
+
+const _NU8_SHR: u8 = 1u8 >> 8; //~ ERROR: evaluation of constant value failed
+const _NU8_SHR_P: &u8 = &(1u8 >> 8); //~ ERROR: evaluation of constant value failed
+
+const _NU16_SHR: u16 = 1u16 >> 16; //~ ERROR: evaluation of constant value failed
+const _NU16_SHR_P: &u16 = &(1u16 >> 16); //~ ERROR: evaluation of constant value failed
+
+const _NU32_SHR: u32 = 1u32 >> 32; //~ ERROR: evaluation of constant value failed
+const _NU32_SHR_P: &u32 = &(1u32 >> 32); //~ ERROR: evaluation of constant value failed
+
+const _NU64_SHR: u64 = 1u64 >> 64; //~ ERROR: evaluation of constant value failed
+const _NU64_SHR_P: &u64 = &(1u64 >> 64); //~ ERROR: evaluation of constant value failed
+
+const _NU128_SHR: u128 = 1u128 >> 128; //~ ERROR: evaluation of constant value failed
+const _NU128_SHR_P: &u128 = &(1u128 >> 128); //~ ERROR: evaluation of constant value failed
+
+const _NISIZE_SHR: isize = 1isize >> BITS; //~ ERROR: evaluation of constant value failed
+const _NISIZE_SHR_P: &isize = &(1isize >> BITS); //~ ERROR: evaluation of constant value failed
+
+const _NUSIZE_SHR: usize = 1usize >> BITS; //~ ERROR: evaluation of constant value failed
+const _NUSIZE_SHR_P: &usize = &(1usize >> BITS); //~ ERROR: evaluation of constant value failed
+
+
+// Addition
+const _NI8_ADD: i8 = 1i8 + i8::MAX; //~ ERROR: evaluation of constant value failed
+const _NI8_ADD_P: &i8 = &(1i8 + i8::MAX); //~ ERROR: evaluation of constant value failed
+
+const _NI16_ADD: i16 = 1i16 + i16::MAX; //~ ERROR: evaluation of constant value failed
+const _NI16_ADD_P: &i16 = &(1i16 + i16::MAX); //~ ERROR: evaluation of constant value failed
+
+const _NI32_ADD: i32 = 1i32 + i32::MAX; //~ ERROR: evaluation of constant value failed
+const _NI32_ADD_P: &i32 = &(1i32 + i32::MAX); //~ ERROR: evaluation of constant value failed
+
+const _NI64_ADD: i64 = 1i64 + i64::MAX; //~ ERROR: evaluation of constant value failed
+const _NI64_ADD_P: &i64 = &(1i64 + i64::MAX); //~ ERROR: evaluation of constant value failed
+
+const _NI128_ADD: i128 = 1i128 + i128::MAX; //~ ERROR: evaluation of constant value failed
+const _NI128_ADD_P: &i128 = &(1i128 + i128::MAX); //~ ERROR: evaluation of constant value failed
+
+const _NU8_ADD: u8 = 1u8 + u8::MAX; //~ ERROR: evaluation of constant value failed
+const _NU8_ADD_P: &u8 = &(1u8 + u8::MAX); //~ ERROR: evaluation of constant value failed
+
+const _NU16_ADD: u16 = 1u16 + u16::MAX; //~ ERROR: evaluation of constant value failed
+const _NU16_ADD_P: &u16 = &(1u16 + u16::MAX); //~ ERROR: evaluation of constant value failed
+
+const _NU32_ADD: u32 = 1u32 + u32::MAX; //~ ERROR: evaluation of constant value failed
+const _NU32_ADD_P: &u32 = &(1u32 + u32::MAX); //~ ERROR: evaluation of constant value failed
+
+const _NU64_ADD: u64 = 1u64 + u64::MAX; //~ ERROR: evaluation of constant value failed
+const _NU64_ADD_P: &u64 = &(1u64 + u64::MAX); //~ ERROR: evaluation of constant value failed
+
+const _NU128_ADD: u128 = 1u128 + u128::MAX; //~ ERROR: evaluation of constant value failed
+const _NU128_ADD_P: &u128 = &(1u128 + u128::MAX); //~ ERROR: evaluation of constant value failed
+
+const _NISIZE_ADD: isize = 1isize + isize::MAX; //~ ERROR: evaluation of constant value failed
+const _NISIZE_ADD_P: &isize = &(1isize + isize::MAX); //~ ERROR: evaluation of constant value failed
+
+const _NUSIZE_ADD: usize = 1usize + usize::MAX; //~ ERROR: evaluation of constant value failed
+const _NUSIZE_ADD_P: &usize = &(1usize + usize::MAX); //~ ERROR: evaluation of constant value failed
+
+
+// Subtraction
+const _NI8_SUB: i8 = -5i8 - i8::MAX; //~ ERROR: evaluation of constant value failed
+const _NI8_SUB_P: &i8 = &(-5i8 - i8::MAX); //~ ERROR: evaluation of constant value failed
+
+const _NI16_SUB: i16 = -5i16 - i16::MAX; //~ ERROR: evaluation of constant value failed
+const _NI16_SUB_P: &i16 = &(-5i16 - i16::MAX); //~ ERROR: evaluation of constant value failed
+
+const _NI32_SUB: i32 = -5i32 - i32::MAX; //~ ERROR: evaluation of constant value failed
+const _NI32_SUB_P: &i32 = &(-5i32 - i32::MAX); //~ ERROR: evaluation of constant value failed
+
+const _NI64_SUB: i64 = -5i64 - i64::MAX; //~ ERROR: evaluation of constant value failed
+const _NI64_SUB_P: &i64 = &(-5i64 - i64::MAX); //~ ERROR: evaluation of constant value failed
+
+const _NI128_SUB: i128 = -5i128 - i128::MAX; //~ ERROR: evaluation of constant value failed
+const _NI128_SUB_P: &i128 = &(-5i128 - i128::MAX); //~ ERROR: evaluation of constant value failed
+
+const _NU8_SUB: u8 = 1u8 - 5; //~ ERROR: evaluation of constant value failed
+const _NU8_SUB_P: &u8 = &(1u8 - 5); //~ ERROR: evaluation of constant value failed
+
+const _NU16_SUB: u16 = 1u16 - 5; //~ ERROR: evaluation of constant value failed
+const _NU16_SUB_P: &u16 = &(1u16 - 5); //~ ERROR: evaluation of constant value failed
+
+const _NU32_SUB: u32 = 1u32 - 5; //~ ERROR: evaluation of constant value failed
+const _NU32_SUB_P: &u32 = &(1u32 - 5); //~ ERROR: evaluation of constant value failed
+
+const _NU64_SUB: u64 = 1u64 - 5; //~ ERROR: evaluation of constant value failed
+const _NU64_SUB_P: &u64 = &(1u64 - 5); //~ ERROR: evaluation of constant value failed
+
+const _NU128_SUB: u128 = 1u128 - 5; //~ ERROR: evaluation of constant value failed
+const _NU128_SUB_P: &u128 = &(1u128 - 5); //~ ERROR: evaluation of constant value failed
+
+const _NISIZE_SUB: isize = -5isize - isize::MAX; //~ ERROR: evaluation of constant value failed
+const _NISIZE_SUB_P: &isize = &(-5isize - isize::MAX); //~ ERROR: evaluation of constant value failed
+
+const _NUSIZE_SUB: usize = 1usize - 5 ; //~ ERROR: evaluation of constant value failed
+const _NUSIZE_SUB_P: &usize = &(1usize - 5 ); //~ ERROR: evaluation of constant value failed
+
+
+// Multiplication
+const _NI8_MUL: i8 = i8::MAX * 5; //~ ERROR: evaluation of constant value failed
+const _NI8_MUL_P: &i8 = &(i8::MAX * 5); //~ ERROR: evaluation of constant value failed
+
+const _NI16_MUL: i16 = i16::MAX * 5; //~ ERROR: evaluation of constant value failed
+const _NI16_MUL_P: &i16 = &(i16::MAX * 5); //~ ERROR: evaluation of constant value failed
+
+const _NI32_MUL: i32 = i32::MAX * 5; //~ ERROR: evaluation of constant value failed
+const _NI32_MUL_P: &i32 = &(i32::MAX * 5); //~ ERROR: evaluation of constant value failed
+
+const _NI64_MUL: i64 = i64::MAX * 5; //~ ERROR: evaluation of constant value failed
+const _NI64_MUL_P: &i64 = &(i64::MAX * 5); //~ ERROR: evaluation of constant value failed
+
+const _NI128_MUL: i128 = i128::MAX * 5; //~ ERROR: evaluation of constant value failed
+const _NI128_MUL_P: &i128 = &(i128::MAX * 5); //~ ERROR: evaluation of constant value failed
+
+const _NU8_MUL: u8 = u8::MAX * 5; //~ ERROR: evaluation of constant value failed
+const _NU8_MUL_P: &u8 = &(u8::MAX * 5); //~ ERROR: evaluation of constant value failed
+
+const _NU16_MUL: u16 = u16::MAX * 5; //~ ERROR: evaluation of constant value failed
+const _NU16_MUL_P: &u16 = &(u16::MAX * 5); //~ ERROR: evaluation of constant value failed
+
+const _NU32_MUL: u32 = u32::MAX * 5; //~ ERROR: evaluation of constant value failed
+const _NU32_MUL_P: &u32 = &(u32::MAX * 5); //~ ERROR: evaluation of constant value failed
+
+const _NU64_MUL: u64 = u64::MAX * 5; //~ ERROR: evaluation of constant value failed
+const _NU64_MUL_P: &u64 = &(u64::MAX * 5); //~ ERROR: evaluation of constant value failed
+
+const _NU128_MUL: u128 = u128::MAX * 5; //~ ERROR: evaluation of constant value failed
+const _NU128_MUL_P: &u128 = &(u128::MAX * 5); //~ ERROR: evaluation of constant value failed
+
+const _NISIZE_MUL: isize = isize::MAX * 5; //~ ERROR: evaluation of constant value failed
+const _NISIZE_MUL_P: &isize = &(isize::MAX * 5); //~ ERROR: evaluation of constant value failed
+
+const _NUSIZE_MUL: usize = usize::MAX * 5; //~ ERROR: evaluation of constant value failed
+const _NUSIZE_MUL_P: &usize = &(usize::MAX * 5); //~ ERROR: evaluation of constant value failed
+
+
+// Division
+const _NI8_DIV: i8 = 1i8 / 0; //~ ERROR: evaluation of constant value failed
+const _NI8_DIV_P: &i8 = &(1i8 / 0); //~ ERROR: evaluation of constant value failed
+
+const _NI16_DIV: i16 = 1i16 / 0; //~ ERROR: evaluation of constant value failed
+const _NI16_DIV_P: &i16 = &(1i16 / 0); //~ ERROR: evaluation of constant value failed
+
+const _NI32_DIV: i32 = 1i32 / 0; //~ ERROR: evaluation of constant value failed
+const _NI32_DIV_P: &i32 = &(1i32 / 0); //~ ERROR: evaluation of constant value failed
+
+const _NI64_DIV: i64 = 1i64 / 0; //~ ERROR: evaluation of constant value failed
+const _NI64_DIV_P: &i64 = &(1i64 / 0); //~ ERROR: evaluation of constant value failed
+
+const _NI128_DIV: i128 = 1i128 / 0; //~ ERROR: evaluation of constant value failed
+const _NI128_DIV_P: &i128 = &(1i128 / 0); //~ ERROR: evaluation of constant value failed
+
+const _NU8_DIV: u8 = 1u8 / 0; //~ ERROR: evaluation of constant value failed
+const _NU8_DIV_P: &u8 = &(1u8 / 0); //~ ERROR: evaluation of constant value failed
+
+const _NU16_DIV: u16 = 1u16 / 0; //~ ERROR: evaluation of constant value failed
+const _NU16_DIV_P: &u16 = &(1u16 / 0); //~ ERROR: evaluation of constant value failed
+
+const _NU32_DIV: u32 = 1u32 / 0; //~ ERROR: evaluation of constant value failed
+const _NU32_DIV_P: &u32 = &(1u32 / 0); //~ ERROR: evaluation of constant value failed
+
+const _NU64_DIV: u64 = 1u64 / 0; //~ ERROR: evaluation of constant value failed
+const _NU64_DIV_P: &u64 = &(1u64 / 0); //~ ERROR: evaluation of constant value failed
+
+const _NU128_DIV: u128 = 1u128 / 0; //~ ERROR: evaluation of constant value failed
+const _NU128_DIV_P: &u128 = &(1u128 / 0); //~ ERROR: evaluation of constant value failed
+
+const _NISIZE_DIV: isize = 1isize / 0; //~ ERROR: evaluation of constant value failed
+const _NISIZE_DIV_P: &isize = &(1isize / 0); //~ ERROR: evaluation of constant value failed
+
+const _NUSIZE_DIV: usize = 1usize / 0; //~ ERROR: evaluation of constant value failed
+const _NUSIZE_DIV_P: &usize = &(1usize / 0); //~ ERROR: evaluation of constant value failed
+
+// Modulus
+const _NI8_MOD: i8 = 1i8 % 0; //~ ERROR: evaluation of constant value failed
+const _NI8_MOD_P: &i8 = &(1i8 % 0); //~ ERROR: evaluation of constant value failed
+
+const _NI16_MOD: i16 = 1i16 % 0; //~ ERROR: evaluation of constant value failed
+const _NI16_MOD_P: &i16 = &(1i16 % 0); //~ ERROR: evaluation of constant value failed
+
+const _NI32_MOD: i32 = 1i32 % 0; //~ ERROR: evaluation of constant value failed
+const _NI32_MOD_P: &i32 = &(1i32 % 0); //~ ERROR: evaluation of constant value failed
+
+const _NI64_MOD: i64 = 1i64 % 0; //~ ERROR: evaluation of constant value failed
+const _NI64_MOD_P: &i64 = &(1i64 % 0); //~ ERROR: evaluation of constant value failed
+
+const _NI128_MOD: i128 = 1i128 % 0; //~ ERROR: evaluation of constant value failed
+const _NI128_MOD_P: &i128 = &(1i128 % 0); //~ ERROR: evaluation of constant value failed
+
+const _NU8_MOD: u8 = 1u8 % 0; //~ ERROR: evaluation of constant value failed
+const _NU8_MOD_P: &u8 = &(1u8 % 0); //~ ERROR: evaluation of constant value failed
+
+const _NU16_MOD: u16 = 1u16 % 0; //~ ERROR: evaluation of constant value failed
+const _NU16_MOD_P: &u16 = &(1u16 % 0); //~ ERROR: evaluation of constant value failed
+
+const _NU32_MOD: u32 = 1u32 % 0; //~ ERROR: evaluation of constant value failed
+const _NU32_MOD_P: &u32 = &(1u32 % 0); //~ ERROR: evaluation of constant value failed
+
+const _NU64_MOD: u64 = 1u64 % 0; //~ ERROR: evaluation of constant value failed
+const _NU64_MOD_P: &u64 = &(1u64 % 0); //~ ERROR: evaluation of constant value failed
+
+const _NU128_MOD: u128 = 1u128 % 0; //~ ERROR: evaluation of constant value failed
+const _NU128_MOD_P: &u128 = &(1u128 % 0); //~ ERROR: evaluation of constant value failed
+
+const _NISIZE_MOD: isize = 1isize % 0; //~ ERROR: evaluation of constant value failed
+const _NISIZE_MOD_P: &isize = &(1isize % 0); //~ ERROR: evaluation of constant value failed
+
+const _NUSIZE_MOD: usize = 1usize % 0; //~ ERROR: evaluation of constant value failed
+const _NUSIZE_MOD_P: &usize = &(1usize % 0); //~ ERROR: evaluation of constant value failed
+
+
+// Out of bounds access
+const _NI32_OOB: i32 = [1, 2, 3][4]; //~ ERROR: evaluation of constant value failed
+const _NI32_OOB_P: &i32 = &([1, 2, 3][4]); //~ ERROR: evaluation of constant value failed
+
+
+pub fn main() {}
diff --git a/tests/ui/consts/promotion.rs b/tests/ui/consts/promotion.rs
index 783ca47d2c6..211dcf8a4e8 100644
--- a/tests/ui/consts/promotion.rs
+++ b/tests/ui/consts/promotion.rs
@@ -25,9 +25,8 @@ fn main() {
     assert_static(&["d", "e", "f"]);
     assert_eq!(C, 42);
 
-    // make sure that these do not cause trouble despite overflowing
+    // make sure that this does not cause trouble despite overflowing
     assert_static(&(0-1));
-    assert_static(&-i32::MIN);
 
     // div-by-non-0 is okay
     assert_static(&(1/1));
diff --git a/tests/ui/error-codes/E0017.rs b/tests/ui/error-codes/E0017.rs
index 9d3433fa543..c128c2779e2 100644
--- a/tests/ui/error-codes/E0017.rs
+++ b/tests/ui/error-codes/E0017.rs
@@ -1,3 +1,5 @@
+#![feature(const_mut_refs)]
+
 static X: i32 = 1;
 const C: i32 = 2;
 static mut M: i32 = 3;
@@ -5,14 +7,12 @@ static mut M: i32 = 3;
 const CR: &'static mut i32 = &mut C; //~ ERROR mutable references are not allowed
 //~| WARN taking a mutable
 
-static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0658
-//~| ERROR cannot borrow
-//~| ERROR mutable references are not allowed
+static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR cannot borrow immutable static item `X` as mutable
 
 static CONST_REF: &'static mut i32 = &mut C; //~ ERROR mutable references are not allowed
 //~| WARN taking a mutable
 
-static STATIC_MUT_REF: &'static mut i32 = unsafe { &mut M }; //~ ERROR mutable references are not
+static STATIC_MUT_REF: &'static mut i32 = unsafe { &mut M };
 //~^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
 
 fn main() {}
diff --git a/tests/ui/error-codes/E0017.stderr b/tests/ui/error-codes/E0017.stderr
index 2a70f2ee0ae..eb626a7fe3a 100644
--- a/tests/ui/error-codes/E0017.stderr
+++ b/tests/ui/error-codes/E0017.stderr
@@ -14,7 +14,7 @@ LL | static STATIC_MUT_REF: &'static mut i32 = unsafe { addr_of_mut!(M) };
    |                                                    ~~~~~~~~~~~~~~~
 
 warning: taking a mutable reference to a `const` item
-  --> $DIR/E0017.rs:5:30
+  --> $DIR/E0017.rs:7:30
    |
 LL | const CR: &'static mut i32 = &mut C;
    |                              ^^^^^^
@@ -22,36 +22,20 @@ LL | const CR: &'static mut i32 = &mut C;
    = note: each usage of a `const` item creates a new temporary
    = note: the mutable reference will refer to this temporary, not the original `const` item
 note: `const` item defined here
-  --> $DIR/E0017.rs:2:1
+  --> $DIR/E0017.rs:4:1
    |
 LL | const C: i32 = 2;
    | ^^^^^^^^^^^^
    = note: `#[warn(const_item_mutation)]` on by default
 
 error[E0764]: mutable references are not allowed in the final value of constants
-  --> $DIR/E0017.rs:5:30
+  --> $DIR/E0017.rs:7:30
    |
 LL | const CR: &'static mut i32 = &mut C;
    |                              ^^^^^^
 
-error[E0658]: mutation through a reference is not allowed in statics
-  --> $DIR/E0017.rs:8:39
-   |
-LL | static STATIC_REF: &'static mut i32 = &mut X;
-   |                                       ^^^^^^
-   |
-   = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
-   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error[E0764]: mutable references are not allowed in the final value of statics
-  --> $DIR/E0017.rs:8:39
-   |
-LL | static STATIC_REF: &'static mut i32 = &mut X;
-   |                                       ^^^^^^
-
 error[E0596]: cannot borrow immutable static item `X` as mutable
-  --> $DIR/E0017.rs:8:39
+  --> $DIR/E0017.rs:10:39
    |
 LL | static STATIC_REF: &'static mut i32 = &mut X;
    |                                       ^^^^^^ cannot borrow as mutable
@@ -65,7 +49,7 @@ LL | static CONST_REF: &'static mut i32 = &mut C;
    = note: each usage of a `const` item creates a new temporary
    = note: the mutable reference will refer to this temporary, not the original `const` item
 note: `const` item defined here
-  --> $DIR/E0017.rs:2:1
+  --> $DIR/E0017.rs:4:1
    |
 LL | const C: i32 = 2;
    | ^^^^^^^^^^^^
@@ -76,13 +60,7 @@ error[E0764]: mutable references are not allowed in the final value of statics
 LL | static CONST_REF: &'static mut i32 = &mut C;
    |                                      ^^^^^^
 
-error[E0764]: mutable references are not allowed in the final value of statics
-  --> $DIR/E0017.rs:15:52
-   |
-LL | static STATIC_MUT_REF: &'static mut i32 = unsafe { &mut M };
-   |                                                    ^^^^^^
-
-error: aborting due to 6 previous errors; 3 warnings emitted
+error: aborting due to 3 previous errors; 3 warnings emitted
 
-Some errors have detailed explanations: E0596, E0658, E0764.
+Some errors have detailed explanations: E0596, E0764.
 For more information about an error, try `rustc --explain E0596`.
diff --git a/tests/ui/error-codes/E0388.rs b/tests/ui/error-codes/E0388.rs
index 6049d95f0d2..bd371328e6b 100644
--- a/tests/ui/error-codes/E0388.rs
+++ b/tests/ui/error-codes/E0388.rs
@@ -3,9 +3,7 @@ const C: i32 = 2;
 
 const CR: &'static mut i32 = &mut C; //~ ERROR mutable references are not allowed
                                      //~| WARN taking a mutable
-static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR cannot borrow
-                                              //~| ERROR E0658
-                                              //~| ERROR mutable references are not allowed
+static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0658
 
 static CONST_REF: &'static mut i32 = &mut C; //~ ERROR mutable references are not allowed
                                              //~| WARN taking a mutable
diff --git a/tests/ui/error-codes/E0388.stderr b/tests/ui/error-codes/E0388.stderr
index 1f7b688899e..3e89e3f804b 100644
--- a/tests/ui/error-codes/E0388.stderr
+++ b/tests/ui/error-codes/E0388.stderr
@@ -19,7 +19,7 @@ error[E0764]: mutable references are not allowed in the final value of constants
 LL | const CR: &'static mut i32 = &mut C;
    |                              ^^^^^^
 
-error[E0658]: mutation through a reference is not allowed in statics
+error[E0658]: mutable references are not allowed in statics
   --> $DIR/E0388.rs:6:39
    |
 LL | static STATIC_REF: &'static mut i32 = &mut X;
@@ -29,20 +29,8 @@ LL | static STATIC_REF: &'static mut i32 = &mut X;
    = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error[E0764]: mutable references are not allowed in the final value of statics
-  --> $DIR/E0388.rs:6:39
-   |
-LL | static STATIC_REF: &'static mut i32 = &mut X;
-   |                                       ^^^^^^
-
-error[E0596]: cannot borrow immutable static item `X` as mutable
-  --> $DIR/E0388.rs:6:39
-   |
-LL | static STATIC_REF: &'static mut i32 = &mut X;
-   |                                       ^^^^^^ cannot borrow as mutable
-
 warning: taking a mutable reference to a `const` item
-  --> $DIR/E0388.rs:10:38
+  --> $DIR/E0388.rs:8:38
    |
 LL | static CONST_REF: &'static mut i32 = &mut C;
    |                                      ^^^^^^
@@ -56,12 +44,12 @@ LL | const C: i32 = 2;
    | ^^^^^^^^^^^^
 
 error[E0764]: mutable references are not allowed in the final value of statics
-  --> $DIR/E0388.rs:10:38
+  --> $DIR/E0388.rs:8:38
    |
 LL | static CONST_REF: &'static mut i32 = &mut C;
    |                                      ^^^^^^
 
-error: aborting due to 5 previous errors; 2 warnings emitted
+error: aborting due to 3 previous errors; 2 warnings emitted
 
-Some errors have detailed explanations: E0596, E0658, E0764.
-For more information about an error, try `rustc --explain E0596`.
+Some errors have detailed explanations: E0658, E0764.
+For more information about an error, try `rustc --explain E0658`.
diff --git a/tests/ui/intrinsics/safe-intrinsic-mismatch.rs b/tests/ui/intrinsics/safe-intrinsic-mismatch.rs
index fcd6612f125..23cd5f10835 100644
--- a/tests/ui/intrinsics/safe-intrinsic-mismatch.rs
+++ b/tests/ui/intrinsics/safe-intrinsic-mismatch.rs
@@ -5,13 +5,13 @@
 extern "rust-intrinsic" {
     fn size_of<T>() -> usize; //~ ERROR intrinsic safety mismatch
     //~^ ERROR intrinsic safety mismatch
-
-    #[rustc_safe_intrinsic]
-    fn assume(b: bool); //~ ERROR intrinsic safety mismatch
-    //~^ ERROR intrinsic safety mismatch
 }
 
 #[rustc_intrinsic]
+const fn assume(_b: bool) {} //~ ERROR intrinsic safety mismatch
+//~| ERROR intrinsic has wrong type
+
+#[rustc_intrinsic]
 const fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {}
 //~^ ERROR intrinsic safety mismatch
 //~| ERROR intrinsic has wrong type
diff --git a/tests/ui/intrinsics/safe-intrinsic-mismatch.stderr b/tests/ui/intrinsics/safe-intrinsic-mismatch.stderr
index 0b579121ac1..2e0812d6472 100644
--- a/tests/ui/intrinsics/safe-intrinsic-mismatch.stderr
+++ b/tests/ui/intrinsics/safe-intrinsic-mismatch.stderr
@@ -4,12 +4,6 @@ error: intrinsic safety mismatch between list of intrinsics within the compiler
 LL |     fn size_of<T>() -> usize;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `assume`
-  --> $DIR/safe-intrinsic-mismatch.rs:10:5
-   |
-LL |     fn assume(b: bool);
-   |     ^^^^^^^^^^^^^^^^^^
-
 error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `size_of`
   --> $DIR/safe-intrinsic-mismatch.rs:6:5
    |
@@ -19,12 +13,19 @@ LL |     fn size_of<T>() -> usize;
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `assume`
-  --> $DIR/safe-intrinsic-mismatch.rs:10:5
+  --> $DIR/safe-intrinsic-mismatch.rs:11:1
    |
-LL |     fn assume(b: bool);
-   |     ^^^^^^^^^^^^^^^^^^
+LL | const fn assume(_b: bool) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0308]: intrinsic has wrong type
+  --> $DIR/safe-intrinsic-mismatch.rs:11:16
    |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+LL | const fn assume(_b: bool) {}
+   |                ^ expected unsafe fn, found normal fn
+   |
+   = note: expected signature `unsafe fn(_)`
+              found signature `fn(_)`
 
 error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `const_deallocate`
   --> $DIR/safe-intrinsic-mismatch.rs:15:1
diff --git a/tests/ui/lint/issue-117949.noopt.stderr b/tests/ui/lint/issue-117949.noopt.stderr
new file mode 100644
index 00000000000..607488e2a4a
--- /dev/null
+++ b/tests/ui/lint/issue-117949.noopt.stderr
@@ -0,0 +1,54 @@
+error: this arithmetic operation will overflow
+  --> $DIR/issue-117949.rs:16:24
+   |
+LL |     format_args!("{}", 5 * i32::MAX);
+   |                        ^^^^^^^^^^^^ attempt to compute `5_i32 * i32::MAX`, which would overflow
+   |
+   = note: `#[deny(arithmetic_overflow)]` on by default
+
+error: this arithmetic operation will overflow
+  --> $DIR/issue-117949.rs:15:24
+   |
+LL |     format_args!("{}", -5 - i32::MAX);
+   |                        ^^^^^^^^^^^^^ attempt to compute `-5_i32 - i32::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/issue-117949.rs:14:24
+   |
+LL |     format_args!("{}", 1 + i32::MAX);
+   |                        ^^^^^^^^^^^^ attempt to compute `1_i32 + i32::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/issue-117949.rs:13:24
+   |
+LL |     format_args!("{}", 1 >> 32);
+   |                        ^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/issue-117949.rs:12:24
+   |
+LL |     format_args!("{}", 1 << 32);
+   |                        ^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+error: this operation will panic at runtime
+  --> $DIR/issue-117949.rs:17:24
+   |
+LL |     format_args!("{}", 1 / 0);
+   |                        ^^^^^ attempt to divide `1_i32` by zero
+   |
+   = note: `#[deny(unconditional_panic)]` on by default
+
+error: this operation will panic at runtime
+  --> $DIR/issue-117949.rs:18:24
+   |
+LL |     format_args!("{}", 1 % 0);
+   |                        ^^^^^ attempt to calculate the remainder of `1_i32` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/issue-117949.rs:19:24
+   |
+LL |     format_args!("{}", [1, 2, 3][4]);
+   |                        ^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 4
+
+error: aborting due to 8 previous errors
+
diff --git a/tests/ui/lint/issue-117949.opt.stderr b/tests/ui/lint/issue-117949.opt.stderr
new file mode 100644
index 00000000000..607488e2a4a
--- /dev/null
+++ b/tests/ui/lint/issue-117949.opt.stderr
@@ -0,0 +1,54 @@
+error: this arithmetic operation will overflow
+  --> $DIR/issue-117949.rs:16:24
+   |
+LL |     format_args!("{}", 5 * i32::MAX);
+   |                        ^^^^^^^^^^^^ attempt to compute `5_i32 * i32::MAX`, which would overflow
+   |
+   = note: `#[deny(arithmetic_overflow)]` on by default
+
+error: this arithmetic operation will overflow
+  --> $DIR/issue-117949.rs:15:24
+   |
+LL |     format_args!("{}", -5 - i32::MAX);
+   |                        ^^^^^^^^^^^^^ attempt to compute `-5_i32 - i32::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/issue-117949.rs:14:24
+   |
+LL |     format_args!("{}", 1 + i32::MAX);
+   |                        ^^^^^^^^^^^^ attempt to compute `1_i32 + i32::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/issue-117949.rs:13:24
+   |
+LL |     format_args!("{}", 1 >> 32);
+   |                        ^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/issue-117949.rs:12:24
+   |
+LL |     format_args!("{}", 1 << 32);
+   |                        ^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+error: this operation will panic at runtime
+  --> $DIR/issue-117949.rs:17:24
+   |
+LL |     format_args!("{}", 1 / 0);
+   |                        ^^^^^ attempt to divide `1_i32` by zero
+   |
+   = note: `#[deny(unconditional_panic)]` on by default
+
+error: this operation will panic at runtime
+  --> $DIR/issue-117949.rs:18:24
+   |
+LL |     format_args!("{}", 1 % 0);
+   |                        ^^^^^ attempt to calculate the remainder of `1_i32` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/issue-117949.rs:19:24
+   |
+LL |     format_args!("{}", [1, 2, 3][4]);
+   |                        ^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 4
+
+error: aborting due to 8 previous errors
+
diff --git a/tests/ui/lint/issue-117949.opt_with_overflow_checks.stderr b/tests/ui/lint/issue-117949.opt_with_overflow_checks.stderr
new file mode 100644
index 00000000000..607488e2a4a
--- /dev/null
+++ b/tests/ui/lint/issue-117949.opt_with_overflow_checks.stderr
@@ -0,0 +1,54 @@
+error: this arithmetic operation will overflow
+  --> $DIR/issue-117949.rs:16:24
+   |
+LL |     format_args!("{}", 5 * i32::MAX);
+   |                        ^^^^^^^^^^^^ attempt to compute `5_i32 * i32::MAX`, which would overflow
+   |
+   = note: `#[deny(arithmetic_overflow)]` on by default
+
+error: this arithmetic operation will overflow
+  --> $DIR/issue-117949.rs:15:24
+   |
+LL |     format_args!("{}", -5 - i32::MAX);
+   |                        ^^^^^^^^^^^^^ attempt to compute `-5_i32 - i32::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/issue-117949.rs:14:24
+   |
+LL |     format_args!("{}", 1 + i32::MAX);
+   |                        ^^^^^^^^^^^^ attempt to compute `1_i32 + i32::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/issue-117949.rs:13:24
+   |
+LL |     format_args!("{}", 1 >> 32);
+   |                        ^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/issue-117949.rs:12:24
+   |
+LL |     format_args!("{}", 1 << 32);
+   |                        ^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+error: this operation will panic at runtime
+  --> $DIR/issue-117949.rs:17:24
+   |
+LL |     format_args!("{}", 1 / 0);
+   |                        ^^^^^ attempt to divide `1_i32` by zero
+   |
+   = note: `#[deny(unconditional_panic)]` on by default
+
+error: this operation will panic at runtime
+  --> $DIR/issue-117949.rs:18:24
+   |
+LL |     format_args!("{}", 1 % 0);
+   |                        ^^^^^ attempt to calculate the remainder of `1_i32` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/issue-117949.rs:19:24
+   |
+LL |     format_args!("{}", [1, 2, 3][4]);
+   |                        ^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 4
+
+error: aborting due to 8 previous errors
+
diff --git a/tests/ui/lint/issue-117949.rs b/tests/ui/lint/issue-117949.rs
new file mode 100644
index 00000000000..5673227f35d
--- /dev/null
+++ b/tests/ui/lint/issue-117949.rs
@@ -0,0 +1,20 @@
+// Regression test for issue #117949
+
+//@ revisions: noopt opt opt_with_overflow_checks
+//@ [noopt]compile-flags: -C opt-level=0 -Z deduplicate-diagnostics=yes
+//@ [opt]compile-flags: -O
+//@ [opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O -Z deduplicate-diagnostics=yes
+//@ build-fail
+//@ ignore-pass (test tests codegen-time behaviour)
+
+
+fn main() {
+    format_args!("{}", 1 << 32); //~ ERROR: arithmetic operation will overflow
+    format_args!("{}", 1 >> 32); //~ ERROR: arithmetic operation will overflow
+    format_args!("{}", 1 + i32::MAX); //~ ERROR: arithmetic operation will overflow
+    format_args!("{}", -5 - i32::MAX); //~ ERROR: arithmetic operation will overflow
+    format_args!("{}", 5 * i32::MAX); //~ ERROR: arithmetic operation will overflow
+    format_args!("{}", 1 / 0); //~ ERROR: this operation will panic at runtime
+    format_args!("{}", 1 % 0); //~ ERROR: this operation will panic at runtime
+    format_args!("{}", [1, 2, 3][4]); //~ ERROR: this operation will panic at runtime
+}
diff --git a/tests/ui/lint/lint-exceeding-bitshifts.noopt.stderr b/tests/ui/lint/lint-exceeding-bitshifts.noopt.stderr
deleted file mode 100644
index 3a84c6c1fb1..00000000000
--- a/tests/ui/lint/lint-exceeding-bitshifts.noopt.stderr
+++ /dev/null
@@ -1,152 +0,0 @@
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:18:20
-   |
-LL |     const N: i32 = T::N << 42;
-   |                    ^^^^^^^^^^ attempt to shift left by `42_i32`, which would overflow
-   |
-note: the lint level is defined here
-  --> $DIR/lint-exceeding-bitshifts.rs:10:9
-   |
-LL | #![warn(arithmetic_overflow)]
-   |         ^^^^^^^^^^^^^^^^^^^
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:22:13
-   |
-LL |     let _ = x << 42;
-   |             ^^^^^^^ attempt to shift left by `42_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:27:15
-   |
-LL |       let n = 1u8 << 8;
-   |               ^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:29:15
-   |
-LL |       let n = 1u16 << 16;
-   |               ^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:31:15
-   |
-LL |       let n = 1u32 << 32;
-   |               ^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:33:15
-   |
-LL |       let n = 1u64 << 64;
-   |               ^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:35:15
-   |
-LL |       let n = 1i8 << 8;
-   |               ^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:37:15
-   |
-LL |       let n = 1i16 << 16;
-   |               ^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:39:15
-   |
-LL |       let n = 1i32 << 32;
-   |               ^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:41:15
-   |
-LL |       let n = 1i64 << 64;
-   |               ^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:44:15
-   |
-LL |       let n = 1u8 >> 8;
-   |               ^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:46:15
-   |
-LL |       let n = 1u16 >> 16;
-   |               ^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:48:15
-   |
-LL |       let n = 1u32 >> 32;
-   |               ^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:50:15
-   |
-LL |       let n = 1u64 >> 64;
-   |               ^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:52:15
-   |
-LL |       let n = 1i8 >> 8;
-   |               ^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:54:15
-   |
-LL |       let n = 1i16 >> 16;
-   |               ^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:56:15
-   |
-LL |       let n = 1i32 >> 32;
-   |               ^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:58:15
-   |
-LL |       let n = 1i64 >> 64;
-   |               ^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:62:15
-   |
-LL |       let n = n << 8;
-   |               ^^^^^^ attempt to shift left by `8_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:64:15
-   |
-LL |       let n = 1u8 << -8;
-   |               ^^^^^^^^^ attempt to shift left by `-8_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:69:15
-   |
-LL |       let n = 1u8 << (4+4);
-   |               ^^^^^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:71:15
-   |
-LL |       let n = 1i64 >> [64][0];
-   |               ^^^^^^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:77:15
-   |
-LL |       let n = 1_isize << BITS;
-   |               ^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:78:15
-   |
-LL |       let n = 1_usize << BITS;
-   |               ^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
-
-warning: 24 warnings emitted
-
diff --git a/tests/ui/lint/lint-exceeding-bitshifts.opt.stderr b/tests/ui/lint/lint-exceeding-bitshifts.opt.stderr
deleted file mode 100644
index 3a84c6c1fb1..00000000000
--- a/tests/ui/lint/lint-exceeding-bitshifts.opt.stderr
+++ /dev/null
@@ -1,152 +0,0 @@
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:18:20
-   |
-LL |     const N: i32 = T::N << 42;
-   |                    ^^^^^^^^^^ attempt to shift left by `42_i32`, which would overflow
-   |
-note: the lint level is defined here
-  --> $DIR/lint-exceeding-bitshifts.rs:10:9
-   |
-LL | #![warn(arithmetic_overflow)]
-   |         ^^^^^^^^^^^^^^^^^^^
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:22:13
-   |
-LL |     let _ = x << 42;
-   |             ^^^^^^^ attempt to shift left by `42_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:27:15
-   |
-LL |       let n = 1u8 << 8;
-   |               ^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:29:15
-   |
-LL |       let n = 1u16 << 16;
-   |               ^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:31:15
-   |
-LL |       let n = 1u32 << 32;
-   |               ^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:33:15
-   |
-LL |       let n = 1u64 << 64;
-   |               ^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:35:15
-   |
-LL |       let n = 1i8 << 8;
-   |               ^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:37:15
-   |
-LL |       let n = 1i16 << 16;
-   |               ^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:39:15
-   |
-LL |       let n = 1i32 << 32;
-   |               ^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:41:15
-   |
-LL |       let n = 1i64 << 64;
-   |               ^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:44:15
-   |
-LL |       let n = 1u8 >> 8;
-   |               ^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:46:15
-   |
-LL |       let n = 1u16 >> 16;
-   |               ^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:48:15
-   |
-LL |       let n = 1u32 >> 32;
-   |               ^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:50:15
-   |
-LL |       let n = 1u64 >> 64;
-   |               ^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:52:15
-   |
-LL |       let n = 1i8 >> 8;
-   |               ^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:54:15
-   |
-LL |       let n = 1i16 >> 16;
-   |               ^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:56:15
-   |
-LL |       let n = 1i32 >> 32;
-   |               ^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:58:15
-   |
-LL |       let n = 1i64 >> 64;
-   |               ^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:62:15
-   |
-LL |       let n = n << 8;
-   |               ^^^^^^ attempt to shift left by `8_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:64:15
-   |
-LL |       let n = 1u8 << -8;
-   |               ^^^^^^^^^ attempt to shift left by `-8_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:69:15
-   |
-LL |       let n = 1u8 << (4+4);
-   |               ^^^^^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:71:15
-   |
-LL |       let n = 1i64 >> [64][0];
-   |               ^^^^^^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:77:15
-   |
-LL |       let n = 1_isize << BITS;
-   |               ^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:78:15
-   |
-LL |       let n = 1_usize << BITS;
-   |               ^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
-
-warning: 24 warnings emitted
-
diff --git a/tests/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr b/tests/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr
deleted file mode 100644
index 3a84c6c1fb1..00000000000
--- a/tests/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr
+++ /dev/null
@@ -1,152 +0,0 @@
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:18:20
-   |
-LL |     const N: i32 = T::N << 42;
-   |                    ^^^^^^^^^^ attempt to shift left by `42_i32`, which would overflow
-   |
-note: the lint level is defined here
-  --> $DIR/lint-exceeding-bitshifts.rs:10:9
-   |
-LL | #![warn(arithmetic_overflow)]
-   |         ^^^^^^^^^^^^^^^^^^^
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:22:13
-   |
-LL |     let _ = x << 42;
-   |             ^^^^^^^ attempt to shift left by `42_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:27:15
-   |
-LL |       let n = 1u8 << 8;
-   |               ^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:29:15
-   |
-LL |       let n = 1u16 << 16;
-   |               ^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:31:15
-   |
-LL |       let n = 1u32 << 32;
-   |               ^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:33:15
-   |
-LL |       let n = 1u64 << 64;
-   |               ^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:35:15
-   |
-LL |       let n = 1i8 << 8;
-   |               ^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:37:15
-   |
-LL |       let n = 1i16 << 16;
-   |               ^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:39:15
-   |
-LL |       let n = 1i32 << 32;
-   |               ^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:41:15
-   |
-LL |       let n = 1i64 << 64;
-   |               ^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:44:15
-   |
-LL |       let n = 1u8 >> 8;
-   |               ^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:46:15
-   |
-LL |       let n = 1u16 >> 16;
-   |               ^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:48:15
-   |
-LL |       let n = 1u32 >> 32;
-   |               ^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:50:15
-   |
-LL |       let n = 1u64 >> 64;
-   |               ^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:52:15
-   |
-LL |       let n = 1i8 >> 8;
-   |               ^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:54:15
-   |
-LL |       let n = 1i16 >> 16;
-   |               ^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:56:15
-   |
-LL |       let n = 1i32 >> 32;
-   |               ^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:58:15
-   |
-LL |       let n = 1i64 >> 64;
-   |               ^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:62:15
-   |
-LL |       let n = n << 8;
-   |               ^^^^^^ attempt to shift left by `8_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:64:15
-   |
-LL |       let n = 1u8 << -8;
-   |               ^^^^^^^^^ attempt to shift left by `-8_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:69:15
-   |
-LL |       let n = 1u8 << (4+4);
-   |               ^^^^^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:71:15
-   |
-LL |       let n = 1i64 >> [64][0];
-   |               ^^^^^^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:77:15
-   |
-LL |       let n = 1_isize << BITS;
-   |               ^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:78:15
-   |
-LL |       let n = 1_usize << BITS;
-   |               ^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
-
-warning: 24 warnings emitted
-
diff --git a/tests/ui/lint/lint-exceeding-bitshifts.rs b/tests/ui/lint/lint-exceeding-bitshifts.rs
deleted file mode 100644
index ea9d5ce6781..00000000000
--- a/tests/ui/lint/lint-exceeding-bitshifts.rs
+++ /dev/null
@@ -1,79 +0,0 @@
-//@ revisions: noopt opt opt_with_overflow_checks
-//@[noopt]compile-flags: -C opt-level=0
-//@[opt]compile-flags: -O
-//@[opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O
-//@ build-pass
-//@ ignore-pass (test emits codegen-time warnings and verifies that they are not errors)
-//@ normalize-stderr-test "shift left by `(64|32)_usize`, which" -> "shift left by `%BITS%`, which"
-
-#![crate_type="lib"]
-#![warn(arithmetic_overflow)]
-
-
-pub trait Foo {
-    const N: i32;
-}
-
-impl<T: Foo> Foo for Vec<T> {
-    const N: i32 = T::N << 42; //~ WARN: arithmetic operation will overflow
-}
-
-pub fn foo(x: i32) {
-    let _ = x << 42; //~ WARN: arithmetic operation will overflow
-}
-
-pub fn main() {
-      let n = 1u8 << 7;
-      let n = 1u8 << 8;   //~ WARN: arithmetic operation will overflow
-      let n = 1u16 << 15;
-      let n = 1u16 << 16; //~ WARN: arithmetic operation will overflow
-      let n = 1u32 << 31;
-      let n = 1u32 << 32; //~ WARN: arithmetic operation will overflow
-      let n = 1u64 << 63;
-      let n = 1u64 << 64; //~ WARN: arithmetic operation will overflow
-      let n = 1i8 << 7;
-      let n = 1i8 << 8;   //~ WARN: arithmetic operation will overflow
-      let n = 1i16 << 15;
-      let n = 1i16 << 16; //~ WARN: arithmetic operation will overflow
-      let n = 1i32 << 31;
-      let n = 1i32 << 32; //~ WARN: arithmetic operation will overflow
-      let n = 1i64 << 63;
-      let n = 1i64 << 64; //~ WARN: arithmetic operation will overflow
-
-      let n = 1u8 >> 7;
-      let n = 1u8 >> 8;   //~ WARN: arithmetic operation will overflow
-      let n = 1u16 >> 15;
-      let n = 1u16 >> 16; //~ WARN: arithmetic operation will overflow
-      let n = 1u32 >> 31;
-      let n = 1u32 >> 32; //~ WARN: arithmetic operation will overflow
-      let n = 1u64 >> 63;
-      let n = 1u64 >> 64; //~ WARN: arithmetic operation will overflow
-      let n = 1i8 >> 7;
-      let n = 1i8 >> 8;   //~ WARN: arithmetic operation will overflow
-      let n = 1i16 >> 15;
-      let n = 1i16 >> 16; //~ WARN: arithmetic operation will overflow
-      let n = 1i32 >> 31;
-      let n = 1i32 >> 32; //~ WARN: arithmetic operation will overflow
-      let n = 1i64 >> 63;
-      let n = 1i64 >> 64; //~ WARN: arithmetic operation will overflow
-
-      let n = 1u8;
-      let n = n << 7;
-      let n = n << 8; //~ WARN: arithmetic operation will overflow
-
-      let n = 1u8 << -8; //~ WARN: arithmetic operation will overflow
-
-      let n = 1i8<<(1isize+-1);
-
-      let n = 1u8 << (4+3);
-      let n = 1u8 << (4+4); //~ WARN: arithmetic operation will overflow
-      let n = 1i64 >> [63][0];
-      let n = 1i64 >> [64][0]; //~ WARN: arithmetic operation will overflow
-
-      #[cfg(target_pointer_width = "32")]
-      const BITS: usize = 32;
-      #[cfg(target_pointer_width = "64")]
-      const BITS: usize = 64;
-      let n = 1_isize << BITS; //~ WARN: arithmetic operation will overflow
-      let n = 1_usize << BITS; //~ WARN: arithmetic operation will overflow
-}
diff --git a/tests/ui/lint/lint-overflowing-ops.noopt.stderr b/tests/ui/lint/lint-overflowing-ops.noopt.stderr
new file mode 100644
index 00000000000..93fc19ce79e
--- /dev/null
+++ b/tests/ui/lint/lint-overflowing-ops.noopt.stderr
@@ -0,0 +1,1030 @@
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:26:14
+   |
+LL |     let _n = 1u8 << 8;
+   |              ^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+   |
+note: the lint level is defined here
+  --> $DIR/lint-overflowing-ops.rs:17:9
+   |
+LL | #![deny(arithmetic_overflow)]
+   |         ^^^^^^^^^^^^^^^^^^^
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:212:15
+   |
+LL |     let _n = &(usize::MAX * 5);
+   |               ^^^^^^^^^^^^^^^^ attempt to compute `usize::MAX * 5_usize`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:209:15
+   |
+LL |     let _n = &(isize::MAX * 5);
+   |               ^^^^^^^^^^^^^^^^ attempt to compute `isize::MAX * 5_isize`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:206:15
+   |
+LL |     let _n = &(i128::MAX * 5);
+   |               ^^^^^^^^^^^^^^^ attempt to compute `i128::MAX * 5_i128`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:203:15
+   |
+LL |     let _n = &(i64::MAX * 5);
+   |               ^^^^^^^^^^^^^^ attempt to compute `i64::MAX * 5_i64`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:200:15
+   |
+LL |     let _n = &(i32::MAX * 5);
+   |               ^^^^^^^^^^^^^^ attempt to compute `i32::MAX * 5_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:197:15
+   |
+LL |     let _n = &(i16::MAX * 5);
+   |               ^^^^^^^^^^^^^^ attempt to compute `i16::MAX * 5_i16`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:194:15
+   |
+LL |     let _n = &(i8::MAX * i8::MAX);
+   |               ^^^^^^^^^^^^^^^^^^^ attempt to compute `i8::MAX * i8::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:191:15
+   |
+LL |     let _n = &(u128::MAX * 5);
+   |               ^^^^^^^^^^^^^^^ attempt to compute `u128::MAX * 5_u128`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:188:15
+   |
+LL |     let _n = &(u64::MAX * 5);
+   |               ^^^^^^^^^^^^^^ attempt to compute `u64::MAX * 5_u64`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:185:15
+   |
+LL |     let _n = &(u32::MAX * 5);
+   |               ^^^^^^^^^^^^^^ attempt to compute `u32::MAX * 5_u32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:182:15
+   |
+LL |     let _n = &(u16::MAX * 5);
+   |               ^^^^^^^^^^^^^^ attempt to compute `u16::MAX * 5_u16`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:179:15
+   |
+LL |     let _n = &(u8::MAX * 5);
+   |               ^^^^^^^^^^^^^ attempt to compute `u8::MAX * 5_u8`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:174:15
+   |
+LL |     let _n = &(1usize - 5);
+   |               ^^^^^^^^^^^^ attempt to compute `1_usize - 5_usize`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:171:15
+   |
+LL |     let _n = &(-5isize - isize::MAX);
+   |               ^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `-5_isize - isize::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:168:15
+   |
+LL |     let _n = &(-5i128 - i128::MAX);
+   |               ^^^^^^^^^^^^^^^^^^^^ attempt to compute `-5_i128 - i128::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:165:15
+   |
+LL |     let _n = &(-5i64 - i64::MAX);
+   |               ^^^^^^^^^^^^^^^^^^ attempt to compute `-5_i64 - i64::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:162:15
+   |
+LL |     let _n = &(-5i32 - i32::MAX);
+   |               ^^^^^^^^^^^^^^^^^^ attempt to compute `-5_i32 - i32::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:159:15
+   |
+LL |     let _n = &(-5i16 - i16::MAX);
+   |               ^^^^^^^^^^^^^^^^^^ attempt to compute `-5_i16 - i16::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:156:15
+   |
+LL |     let _n = &(-5i8 - i8::MAX);
+   |               ^^^^^^^^^^^^^^^^ attempt to compute `-5_i8 - i8::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:153:15
+   |
+LL |     let _n = &(1u128 - 5);
+   |               ^^^^^^^^^^^ attempt to compute `1_u128 - 5_u128`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:150:15
+   |
+LL |     let _n = &(1u64 - 5);
+   |               ^^^^^^^^^^ attempt to compute `1_u64 - 5_u64`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:147:15
+   |
+LL |     let _n = &(1u32 - 5);
+   |               ^^^^^^^^^^ attempt to compute `1_u32 - 5_u32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:144:15
+   |
+LL |     let _n = &(1u16 - 5);
+   |               ^^^^^^^^^^ attempt to compute `1_u16 - 5_u16`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:141:15
+   |
+LL |     let _n = &(1u8 - 5);
+   |               ^^^^^^^^^ attempt to compute `1_u8 - 5_u8`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:136:15
+   |
+LL |     let _n = &(1usize + usize::MAX);
+   |               ^^^^^^^^^^^^^^^^^^^^^ attempt to compute `1_usize + usize::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:133:15
+   |
+LL |     let _n = &(1isize + isize::MAX);
+   |               ^^^^^^^^^^^^^^^^^^^^^ attempt to compute `1_isize + isize::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:130:15
+   |
+LL |     let _n = &(1i128 + i128::MAX);
+   |               ^^^^^^^^^^^^^^^^^^^ attempt to compute `1_i128 + i128::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:127:15
+   |
+LL |     let _n = &(1i64 + i64::MAX);
+   |               ^^^^^^^^^^^^^^^^^ attempt to compute `1_i64 + i64::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:124:15
+   |
+LL |     let _n = &(1i32 + i32::MAX);
+   |               ^^^^^^^^^^^^^^^^^ attempt to compute `1_i32 + i32::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:121:15
+   |
+LL |     let _n = &(1i16 + i16::MAX);
+   |               ^^^^^^^^^^^^^^^^^ attempt to compute `1_i16 + i16::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:118:15
+   |
+LL |     let _n = &(1i8 + i8::MAX);
+   |               ^^^^^^^^^^^^^^^ attempt to compute `1_i8 + i8::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:115:15
+   |
+LL |     let _n = &(1u128 + u128::MAX);
+   |               ^^^^^^^^^^^^^^^^^^^ attempt to compute `1_u128 + u128::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:112:15
+   |
+LL |     let _n = &(1u64 + u64::MAX);
+   |               ^^^^^^^^^^^^^^^^^ attempt to compute `1_u64 + u64::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:109:15
+   |
+LL |     let _n = &(1u32 + u32::MAX);
+   |               ^^^^^^^^^^^^^^^^^ attempt to compute `1_u32 + u32::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:106:15
+   |
+LL |     let _n = &(1u16 + u16::MAX);
+   |               ^^^^^^^^^^^^^^^^^ attempt to compute `1_u16 + u16::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:103:15
+   |
+LL |     let _n = &(1u8 + u8::MAX);
+   |               ^^^^^^^^^^^^^^^ attempt to compute `1_u8 + u8::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:98:15
+   |
+LL |     let _n = &(1_usize >> BITS);
+   |               ^^^^^^^^^^^^^^^^^ attempt to shift right by `%BITS%`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:95:15
+   |
+LL |     let _n = &(1_isize >> BITS);
+   |               ^^^^^^^^^^^^^^^^^ attempt to shift right by `%BITS%`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:92:15
+   |
+LL |     let _n = &(1i128 >> 128);
+   |               ^^^^^^^^^^^^^^ attempt to shift right by `128_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:89:15
+   |
+LL |     let _n = &(1i64 >> 64);
+   |               ^^^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:86:15
+   |
+LL |     let _n = &(1i32 >> 32);
+   |               ^^^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:83:15
+   |
+LL |     let _n = &(1i16 >> 16);
+   |               ^^^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:80:15
+   |
+LL |     let _n = &(1i8 >> 8);
+   |               ^^^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:77:15
+   |
+LL |     let _n = &(1u128 >> 128);
+   |               ^^^^^^^^^^^^^^ attempt to shift right by `128_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:74:15
+   |
+LL |     let _n = &(1u64 >> 64);
+   |               ^^^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:71:15
+   |
+LL |     let _n = &(1u32 >> 32);
+   |               ^^^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:68:15
+   |
+LL |     let _n = &(1u16 >> 16);
+   |               ^^^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:65:15
+   |
+LL |     let _n = &(1u8 >> 8);
+   |               ^^^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:60:15
+   |
+LL |     let _n = &(1_usize << BITS);
+   |               ^^^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:57:15
+   |
+LL |     let _n = &(1_isize << BITS);
+   |               ^^^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:54:15
+   |
+LL |     let _n = &(1i128 << 128);
+   |               ^^^^^^^^^^^^^^ attempt to shift left by `128_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:51:15
+   |
+LL |     let _n = &(1i64 << 64);
+   |               ^^^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:48:15
+   |
+LL |     let _n = &(1i32 << 32);
+   |               ^^^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:45:15
+   |
+LL |     let _n = &(1i16 << 16);
+   |               ^^^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:42:15
+   |
+LL |     let _n = &(1i8 << 8);
+   |               ^^^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:39:15
+   |
+LL |     let _n = &(1u128 << 128);
+   |               ^^^^^^^^^^^^^^ attempt to shift left by `128_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:36:15
+   |
+LL |     let _n = &(1u64 << 64);
+   |               ^^^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:33:15
+   |
+LL |     let _n = &(1u32 << 32);
+   |               ^^^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:30:15
+   |
+LL |     let _n = &(1u16 << 16);
+   |               ^^^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:27:15
+   |
+LL |     let _n = &(1u8 << 8);
+   |               ^^^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:29:14
+   |
+LL |     let _n = 1u16 << 16;
+   |              ^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:32:14
+   |
+LL |     let _n = 1u32 << 32;
+   |              ^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:35:14
+   |
+LL |     let _n = 1u64 << 64;
+   |              ^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:38:14
+   |
+LL |     let _n = 1u128 << 128;
+   |              ^^^^^^^^^^^^ attempt to shift left by `128_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:41:14
+   |
+LL |     let _n = 1i8 << 8;
+   |              ^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:44:14
+   |
+LL |     let _n = 1i16 << 16;
+   |              ^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:47:14
+   |
+LL |     let _n = 1i32 << 32;
+   |              ^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:50:14
+   |
+LL |     let _n = 1i64 << 64;
+   |              ^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:53:14
+   |
+LL |     let _n = 1i128 << 128;
+   |              ^^^^^^^^^^^^ attempt to shift left by `128_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:56:14
+   |
+LL |     let _n = 1_isize << BITS;
+   |              ^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:59:14
+   |
+LL |     let _n = 1_usize << BITS;
+   |              ^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:64:14
+   |
+LL |     let _n = 1u8 >> 8;
+   |              ^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:67:14
+   |
+LL |     let _n = 1u16 >> 16;
+   |              ^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:70:14
+   |
+LL |     let _n = 1u32 >> 32;
+   |              ^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:73:14
+   |
+LL |     let _n = 1u64 >> 64;
+   |              ^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:76:14
+   |
+LL |     let _n = 1u128 >> 128;
+   |              ^^^^^^^^^^^^ attempt to shift right by `128_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:79:14
+   |
+LL |     let _n = 1i8 >> 8;
+   |              ^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:82:14
+   |
+LL |     let _n = 1i16 >> 16;
+   |              ^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:85:14
+   |
+LL |     let _n = 1i32 >> 32;
+   |              ^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:88:14
+   |
+LL |     let _n = 1i64 >> 64;
+   |              ^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:91:14
+   |
+LL |     let _n = 1i128 >> 128;
+   |              ^^^^^^^^^^^^ attempt to shift right by `128_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:94:14
+   |
+LL |     let _n = 1_isize >> BITS;
+   |              ^^^^^^^^^^^^^^^ attempt to shift right by `%BITS%`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:97:14
+   |
+LL |     let _n = 1_usize >> BITS;
+   |              ^^^^^^^^^^^^^^^ attempt to shift right by `%BITS%`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:102:14
+   |
+LL |     let _n = 1u8 + u8::MAX;
+   |              ^^^^^^^^^^^^^ attempt to compute `1_u8 + u8::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:105:14
+   |
+LL |     let _n = 1u16 + u16::MAX;
+   |              ^^^^^^^^^^^^^^^ attempt to compute `1_u16 + u16::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:108:14
+   |
+LL |     let _n = 1u32 + u32::MAX;
+   |              ^^^^^^^^^^^^^^^ attempt to compute `1_u32 + u32::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:111:14
+   |
+LL |     let _n = 1u64 + u64::MAX;
+   |              ^^^^^^^^^^^^^^^ attempt to compute `1_u64 + u64::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:114:14
+   |
+LL |     let _n = 1u128 + u128::MAX;
+   |              ^^^^^^^^^^^^^^^^^ attempt to compute `1_u128 + u128::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:117:14
+   |
+LL |     let _n = 1i8 + i8::MAX;
+   |              ^^^^^^^^^^^^^ attempt to compute `1_i8 + i8::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:120:14
+   |
+LL |     let _n = 1i16 + i16::MAX;
+   |              ^^^^^^^^^^^^^^^ attempt to compute `1_i16 + i16::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:123:14
+   |
+LL |     let _n = 1i32 + i32::MAX;
+   |              ^^^^^^^^^^^^^^^ attempt to compute `1_i32 + i32::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:126:14
+   |
+LL |     let _n = 1i64 + i64::MAX;
+   |              ^^^^^^^^^^^^^^^ attempt to compute `1_i64 + i64::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:129:14
+   |
+LL |     let _n = 1i128 + i128::MAX;
+   |              ^^^^^^^^^^^^^^^^^ attempt to compute `1_i128 + i128::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:132:14
+   |
+LL |     let _n = 1isize + isize::MAX;
+   |              ^^^^^^^^^^^^^^^^^^^ attempt to compute `1_isize + isize::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:135:14
+   |
+LL |     let _n = 1usize + usize::MAX;
+   |              ^^^^^^^^^^^^^^^^^^^ attempt to compute `1_usize + usize::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:140:14
+   |
+LL |     let _n = 1u8 - 5;
+   |              ^^^^^^^ attempt to compute `1_u8 - 5_u8`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:143:14
+   |
+LL |     let _n = 1u16 - 5;
+   |              ^^^^^^^^ attempt to compute `1_u16 - 5_u16`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:146:14
+   |
+LL |     let _n = 1u32 - 5;
+   |              ^^^^^^^^ attempt to compute `1_u32 - 5_u32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:149:14
+   |
+LL |     let _n = 1u64 - 5 ;
+   |              ^^^^^^^^ attempt to compute `1_u64 - 5_u64`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:152:14
+   |
+LL |     let _n = 1u128 - 5 ;
+   |              ^^^^^^^^^ attempt to compute `1_u128 - 5_u128`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:155:14
+   |
+LL |     let _n = -5i8 - i8::MAX;
+   |              ^^^^^^^^^^^^^^ attempt to compute `-5_i8 - i8::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:158:14
+   |
+LL |     let _n = -5i16 - i16::MAX;
+   |              ^^^^^^^^^^^^^^^^ attempt to compute `-5_i16 - i16::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:161:14
+   |
+LL |     let _n = -5i32 - i32::MAX;
+   |              ^^^^^^^^^^^^^^^^ attempt to compute `-5_i32 - i32::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:164:14
+   |
+LL |     let _n = -5i64 - i64::MAX;
+   |              ^^^^^^^^^^^^^^^^ attempt to compute `-5_i64 - i64::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:167:14
+   |
+LL |     let _n = -5i128 - i128::MAX;
+   |              ^^^^^^^^^^^^^^^^^^ attempt to compute `-5_i128 - i128::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:170:14
+   |
+LL |     let _n = -5isize - isize::MAX;
+   |              ^^^^^^^^^^^^^^^^^^^^ attempt to compute `-5_isize - isize::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:173:14
+   |
+LL |     let _n = 1usize - 5;
+   |              ^^^^^^^^^^ attempt to compute `1_usize - 5_usize`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:178:14
+   |
+LL |     let _n = u8::MAX * 5;
+   |              ^^^^^^^^^^^ attempt to compute `u8::MAX * 5_u8`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:181:14
+   |
+LL |     let _n = u16::MAX * 5;
+   |              ^^^^^^^^^^^^ attempt to compute `u16::MAX * 5_u16`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:184:14
+   |
+LL |     let _n = u32::MAX * 5;
+   |              ^^^^^^^^^^^^ attempt to compute `u32::MAX * 5_u32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:187:14
+   |
+LL |     let _n = u64::MAX * 5;
+   |              ^^^^^^^^^^^^ attempt to compute `u64::MAX * 5_u64`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:190:14
+   |
+LL |     let _n = u128::MAX * 5;
+   |              ^^^^^^^^^^^^^ attempt to compute `u128::MAX * 5_u128`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:193:14
+   |
+LL |     let _n = i8::MAX * i8::MAX;
+   |              ^^^^^^^^^^^^^^^^^ attempt to compute `i8::MAX * i8::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:196:14
+   |
+LL |     let _n = i16::MAX * 5;
+   |              ^^^^^^^^^^^^ attempt to compute `i16::MAX * 5_i16`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:199:14
+   |
+LL |     let _n = i32::MAX * 5;
+   |              ^^^^^^^^^^^^ attempt to compute `i32::MAX * 5_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:202:14
+   |
+LL |     let _n = i64::MAX * 5;
+   |              ^^^^^^^^^^^^ attempt to compute `i64::MAX * 5_i64`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:205:14
+   |
+LL |     let _n = i128::MAX * 5;
+   |              ^^^^^^^^^^^^^ attempt to compute `i128::MAX * 5_i128`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:208:14
+   |
+LL |     let _n = isize::MAX * 5;
+   |              ^^^^^^^^^^^^^^ attempt to compute `isize::MAX * 5_isize`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:211:14
+   |
+LL |     let _n = usize::MAX * 5;
+   |              ^^^^^^^^^^^^^^ attempt to compute `usize::MAX * 5_usize`, which would overflow
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:216:14
+   |
+LL |     let _n = 1u8 / 0;
+   |              ^^^^^^^ attempt to divide `1_u8` by zero
+   |
+   = note: `#[deny(unconditional_panic)]` on by default
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:217:15
+   |
+LL |     let _n = &(1u8 / 0);
+   |               ^^^^^^^^^ attempt to divide `1_u8` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:219:14
+   |
+LL |     let _n = 1u16 / 0;
+   |              ^^^^^^^^ attempt to divide `1_u16` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:220:15
+   |
+LL |     let _n = &(1u16 / 0);
+   |               ^^^^^^^^^^ attempt to divide `1_u16` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:222:14
+   |
+LL |     let _n = 1u32 / 0;
+   |              ^^^^^^^^ attempt to divide `1_u32` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:223:15
+   |
+LL |     let _n = &(1u32 / 0);
+   |               ^^^^^^^^^^ attempt to divide `1_u32` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:225:14
+   |
+LL |     let _n = 1u64 / 0;
+   |              ^^^^^^^^ attempt to divide `1_u64` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:226:15
+   |
+LL |     let _n = &(1u64 / 0);
+   |               ^^^^^^^^^^ attempt to divide `1_u64` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:228:14
+   |
+LL |     let _n = 1u128 / 0;
+   |              ^^^^^^^^^ attempt to divide `1_u128` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:229:15
+   |
+LL |     let _n = &(1u128 / 0);
+   |               ^^^^^^^^^^^ attempt to divide `1_u128` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:231:14
+   |
+LL |     let _n = 1i8 / 0;
+   |              ^^^^^^^ attempt to divide `1_i8` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:232:15
+   |
+LL |     let _n = &(1i8 / 0);
+   |               ^^^^^^^^^ attempt to divide `1_i8` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:234:14
+   |
+LL |     let _n = 1i16 / 0;
+   |              ^^^^^^^^ attempt to divide `1_i16` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:235:15
+   |
+LL |     let _n = &(1i16 / 0);
+   |               ^^^^^^^^^^ attempt to divide `1_i16` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:237:14
+   |
+LL |     let _n = 1i32 / 0;
+   |              ^^^^^^^^ attempt to divide `1_i32` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:238:15
+   |
+LL |     let _n = &(1i32 / 0);
+   |               ^^^^^^^^^^ attempt to divide `1_i32` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:240:14
+   |
+LL |     let _n = 1i64 / 0;
+   |              ^^^^^^^^ attempt to divide `1_i64` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:241:15
+   |
+LL |     let _n = &(1i64 / 0);
+   |               ^^^^^^^^^^ attempt to divide `1_i64` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:243:14
+   |
+LL |     let _n = 1i128 / 0;
+   |              ^^^^^^^^^ attempt to divide `1_i128` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:244:15
+   |
+LL |     let _n = &(1i128 / 0);
+   |               ^^^^^^^^^^^ attempt to divide `1_i128` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:246:14
+   |
+LL |     let _n = 1isize / 0;
+   |              ^^^^^^^^^^ attempt to divide `1_isize` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:247:15
+   |
+LL |     let _n = &(1isize / 0);
+   |               ^^^^^^^^^^^^ attempt to divide `1_isize` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:249:14
+   |
+LL |     let _n = 1usize / 0;
+   |              ^^^^^^^^^^ attempt to divide `1_usize` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:250:15
+   |
+LL |     let _n = &(1usize / 0);
+   |               ^^^^^^^^^^^^ attempt to divide `1_usize` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:254:14
+   |
+LL |     let _n = 1u8 % 0;
+   |              ^^^^^^^ attempt to calculate the remainder of `1_u8` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:255:15
+   |
+LL |     let _n = &(1u8 % 0);
+   |               ^^^^^^^^^ attempt to calculate the remainder of `1_u8` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:257:14
+   |
+LL |     let _n = 1u16 % 0;
+   |              ^^^^^^^^ attempt to calculate the remainder of `1_u16` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:258:15
+   |
+LL |     let _n = &(1u16 % 0);
+   |               ^^^^^^^^^^ attempt to calculate the remainder of `1_u16` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:260:14
+   |
+LL |     let _n = 1u32 % 0;
+   |              ^^^^^^^^ attempt to calculate the remainder of `1_u32` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:261:15
+   |
+LL |     let _n = &(1u32 % 0);
+   |               ^^^^^^^^^^ attempt to calculate the remainder of `1_u32` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:263:14
+   |
+LL |     let _n = 1u64 % 0;
+   |              ^^^^^^^^ attempt to calculate the remainder of `1_u64` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:264:15
+   |
+LL |     let _n = &(1u64 % 0);
+   |               ^^^^^^^^^^ attempt to calculate the remainder of `1_u64` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:266:14
+   |
+LL |     let _n = 1u128 % 0;
+   |              ^^^^^^^^^ attempt to calculate the remainder of `1_u128` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:267:15
+   |
+LL |     let _n = &(1u128 % 0);
+   |               ^^^^^^^^^^^ attempt to calculate the remainder of `1_u128` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:269:14
+   |
+LL |     let _n = 1i8 % 0;
+   |              ^^^^^^^ attempt to calculate the remainder of `1_i8` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:270:15
+   |
+LL |     let _n = &(1i8 % 0);
+   |               ^^^^^^^^^ attempt to calculate the remainder of `1_i8` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:272:14
+   |
+LL |     let _n = 1i16 % 0;
+   |              ^^^^^^^^ attempt to calculate the remainder of `1_i16` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:273:15
+   |
+LL |     let _n = &(1i16 % 0);
+   |               ^^^^^^^^^^ attempt to calculate the remainder of `1_i16` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:275:14
+   |
+LL |     let _n = 1i32 % 0;
+   |              ^^^^^^^^ attempt to calculate the remainder of `1_i32` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:276:15
+   |
+LL |     let _n = &(1i32 % 0);
+   |               ^^^^^^^^^^ attempt to calculate the remainder of `1_i32` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:278:14
+   |
+LL |     let _n = 1i64 % 0;
+   |              ^^^^^^^^ attempt to calculate the remainder of `1_i64` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:279:15
+   |
+LL |     let _n = &(1i64 % 0);
+   |               ^^^^^^^^^^ attempt to calculate the remainder of `1_i64` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:281:14
+   |
+LL |     let _n = 1i128 % 0;
+   |              ^^^^^^^^^ attempt to calculate the remainder of `1_i128` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:282:15
+   |
+LL |     let _n = &(1i128 % 0);
+   |               ^^^^^^^^^^^ attempt to calculate the remainder of `1_i128` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:284:14
+   |
+LL |     let _n = 1isize % 0;
+   |              ^^^^^^^^^^ attempt to calculate the remainder of `1_isize` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:285:15
+   |
+LL |     let _n = &(1isize % 0);
+   |               ^^^^^^^^^^^^ attempt to calculate the remainder of `1_isize` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:287:14
+   |
+LL |     let _n = 1usize % 0;
+   |              ^^^^^^^^^^ attempt to calculate the remainder of `1_usize` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:288:15
+   |
+LL |     let _n = &(1usize % 0);
+   |               ^^^^^^^^^^^^ attempt to calculate the remainder of `1_usize` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:292:14
+   |
+LL |     let _n = [1, 2, 3][4];
+   |              ^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 4
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:293:15
+   |
+LL |     let _n = &([1, 2, 3][4]);
+   |               ^^^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 4
+
+error: aborting due to 170 previous errors
+
diff --git a/tests/ui/lint/lint-overflowing-ops.opt.stderr b/tests/ui/lint/lint-overflowing-ops.opt.stderr
new file mode 100644
index 00000000000..93fc19ce79e
--- /dev/null
+++ b/tests/ui/lint/lint-overflowing-ops.opt.stderr
@@ -0,0 +1,1030 @@
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:26:14
+   |
+LL |     let _n = 1u8 << 8;
+   |              ^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+   |
+note: the lint level is defined here
+  --> $DIR/lint-overflowing-ops.rs:17:9
+   |
+LL | #![deny(arithmetic_overflow)]
+   |         ^^^^^^^^^^^^^^^^^^^
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:212:15
+   |
+LL |     let _n = &(usize::MAX * 5);
+   |               ^^^^^^^^^^^^^^^^ attempt to compute `usize::MAX * 5_usize`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:209:15
+   |
+LL |     let _n = &(isize::MAX * 5);
+   |               ^^^^^^^^^^^^^^^^ attempt to compute `isize::MAX * 5_isize`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:206:15
+   |
+LL |     let _n = &(i128::MAX * 5);
+   |               ^^^^^^^^^^^^^^^ attempt to compute `i128::MAX * 5_i128`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:203:15
+   |
+LL |     let _n = &(i64::MAX * 5);
+   |               ^^^^^^^^^^^^^^ attempt to compute `i64::MAX * 5_i64`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:200:15
+   |
+LL |     let _n = &(i32::MAX * 5);
+   |               ^^^^^^^^^^^^^^ attempt to compute `i32::MAX * 5_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:197:15
+   |
+LL |     let _n = &(i16::MAX * 5);
+   |               ^^^^^^^^^^^^^^ attempt to compute `i16::MAX * 5_i16`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:194:15
+   |
+LL |     let _n = &(i8::MAX * i8::MAX);
+   |               ^^^^^^^^^^^^^^^^^^^ attempt to compute `i8::MAX * i8::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:191:15
+   |
+LL |     let _n = &(u128::MAX * 5);
+   |               ^^^^^^^^^^^^^^^ attempt to compute `u128::MAX * 5_u128`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:188:15
+   |
+LL |     let _n = &(u64::MAX * 5);
+   |               ^^^^^^^^^^^^^^ attempt to compute `u64::MAX * 5_u64`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:185:15
+   |
+LL |     let _n = &(u32::MAX * 5);
+   |               ^^^^^^^^^^^^^^ attempt to compute `u32::MAX * 5_u32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:182:15
+   |
+LL |     let _n = &(u16::MAX * 5);
+   |               ^^^^^^^^^^^^^^ attempt to compute `u16::MAX * 5_u16`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:179:15
+   |
+LL |     let _n = &(u8::MAX * 5);
+   |               ^^^^^^^^^^^^^ attempt to compute `u8::MAX * 5_u8`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:174:15
+   |
+LL |     let _n = &(1usize - 5);
+   |               ^^^^^^^^^^^^ attempt to compute `1_usize - 5_usize`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:171:15
+   |
+LL |     let _n = &(-5isize - isize::MAX);
+   |               ^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `-5_isize - isize::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:168:15
+   |
+LL |     let _n = &(-5i128 - i128::MAX);
+   |               ^^^^^^^^^^^^^^^^^^^^ attempt to compute `-5_i128 - i128::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:165:15
+   |
+LL |     let _n = &(-5i64 - i64::MAX);
+   |               ^^^^^^^^^^^^^^^^^^ attempt to compute `-5_i64 - i64::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:162:15
+   |
+LL |     let _n = &(-5i32 - i32::MAX);
+   |               ^^^^^^^^^^^^^^^^^^ attempt to compute `-5_i32 - i32::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:159:15
+   |
+LL |     let _n = &(-5i16 - i16::MAX);
+   |               ^^^^^^^^^^^^^^^^^^ attempt to compute `-5_i16 - i16::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:156:15
+   |
+LL |     let _n = &(-5i8 - i8::MAX);
+   |               ^^^^^^^^^^^^^^^^ attempt to compute `-5_i8 - i8::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:153:15
+   |
+LL |     let _n = &(1u128 - 5);
+   |               ^^^^^^^^^^^ attempt to compute `1_u128 - 5_u128`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:150:15
+   |
+LL |     let _n = &(1u64 - 5);
+   |               ^^^^^^^^^^ attempt to compute `1_u64 - 5_u64`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:147:15
+   |
+LL |     let _n = &(1u32 - 5);
+   |               ^^^^^^^^^^ attempt to compute `1_u32 - 5_u32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:144:15
+   |
+LL |     let _n = &(1u16 - 5);
+   |               ^^^^^^^^^^ attempt to compute `1_u16 - 5_u16`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:141:15
+   |
+LL |     let _n = &(1u8 - 5);
+   |               ^^^^^^^^^ attempt to compute `1_u8 - 5_u8`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:136:15
+   |
+LL |     let _n = &(1usize + usize::MAX);
+   |               ^^^^^^^^^^^^^^^^^^^^^ attempt to compute `1_usize + usize::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:133:15
+   |
+LL |     let _n = &(1isize + isize::MAX);
+   |               ^^^^^^^^^^^^^^^^^^^^^ attempt to compute `1_isize + isize::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:130:15
+   |
+LL |     let _n = &(1i128 + i128::MAX);
+   |               ^^^^^^^^^^^^^^^^^^^ attempt to compute `1_i128 + i128::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:127:15
+   |
+LL |     let _n = &(1i64 + i64::MAX);
+   |               ^^^^^^^^^^^^^^^^^ attempt to compute `1_i64 + i64::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:124:15
+   |
+LL |     let _n = &(1i32 + i32::MAX);
+   |               ^^^^^^^^^^^^^^^^^ attempt to compute `1_i32 + i32::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:121:15
+   |
+LL |     let _n = &(1i16 + i16::MAX);
+   |               ^^^^^^^^^^^^^^^^^ attempt to compute `1_i16 + i16::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:118:15
+   |
+LL |     let _n = &(1i8 + i8::MAX);
+   |               ^^^^^^^^^^^^^^^ attempt to compute `1_i8 + i8::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:115:15
+   |
+LL |     let _n = &(1u128 + u128::MAX);
+   |               ^^^^^^^^^^^^^^^^^^^ attempt to compute `1_u128 + u128::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:112:15
+   |
+LL |     let _n = &(1u64 + u64::MAX);
+   |               ^^^^^^^^^^^^^^^^^ attempt to compute `1_u64 + u64::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:109:15
+   |
+LL |     let _n = &(1u32 + u32::MAX);
+   |               ^^^^^^^^^^^^^^^^^ attempt to compute `1_u32 + u32::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:106:15
+   |
+LL |     let _n = &(1u16 + u16::MAX);
+   |               ^^^^^^^^^^^^^^^^^ attempt to compute `1_u16 + u16::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:103:15
+   |
+LL |     let _n = &(1u8 + u8::MAX);
+   |               ^^^^^^^^^^^^^^^ attempt to compute `1_u8 + u8::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:98:15
+   |
+LL |     let _n = &(1_usize >> BITS);
+   |               ^^^^^^^^^^^^^^^^^ attempt to shift right by `%BITS%`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:95:15
+   |
+LL |     let _n = &(1_isize >> BITS);
+   |               ^^^^^^^^^^^^^^^^^ attempt to shift right by `%BITS%`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:92:15
+   |
+LL |     let _n = &(1i128 >> 128);
+   |               ^^^^^^^^^^^^^^ attempt to shift right by `128_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:89:15
+   |
+LL |     let _n = &(1i64 >> 64);
+   |               ^^^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:86:15
+   |
+LL |     let _n = &(1i32 >> 32);
+   |               ^^^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:83:15
+   |
+LL |     let _n = &(1i16 >> 16);
+   |               ^^^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:80:15
+   |
+LL |     let _n = &(1i8 >> 8);
+   |               ^^^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:77:15
+   |
+LL |     let _n = &(1u128 >> 128);
+   |               ^^^^^^^^^^^^^^ attempt to shift right by `128_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:74:15
+   |
+LL |     let _n = &(1u64 >> 64);
+   |               ^^^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:71:15
+   |
+LL |     let _n = &(1u32 >> 32);
+   |               ^^^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:68:15
+   |
+LL |     let _n = &(1u16 >> 16);
+   |               ^^^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:65:15
+   |
+LL |     let _n = &(1u8 >> 8);
+   |               ^^^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:60:15
+   |
+LL |     let _n = &(1_usize << BITS);
+   |               ^^^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:57:15
+   |
+LL |     let _n = &(1_isize << BITS);
+   |               ^^^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:54:15
+   |
+LL |     let _n = &(1i128 << 128);
+   |               ^^^^^^^^^^^^^^ attempt to shift left by `128_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:51:15
+   |
+LL |     let _n = &(1i64 << 64);
+   |               ^^^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:48:15
+   |
+LL |     let _n = &(1i32 << 32);
+   |               ^^^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:45:15
+   |
+LL |     let _n = &(1i16 << 16);
+   |               ^^^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:42:15
+   |
+LL |     let _n = &(1i8 << 8);
+   |               ^^^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:39:15
+   |
+LL |     let _n = &(1u128 << 128);
+   |               ^^^^^^^^^^^^^^ attempt to shift left by `128_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:36:15
+   |
+LL |     let _n = &(1u64 << 64);
+   |               ^^^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:33:15
+   |
+LL |     let _n = &(1u32 << 32);
+   |               ^^^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:30:15
+   |
+LL |     let _n = &(1u16 << 16);
+   |               ^^^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:27:15
+   |
+LL |     let _n = &(1u8 << 8);
+   |               ^^^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:29:14
+   |
+LL |     let _n = 1u16 << 16;
+   |              ^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:32:14
+   |
+LL |     let _n = 1u32 << 32;
+   |              ^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:35:14
+   |
+LL |     let _n = 1u64 << 64;
+   |              ^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:38:14
+   |
+LL |     let _n = 1u128 << 128;
+   |              ^^^^^^^^^^^^ attempt to shift left by `128_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:41:14
+   |
+LL |     let _n = 1i8 << 8;
+   |              ^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:44:14
+   |
+LL |     let _n = 1i16 << 16;
+   |              ^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:47:14
+   |
+LL |     let _n = 1i32 << 32;
+   |              ^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:50:14
+   |
+LL |     let _n = 1i64 << 64;
+   |              ^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:53:14
+   |
+LL |     let _n = 1i128 << 128;
+   |              ^^^^^^^^^^^^ attempt to shift left by `128_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:56:14
+   |
+LL |     let _n = 1_isize << BITS;
+   |              ^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:59:14
+   |
+LL |     let _n = 1_usize << BITS;
+   |              ^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:64:14
+   |
+LL |     let _n = 1u8 >> 8;
+   |              ^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:67:14
+   |
+LL |     let _n = 1u16 >> 16;
+   |              ^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:70:14
+   |
+LL |     let _n = 1u32 >> 32;
+   |              ^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:73:14
+   |
+LL |     let _n = 1u64 >> 64;
+   |              ^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:76:14
+   |
+LL |     let _n = 1u128 >> 128;
+   |              ^^^^^^^^^^^^ attempt to shift right by `128_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:79:14
+   |
+LL |     let _n = 1i8 >> 8;
+   |              ^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:82:14
+   |
+LL |     let _n = 1i16 >> 16;
+   |              ^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:85:14
+   |
+LL |     let _n = 1i32 >> 32;
+   |              ^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:88:14
+   |
+LL |     let _n = 1i64 >> 64;
+   |              ^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:91:14
+   |
+LL |     let _n = 1i128 >> 128;
+   |              ^^^^^^^^^^^^ attempt to shift right by `128_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:94:14
+   |
+LL |     let _n = 1_isize >> BITS;
+   |              ^^^^^^^^^^^^^^^ attempt to shift right by `%BITS%`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:97:14
+   |
+LL |     let _n = 1_usize >> BITS;
+   |              ^^^^^^^^^^^^^^^ attempt to shift right by `%BITS%`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:102:14
+   |
+LL |     let _n = 1u8 + u8::MAX;
+   |              ^^^^^^^^^^^^^ attempt to compute `1_u8 + u8::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:105:14
+   |
+LL |     let _n = 1u16 + u16::MAX;
+   |              ^^^^^^^^^^^^^^^ attempt to compute `1_u16 + u16::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:108:14
+   |
+LL |     let _n = 1u32 + u32::MAX;
+   |              ^^^^^^^^^^^^^^^ attempt to compute `1_u32 + u32::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:111:14
+   |
+LL |     let _n = 1u64 + u64::MAX;
+   |              ^^^^^^^^^^^^^^^ attempt to compute `1_u64 + u64::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:114:14
+   |
+LL |     let _n = 1u128 + u128::MAX;
+   |              ^^^^^^^^^^^^^^^^^ attempt to compute `1_u128 + u128::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:117:14
+   |
+LL |     let _n = 1i8 + i8::MAX;
+   |              ^^^^^^^^^^^^^ attempt to compute `1_i8 + i8::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:120:14
+   |
+LL |     let _n = 1i16 + i16::MAX;
+   |              ^^^^^^^^^^^^^^^ attempt to compute `1_i16 + i16::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:123:14
+   |
+LL |     let _n = 1i32 + i32::MAX;
+   |              ^^^^^^^^^^^^^^^ attempt to compute `1_i32 + i32::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:126:14
+   |
+LL |     let _n = 1i64 + i64::MAX;
+   |              ^^^^^^^^^^^^^^^ attempt to compute `1_i64 + i64::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:129:14
+   |
+LL |     let _n = 1i128 + i128::MAX;
+   |              ^^^^^^^^^^^^^^^^^ attempt to compute `1_i128 + i128::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:132:14
+   |
+LL |     let _n = 1isize + isize::MAX;
+   |              ^^^^^^^^^^^^^^^^^^^ attempt to compute `1_isize + isize::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:135:14
+   |
+LL |     let _n = 1usize + usize::MAX;
+   |              ^^^^^^^^^^^^^^^^^^^ attempt to compute `1_usize + usize::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:140:14
+   |
+LL |     let _n = 1u8 - 5;
+   |              ^^^^^^^ attempt to compute `1_u8 - 5_u8`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:143:14
+   |
+LL |     let _n = 1u16 - 5;
+   |              ^^^^^^^^ attempt to compute `1_u16 - 5_u16`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:146:14
+   |
+LL |     let _n = 1u32 - 5;
+   |              ^^^^^^^^ attempt to compute `1_u32 - 5_u32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:149:14
+   |
+LL |     let _n = 1u64 - 5 ;
+   |              ^^^^^^^^ attempt to compute `1_u64 - 5_u64`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:152:14
+   |
+LL |     let _n = 1u128 - 5 ;
+   |              ^^^^^^^^^ attempt to compute `1_u128 - 5_u128`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:155:14
+   |
+LL |     let _n = -5i8 - i8::MAX;
+   |              ^^^^^^^^^^^^^^ attempt to compute `-5_i8 - i8::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:158:14
+   |
+LL |     let _n = -5i16 - i16::MAX;
+   |              ^^^^^^^^^^^^^^^^ attempt to compute `-5_i16 - i16::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:161:14
+   |
+LL |     let _n = -5i32 - i32::MAX;
+   |              ^^^^^^^^^^^^^^^^ attempt to compute `-5_i32 - i32::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:164:14
+   |
+LL |     let _n = -5i64 - i64::MAX;
+   |              ^^^^^^^^^^^^^^^^ attempt to compute `-5_i64 - i64::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:167:14
+   |
+LL |     let _n = -5i128 - i128::MAX;
+   |              ^^^^^^^^^^^^^^^^^^ attempt to compute `-5_i128 - i128::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:170:14
+   |
+LL |     let _n = -5isize - isize::MAX;
+   |              ^^^^^^^^^^^^^^^^^^^^ attempt to compute `-5_isize - isize::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:173:14
+   |
+LL |     let _n = 1usize - 5;
+   |              ^^^^^^^^^^ attempt to compute `1_usize - 5_usize`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:178:14
+   |
+LL |     let _n = u8::MAX * 5;
+   |              ^^^^^^^^^^^ attempt to compute `u8::MAX * 5_u8`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:181:14
+   |
+LL |     let _n = u16::MAX * 5;
+   |              ^^^^^^^^^^^^ attempt to compute `u16::MAX * 5_u16`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:184:14
+   |
+LL |     let _n = u32::MAX * 5;
+   |              ^^^^^^^^^^^^ attempt to compute `u32::MAX * 5_u32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:187:14
+   |
+LL |     let _n = u64::MAX * 5;
+   |              ^^^^^^^^^^^^ attempt to compute `u64::MAX * 5_u64`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:190:14
+   |
+LL |     let _n = u128::MAX * 5;
+   |              ^^^^^^^^^^^^^ attempt to compute `u128::MAX * 5_u128`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:193:14
+   |
+LL |     let _n = i8::MAX * i8::MAX;
+   |              ^^^^^^^^^^^^^^^^^ attempt to compute `i8::MAX * i8::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:196:14
+   |
+LL |     let _n = i16::MAX * 5;
+   |              ^^^^^^^^^^^^ attempt to compute `i16::MAX * 5_i16`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:199:14
+   |
+LL |     let _n = i32::MAX * 5;
+   |              ^^^^^^^^^^^^ attempt to compute `i32::MAX * 5_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:202:14
+   |
+LL |     let _n = i64::MAX * 5;
+   |              ^^^^^^^^^^^^ attempt to compute `i64::MAX * 5_i64`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:205:14
+   |
+LL |     let _n = i128::MAX * 5;
+   |              ^^^^^^^^^^^^^ attempt to compute `i128::MAX * 5_i128`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:208:14
+   |
+LL |     let _n = isize::MAX * 5;
+   |              ^^^^^^^^^^^^^^ attempt to compute `isize::MAX * 5_isize`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:211:14
+   |
+LL |     let _n = usize::MAX * 5;
+   |              ^^^^^^^^^^^^^^ attempt to compute `usize::MAX * 5_usize`, which would overflow
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:216:14
+   |
+LL |     let _n = 1u8 / 0;
+   |              ^^^^^^^ attempt to divide `1_u8` by zero
+   |
+   = note: `#[deny(unconditional_panic)]` on by default
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:217:15
+   |
+LL |     let _n = &(1u8 / 0);
+   |               ^^^^^^^^^ attempt to divide `1_u8` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:219:14
+   |
+LL |     let _n = 1u16 / 0;
+   |              ^^^^^^^^ attempt to divide `1_u16` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:220:15
+   |
+LL |     let _n = &(1u16 / 0);
+   |               ^^^^^^^^^^ attempt to divide `1_u16` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:222:14
+   |
+LL |     let _n = 1u32 / 0;
+   |              ^^^^^^^^ attempt to divide `1_u32` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:223:15
+   |
+LL |     let _n = &(1u32 / 0);
+   |               ^^^^^^^^^^ attempt to divide `1_u32` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:225:14
+   |
+LL |     let _n = 1u64 / 0;
+   |              ^^^^^^^^ attempt to divide `1_u64` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:226:15
+   |
+LL |     let _n = &(1u64 / 0);
+   |               ^^^^^^^^^^ attempt to divide `1_u64` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:228:14
+   |
+LL |     let _n = 1u128 / 0;
+   |              ^^^^^^^^^ attempt to divide `1_u128` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:229:15
+   |
+LL |     let _n = &(1u128 / 0);
+   |               ^^^^^^^^^^^ attempt to divide `1_u128` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:231:14
+   |
+LL |     let _n = 1i8 / 0;
+   |              ^^^^^^^ attempt to divide `1_i8` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:232:15
+   |
+LL |     let _n = &(1i8 / 0);
+   |               ^^^^^^^^^ attempt to divide `1_i8` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:234:14
+   |
+LL |     let _n = 1i16 / 0;
+   |              ^^^^^^^^ attempt to divide `1_i16` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:235:15
+   |
+LL |     let _n = &(1i16 / 0);
+   |               ^^^^^^^^^^ attempt to divide `1_i16` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:237:14
+   |
+LL |     let _n = 1i32 / 0;
+   |              ^^^^^^^^ attempt to divide `1_i32` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:238:15
+   |
+LL |     let _n = &(1i32 / 0);
+   |               ^^^^^^^^^^ attempt to divide `1_i32` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:240:14
+   |
+LL |     let _n = 1i64 / 0;
+   |              ^^^^^^^^ attempt to divide `1_i64` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:241:15
+   |
+LL |     let _n = &(1i64 / 0);
+   |               ^^^^^^^^^^ attempt to divide `1_i64` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:243:14
+   |
+LL |     let _n = 1i128 / 0;
+   |              ^^^^^^^^^ attempt to divide `1_i128` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:244:15
+   |
+LL |     let _n = &(1i128 / 0);
+   |               ^^^^^^^^^^^ attempt to divide `1_i128` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:246:14
+   |
+LL |     let _n = 1isize / 0;
+   |              ^^^^^^^^^^ attempt to divide `1_isize` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:247:15
+   |
+LL |     let _n = &(1isize / 0);
+   |               ^^^^^^^^^^^^ attempt to divide `1_isize` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:249:14
+   |
+LL |     let _n = 1usize / 0;
+   |              ^^^^^^^^^^ attempt to divide `1_usize` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:250:15
+   |
+LL |     let _n = &(1usize / 0);
+   |               ^^^^^^^^^^^^ attempt to divide `1_usize` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:254:14
+   |
+LL |     let _n = 1u8 % 0;
+   |              ^^^^^^^ attempt to calculate the remainder of `1_u8` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:255:15
+   |
+LL |     let _n = &(1u8 % 0);
+   |               ^^^^^^^^^ attempt to calculate the remainder of `1_u8` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:257:14
+   |
+LL |     let _n = 1u16 % 0;
+   |              ^^^^^^^^ attempt to calculate the remainder of `1_u16` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:258:15
+   |
+LL |     let _n = &(1u16 % 0);
+   |               ^^^^^^^^^^ attempt to calculate the remainder of `1_u16` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:260:14
+   |
+LL |     let _n = 1u32 % 0;
+   |              ^^^^^^^^ attempt to calculate the remainder of `1_u32` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:261:15
+   |
+LL |     let _n = &(1u32 % 0);
+   |               ^^^^^^^^^^ attempt to calculate the remainder of `1_u32` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:263:14
+   |
+LL |     let _n = 1u64 % 0;
+   |              ^^^^^^^^ attempt to calculate the remainder of `1_u64` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:264:15
+   |
+LL |     let _n = &(1u64 % 0);
+   |               ^^^^^^^^^^ attempt to calculate the remainder of `1_u64` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:266:14
+   |
+LL |     let _n = 1u128 % 0;
+   |              ^^^^^^^^^ attempt to calculate the remainder of `1_u128` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:267:15
+   |
+LL |     let _n = &(1u128 % 0);
+   |               ^^^^^^^^^^^ attempt to calculate the remainder of `1_u128` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:269:14
+   |
+LL |     let _n = 1i8 % 0;
+   |              ^^^^^^^ attempt to calculate the remainder of `1_i8` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:270:15
+   |
+LL |     let _n = &(1i8 % 0);
+   |               ^^^^^^^^^ attempt to calculate the remainder of `1_i8` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:272:14
+   |
+LL |     let _n = 1i16 % 0;
+   |              ^^^^^^^^ attempt to calculate the remainder of `1_i16` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:273:15
+   |
+LL |     let _n = &(1i16 % 0);
+   |               ^^^^^^^^^^ attempt to calculate the remainder of `1_i16` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:275:14
+   |
+LL |     let _n = 1i32 % 0;
+   |              ^^^^^^^^ attempt to calculate the remainder of `1_i32` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:276:15
+   |
+LL |     let _n = &(1i32 % 0);
+   |               ^^^^^^^^^^ attempt to calculate the remainder of `1_i32` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:278:14
+   |
+LL |     let _n = 1i64 % 0;
+   |              ^^^^^^^^ attempt to calculate the remainder of `1_i64` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:279:15
+   |
+LL |     let _n = &(1i64 % 0);
+   |               ^^^^^^^^^^ attempt to calculate the remainder of `1_i64` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:281:14
+   |
+LL |     let _n = 1i128 % 0;
+   |              ^^^^^^^^^ attempt to calculate the remainder of `1_i128` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:282:15
+   |
+LL |     let _n = &(1i128 % 0);
+   |               ^^^^^^^^^^^ attempt to calculate the remainder of `1_i128` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:284:14
+   |
+LL |     let _n = 1isize % 0;
+   |              ^^^^^^^^^^ attempt to calculate the remainder of `1_isize` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:285:15
+   |
+LL |     let _n = &(1isize % 0);
+   |               ^^^^^^^^^^^^ attempt to calculate the remainder of `1_isize` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:287:14
+   |
+LL |     let _n = 1usize % 0;
+   |              ^^^^^^^^^^ attempt to calculate the remainder of `1_usize` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:288:15
+   |
+LL |     let _n = &(1usize % 0);
+   |               ^^^^^^^^^^^^ attempt to calculate the remainder of `1_usize` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:292:14
+   |
+LL |     let _n = [1, 2, 3][4];
+   |              ^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 4
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:293:15
+   |
+LL |     let _n = &([1, 2, 3][4]);
+   |               ^^^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 4
+
+error: aborting due to 170 previous errors
+
diff --git a/tests/ui/lint/lint-overflowing-ops.opt_with_overflow_checks.stderr b/tests/ui/lint/lint-overflowing-ops.opt_with_overflow_checks.stderr
new file mode 100644
index 00000000000..93fc19ce79e
--- /dev/null
+++ b/tests/ui/lint/lint-overflowing-ops.opt_with_overflow_checks.stderr
@@ -0,0 +1,1030 @@
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:26:14
+   |
+LL |     let _n = 1u8 << 8;
+   |              ^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+   |
+note: the lint level is defined here
+  --> $DIR/lint-overflowing-ops.rs:17:9
+   |
+LL | #![deny(arithmetic_overflow)]
+   |         ^^^^^^^^^^^^^^^^^^^
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:212:15
+   |
+LL |     let _n = &(usize::MAX * 5);
+   |               ^^^^^^^^^^^^^^^^ attempt to compute `usize::MAX * 5_usize`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:209:15
+   |
+LL |     let _n = &(isize::MAX * 5);
+   |               ^^^^^^^^^^^^^^^^ attempt to compute `isize::MAX * 5_isize`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:206:15
+   |
+LL |     let _n = &(i128::MAX * 5);
+   |               ^^^^^^^^^^^^^^^ attempt to compute `i128::MAX * 5_i128`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:203:15
+   |
+LL |     let _n = &(i64::MAX * 5);
+   |               ^^^^^^^^^^^^^^ attempt to compute `i64::MAX * 5_i64`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:200:15
+   |
+LL |     let _n = &(i32::MAX * 5);
+   |               ^^^^^^^^^^^^^^ attempt to compute `i32::MAX * 5_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:197:15
+   |
+LL |     let _n = &(i16::MAX * 5);
+   |               ^^^^^^^^^^^^^^ attempt to compute `i16::MAX * 5_i16`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:194:15
+   |
+LL |     let _n = &(i8::MAX * i8::MAX);
+   |               ^^^^^^^^^^^^^^^^^^^ attempt to compute `i8::MAX * i8::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:191:15
+   |
+LL |     let _n = &(u128::MAX * 5);
+   |               ^^^^^^^^^^^^^^^ attempt to compute `u128::MAX * 5_u128`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:188:15
+   |
+LL |     let _n = &(u64::MAX * 5);
+   |               ^^^^^^^^^^^^^^ attempt to compute `u64::MAX * 5_u64`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:185:15
+   |
+LL |     let _n = &(u32::MAX * 5);
+   |               ^^^^^^^^^^^^^^ attempt to compute `u32::MAX * 5_u32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:182:15
+   |
+LL |     let _n = &(u16::MAX * 5);
+   |               ^^^^^^^^^^^^^^ attempt to compute `u16::MAX * 5_u16`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:179:15
+   |
+LL |     let _n = &(u8::MAX * 5);
+   |               ^^^^^^^^^^^^^ attempt to compute `u8::MAX * 5_u8`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:174:15
+   |
+LL |     let _n = &(1usize - 5);
+   |               ^^^^^^^^^^^^ attempt to compute `1_usize - 5_usize`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:171:15
+   |
+LL |     let _n = &(-5isize - isize::MAX);
+   |               ^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `-5_isize - isize::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:168:15
+   |
+LL |     let _n = &(-5i128 - i128::MAX);
+   |               ^^^^^^^^^^^^^^^^^^^^ attempt to compute `-5_i128 - i128::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:165:15
+   |
+LL |     let _n = &(-5i64 - i64::MAX);
+   |               ^^^^^^^^^^^^^^^^^^ attempt to compute `-5_i64 - i64::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:162:15
+   |
+LL |     let _n = &(-5i32 - i32::MAX);
+   |               ^^^^^^^^^^^^^^^^^^ attempt to compute `-5_i32 - i32::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:159:15
+   |
+LL |     let _n = &(-5i16 - i16::MAX);
+   |               ^^^^^^^^^^^^^^^^^^ attempt to compute `-5_i16 - i16::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:156:15
+   |
+LL |     let _n = &(-5i8 - i8::MAX);
+   |               ^^^^^^^^^^^^^^^^ attempt to compute `-5_i8 - i8::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:153:15
+   |
+LL |     let _n = &(1u128 - 5);
+   |               ^^^^^^^^^^^ attempt to compute `1_u128 - 5_u128`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:150:15
+   |
+LL |     let _n = &(1u64 - 5);
+   |               ^^^^^^^^^^ attempt to compute `1_u64 - 5_u64`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:147:15
+   |
+LL |     let _n = &(1u32 - 5);
+   |               ^^^^^^^^^^ attempt to compute `1_u32 - 5_u32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:144:15
+   |
+LL |     let _n = &(1u16 - 5);
+   |               ^^^^^^^^^^ attempt to compute `1_u16 - 5_u16`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:141:15
+   |
+LL |     let _n = &(1u8 - 5);
+   |               ^^^^^^^^^ attempt to compute `1_u8 - 5_u8`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:136:15
+   |
+LL |     let _n = &(1usize + usize::MAX);
+   |               ^^^^^^^^^^^^^^^^^^^^^ attempt to compute `1_usize + usize::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:133:15
+   |
+LL |     let _n = &(1isize + isize::MAX);
+   |               ^^^^^^^^^^^^^^^^^^^^^ attempt to compute `1_isize + isize::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:130:15
+   |
+LL |     let _n = &(1i128 + i128::MAX);
+   |               ^^^^^^^^^^^^^^^^^^^ attempt to compute `1_i128 + i128::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:127:15
+   |
+LL |     let _n = &(1i64 + i64::MAX);
+   |               ^^^^^^^^^^^^^^^^^ attempt to compute `1_i64 + i64::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:124:15
+   |
+LL |     let _n = &(1i32 + i32::MAX);
+   |               ^^^^^^^^^^^^^^^^^ attempt to compute `1_i32 + i32::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:121:15
+   |
+LL |     let _n = &(1i16 + i16::MAX);
+   |               ^^^^^^^^^^^^^^^^^ attempt to compute `1_i16 + i16::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:118:15
+   |
+LL |     let _n = &(1i8 + i8::MAX);
+   |               ^^^^^^^^^^^^^^^ attempt to compute `1_i8 + i8::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:115:15
+   |
+LL |     let _n = &(1u128 + u128::MAX);
+   |               ^^^^^^^^^^^^^^^^^^^ attempt to compute `1_u128 + u128::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:112:15
+   |
+LL |     let _n = &(1u64 + u64::MAX);
+   |               ^^^^^^^^^^^^^^^^^ attempt to compute `1_u64 + u64::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:109:15
+   |
+LL |     let _n = &(1u32 + u32::MAX);
+   |               ^^^^^^^^^^^^^^^^^ attempt to compute `1_u32 + u32::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:106:15
+   |
+LL |     let _n = &(1u16 + u16::MAX);
+   |               ^^^^^^^^^^^^^^^^^ attempt to compute `1_u16 + u16::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:103:15
+   |
+LL |     let _n = &(1u8 + u8::MAX);
+   |               ^^^^^^^^^^^^^^^ attempt to compute `1_u8 + u8::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:98:15
+   |
+LL |     let _n = &(1_usize >> BITS);
+   |               ^^^^^^^^^^^^^^^^^ attempt to shift right by `%BITS%`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:95:15
+   |
+LL |     let _n = &(1_isize >> BITS);
+   |               ^^^^^^^^^^^^^^^^^ attempt to shift right by `%BITS%`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:92:15
+   |
+LL |     let _n = &(1i128 >> 128);
+   |               ^^^^^^^^^^^^^^ attempt to shift right by `128_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:89:15
+   |
+LL |     let _n = &(1i64 >> 64);
+   |               ^^^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:86:15
+   |
+LL |     let _n = &(1i32 >> 32);
+   |               ^^^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:83:15
+   |
+LL |     let _n = &(1i16 >> 16);
+   |               ^^^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:80:15
+   |
+LL |     let _n = &(1i8 >> 8);
+   |               ^^^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:77:15
+   |
+LL |     let _n = &(1u128 >> 128);
+   |               ^^^^^^^^^^^^^^ attempt to shift right by `128_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:74:15
+   |
+LL |     let _n = &(1u64 >> 64);
+   |               ^^^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:71:15
+   |
+LL |     let _n = &(1u32 >> 32);
+   |               ^^^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:68:15
+   |
+LL |     let _n = &(1u16 >> 16);
+   |               ^^^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:65:15
+   |
+LL |     let _n = &(1u8 >> 8);
+   |               ^^^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:60:15
+   |
+LL |     let _n = &(1_usize << BITS);
+   |               ^^^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:57:15
+   |
+LL |     let _n = &(1_isize << BITS);
+   |               ^^^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:54:15
+   |
+LL |     let _n = &(1i128 << 128);
+   |               ^^^^^^^^^^^^^^ attempt to shift left by `128_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:51:15
+   |
+LL |     let _n = &(1i64 << 64);
+   |               ^^^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:48:15
+   |
+LL |     let _n = &(1i32 << 32);
+   |               ^^^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:45:15
+   |
+LL |     let _n = &(1i16 << 16);
+   |               ^^^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:42:15
+   |
+LL |     let _n = &(1i8 << 8);
+   |               ^^^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:39:15
+   |
+LL |     let _n = &(1u128 << 128);
+   |               ^^^^^^^^^^^^^^ attempt to shift left by `128_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:36:15
+   |
+LL |     let _n = &(1u64 << 64);
+   |               ^^^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:33:15
+   |
+LL |     let _n = &(1u32 << 32);
+   |               ^^^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:30:15
+   |
+LL |     let _n = &(1u16 << 16);
+   |               ^^^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:27:15
+   |
+LL |     let _n = &(1u8 << 8);
+   |               ^^^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:29:14
+   |
+LL |     let _n = 1u16 << 16;
+   |              ^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:32:14
+   |
+LL |     let _n = 1u32 << 32;
+   |              ^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:35:14
+   |
+LL |     let _n = 1u64 << 64;
+   |              ^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:38:14
+   |
+LL |     let _n = 1u128 << 128;
+   |              ^^^^^^^^^^^^ attempt to shift left by `128_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:41:14
+   |
+LL |     let _n = 1i8 << 8;
+   |              ^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:44:14
+   |
+LL |     let _n = 1i16 << 16;
+   |              ^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:47:14
+   |
+LL |     let _n = 1i32 << 32;
+   |              ^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:50:14
+   |
+LL |     let _n = 1i64 << 64;
+   |              ^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:53:14
+   |
+LL |     let _n = 1i128 << 128;
+   |              ^^^^^^^^^^^^ attempt to shift left by `128_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:56:14
+   |
+LL |     let _n = 1_isize << BITS;
+   |              ^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:59:14
+   |
+LL |     let _n = 1_usize << BITS;
+   |              ^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:64:14
+   |
+LL |     let _n = 1u8 >> 8;
+   |              ^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:67:14
+   |
+LL |     let _n = 1u16 >> 16;
+   |              ^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:70:14
+   |
+LL |     let _n = 1u32 >> 32;
+   |              ^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:73:14
+   |
+LL |     let _n = 1u64 >> 64;
+   |              ^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:76:14
+   |
+LL |     let _n = 1u128 >> 128;
+   |              ^^^^^^^^^^^^ attempt to shift right by `128_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:79:14
+   |
+LL |     let _n = 1i8 >> 8;
+   |              ^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:82:14
+   |
+LL |     let _n = 1i16 >> 16;
+   |              ^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:85:14
+   |
+LL |     let _n = 1i32 >> 32;
+   |              ^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:88:14
+   |
+LL |     let _n = 1i64 >> 64;
+   |              ^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:91:14
+   |
+LL |     let _n = 1i128 >> 128;
+   |              ^^^^^^^^^^^^ attempt to shift right by `128_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:94:14
+   |
+LL |     let _n = 1_isize >> BITS;
+   |              ^^^^^^^^^^^^^^^ attempt to shift right by `%BITS%`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:97:14
+   |
+LL |     let _n = 1_usize >> BITS;
+   |              ^^^^^^^^^^^^^^^ attempt to shift right by `%BITS%`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:102:14
+   |
+LL |     let _n = 1u8 + u8::MAX;
+   |              ^^^^^^^^^^^^^ attempt to compute `1_u8 + u8::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:105:14
+   |
+LL |     let _n = 1u16 + u16::MAX;
+   |              ^^^^^^^^^^^^^^^ attempt to compute `1_u16 + u16::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:108:14
+   |
+LL |     let _n = 1u32 + u32::MAX;
+   |              ^^^^^^^^^^^^^^^ attempt to compute `1_u32 + u32::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:111:14
+   |
+LL |     let _n = 1u64 + u64::MAX;
+   |              ^^^^^^^^^^^^^^^ attempt to compute `1_u64 + u64::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:114:14
+   |
+LL |     let _n = 1u128 + u128::MAX;
+   |              ^^^^^^^^^^^^^^^^^ attempt to compute `1_u128 + u128::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:117:14
+   |
+LL |     let _n = 1i8 + i8::MAX;
+   |              ^^^^^^^^^^^^^ attempt to compute `1_i8 + i8::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:120:14
+   |
+LL |     let _n = 1i16 + i16::MAX;
+   |              ^^^^^^^^^^^^^^^ attempt to compute `1_i16 + i16::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:123:14
+   |
+LL |     let _n = 1i32 + i32::MAX;
+   |              ^^^^^^^^^^^^^^^ attempt to compute `1_i32 + i32::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:126:14
+   |
+LL |     let _n = 1i64 + i64::MAX;
+   |              ^^^^^^^^^^^^^^^ attempt to compute `1_i64 + i64::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:129:14
+   |
+LL |     let _n = 1i128 + i128::MAX;
+   |              ^^^^^^^^^^^^^^^^^ attempt to compute `1_i128 + i128::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:132:14
+   |
+LL |     let _n = 1isize + isize::MAX;
+   |              ^^^^^^^^^^^^^^^^^^^ attempt to compute `1_isize + isize::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:135:14
+   |
+LL |     let _n = 1usize + usize::MAX;
+   |              ^^^^^^^^^^^^^^^^^^^ attempt to compute `1_usize + usize::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:140:14
+   |
+LL |     let _n = 1u8 - 5;
+   |              ^^^^^^^ attempt to compute `1_u8 - 5_u8`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:143:14
+   |
+LL |     let _n = 1u16 - 5;
+   |              ^^^^^^^^ attempt to compute `1_u16 - 5_u16`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:146:14
+   |
+LL |     let _n = 1u32 - 5;
+   |              ^^^^^^^^ attempt to compute `1_u32 - 5_u32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:149:14
+   |
+LL |     let _n = 1u64 - 5 ;
+   |              ^^^^^^^^ attempt to compute `1_u64 - 5_u64`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:152:14
+   |
+LL |     let _n = 1u128 - 5 ;
+   |              ^^^^^^^^^ attempt to compute `1_u128 - 5_u128`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:155:14
+   |
+LL |     let _n = -5i8 - i8::MAX;
+   |              ^^^^^^^^^^^^^^ attempt to compute `-5_i8 - i8::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:158:14
+   |
+LL |     let _n = -5i16 - i16::MAX;
+   |              ^^^^^^^^^^^^^^^^ attempt to compute `-5_i16 - i16::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:161:14
+   |
+LL |     let _n = -5i32 - i32::MAX;
+   |              ^^^^^^^^^^^^^^^^ attempt to compute `-5_i32 - i32::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:164:14
+   |
+LL |     let _n = -5i64 - i64::MAX;
+   |              ^^^^^^^^^^^^^^^^ attempt to compute `-5_i64 - i64::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:167:14
+   |
+LL |     let _n = -5i128 - i128::MAX;
+   |              ^^^^^^^^^^^^^^^^^^ attempt to compute `-5_i128 - i128::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:170:14
+   |
+LL |     let _n = -5isize - isize::MAX;
+   |              ^^^^^^^^^^^^^^^^^^^^ attempt to compute `-5_isize - isize::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:173:14
+   |
+LL |     let _n = 1usize - 5;
+   |              ^^^^^^^^^^ attempt to compute `1_usize - 5_usize`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:178:14
+   |
+LL |     let _n = u8::MAX * 5;
+   |              ^^^^^^^^^^^ attempt to compute `u8::MAX * 5_u8`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:181:14
+   |
+LL |     let _n = u16::MAX * 5;
+   |              ^^^^^^^^^^^^ attempt to compute `u16::MAX * 5_u16`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:184:14
+   |
+LL |     let _n = u32::MAX * 5;
+   |              ^^^^^^^^^^^^ attempt to compute `u32::MAX * 5_u32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:187:14
+   |
+LL |     let _n = u64::MAX * 5;
+   |              ^^^^^^^^^^^^ attempt to compute `u64::MAX * 5_u64`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:190:14
+   |
+LL |     let _n = u128::MAX * 5;
+   |              ^^^^^^^^^^^^^ attempt to compute `u128::MAX * 5_u128`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:193:14
+   |
+LL |     let _n = i8::MAX * i8::MAX;
+   |              ^^^^^^^^^^^^^^^^^ attempt to compute `i8::MAX * i8::MAX`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:196:14
+   |
+LL |     let _n = i16::MAX * 5;
+   |              ^^^^^^^^^^^^ attempt to compute `i16::MAX * 5_i16`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:199:14
+   |
+LL |     let _n = i32::MAX * 5;
+   |              ^^^^^^^^^^^^ attempt to compute `i32::MAX * 5_i32`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:202:14
+   |
+LL |     let _n = i64::MAX * 5;
+   |              ^^^^^^^^^^^^ attempt to compute `i64::MAX * 5_i64`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:205:14
+   |
+LL |     let _n = i128::MAX * 5;
+   |              ^^^^^^^^^^^^^ attempt to compute `i128::MAX * 5_i128`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:208:14
+   |
+LL |     let _n = isize::MAX * 5;
+   |              ^^^^^^^^^^^^^^ attempt to compute `isize::MAX * 5_isize`, which would overflow
+
+error: this arithmetic operation will overflow
+  --> $DIR/lint-overflowing-ops.rs:211:14
+   |
+LL |     let _n = usize::MAX * 5;
+   |              ^^^^^^^^^^^^^^ attempt to compute `usize::MAX * 5_usize`, which would overflow
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:216:14
+   |
+LL |     let _n = 1u8 / 0;
+   |              ^^^^^^^ attempt to divide `1_u8` by zero
+   |
+   = note: `#[deny(unconditional_panic)]` on by default
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:217:15
+   |
+LL |     let _n = &(1u8 / 0);
+   |               ^^^^^^^^^ attempt to divide `1_u8` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:219:14
+   |
+LL |     let _n = 1u16 / 0;
+   |              ^^^^^^^^ attempt to divide `1_u16` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:220:15
+   |
+LL |     let _n = &(1u16 / 0);
+   |               ^^^^^^^^^^ attempt to divide `1_u16` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:222:14
+   |
+LL |     let _n = 1u32 / 0;
+   |              ^^^^^^^^ attempt to divide `1_u32` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:223:15
+   |
+LL |     let _n = &(1u32 / 0);
+   |               ^^^^^^^^^^ attempt to divide `1_u32` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:225:14
+   |
+LL |     let _n = 1u64 / 0;
+   |              ^^^^^^^^ attempt to divide `1_u64` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:226:15
+   |
+LL |     let _n = &(1u64 / 0);
+   |               ^^^^^^^^^^ attempt to divide `1_u64` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:228:14
+   |
+LL |     let _n = 1u128 / 0;
+   |              ^^^^^^^^^ attempt to divide `1_u128` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:229:15
+   |
+LL |     let _n = &(1u128 / 0);
+   |               ^^^^^^^^^^^ attempt to divide `1_u128` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:231:14
+   |
+LL |     let _n = 1i8 / 0;
+   |              ^^^^^^^ attempt to divide `1_i8` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:232:15
+   |
+LL |     let _n = &(1i8 / 0);
+   |               ^^^^^^^^^ attempt to divide `1_i8` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:234:14
+   |
+LL |     let _n = 1i16 / 0;
+   |              ^^^^^^^^ attempt to divide `1_i16` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:235:15
+   |
+LL |     let _n = &(1i16 / 0);
+   |               ^^^^^^^^^^ attempt to divide `1_i16` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:237:14
+   |
+LL |     let _n = 1i32 / 0;
+   |              ^^^^^^^^ attempt to divide `1_i32` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:238:15
+   |
+LL |     let _n = &(1i32 / 0);
+   |               ^^^^^^^^^^ attempt to divide `1_i32` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:240:14
+   |
+LL |     let _n = 1i64 / 0;
+   |              ^^^^^^^^ attempt to divide `1_i64` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:241:15
+   |
+LL |     let _n = &(1i64 / 0);
+   |               ^^^^^^^^^^ attempt to divide `1_i64` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:243:14
+   |
+LL |     let _n = 1i128 / 0;
+   |              ^^^^^^^^^ attempt to divide `1_i128` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:244:15
+   |
+LL |     let _n = &(1i128 / 0);
+   |               ^^^^^^^^^^^ attempt to divide `1_i128` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:246:14
+   |
+LL |     let _n = 1isize / 0;
+   |              ^^^^^^^^^^ attempt to divide `1_isize` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:247:15
+   |
+LL |     let _n = &(1isize / 0);
+   |               ^^^^^^^^^^^^ attempt to divide `1_isize` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:249:14
+   |
+LL |     let _n = 1usize / 0;
+   |              ^^^^^^^^^^ attempt to divide `1_usize` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:250:15
+   |
+LL |     let _n = &(1usize / 0);
+   |               ^^^^^^^^^^^^ attempt to divide `1_usize` by zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:254:14
+   |
+LL |     let _n = 1u8 % 0;
+   |              ^^^^^^^ attempt to calculate the remainder of `1_u8` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:255:15
+   |
+LL |     let _n = &(1u8 % 0);
+   |               ^^^^^^^^^ attempt to calculate the remainder of `1_u8` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:257:14
+   |
+LL |     let _n = 1u16 % 0;
+   |              ^^^^^^^^ attempt to calculate the remainder of `1_u16` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:258:15
+   |
+LL |     let _n = &(1u16 % 0);
+   |               ^^^^^^^^^^ attempt to calculate the remainder of `1_u16` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:260:14
+   |
+LL |     let _n = 1u32 % 0;
+   |              ^^^^^^^^ attempt to calculate the remainder of `1_u32` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:261:15
+   |
+LL |     let _n = &(1u32 % 0);
+   |               ^^^^^^^^^^ attempt to calculate the remainder of `1_u32` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:263:14
+   |
+LL |     let _n = 1u64 % 0;
+   |              ^^^^^^^^ attempt to calculate the remainder of `1_u64` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:264:15
+   |
+LL |     let _n = &(1u64 % 0);
+   |               ^^^^^^^^^^ attempt to calculate the remainder of `1_u64` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:266:14
+   |
+LL |     let _n = 1u128 % 0;
+   |              ^^^^^^^^^ attempt to calculate the remainder of `1_u128` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:267:15
+   |
+LL |     let _n = &(1u128 % 0);
+   |               ^^^^^^^^^^^ attempt to calculate the remainder of `1_u128` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:269:14
+   |
+LL |     let _n = 1i8 % 0;
+   |              ^^^^^^^ attempt to calculate the remainder of `1_i8` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:270:15
+   |
+LL |     let _n = &(1i8 % 0);
+   |               ^^^^^^^^^ attempt to calculate the remainder of `1_i8` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:272:14
+   |
+LL |     let _n = 1i16 % 0;
+   |              ^^^^^^^^ attempt to calculate the remainder of `1_i16` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:273:15
+   |
+LL |     let _n = &(1i16 % 0);
+   |               ^^^^^^^^^^ attempt to calculate the remainder of `1_i16` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:275:14
+   |
+LL |     let _n = 1i32 % 0;
+   |              ^^^^^^^^ attempt to calculate the remainder of `1_i32` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:276:15
+   |
+LL |     let _n = &(1i32 % 0);
+   |               ^^^^^^^^^^ attempt to calculate the remainder of `1_i32` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:278:14
+   |
+LL |     let _n = 1i64 % 0;
+   |              ^^^^^^^^ attempt to calculate the remainder of `1_i64` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:279:15
+   |
+LL |     let _n = &(1i64 % 0);
+   |               ^^^^^^^^^^ attempt to calculate the remainder of `1_i64` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:281:14
+   |
+LL |     let _n = 1i128 % 0;
+   |              ^^^^^^^^^ attempt to calculate the remainder of `1_i128` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:282:15
+   |
+LL |     let _n = &(1i128 % 0);
+   |               ^^^^^^^^^^^ attempt to calculate the remainder of `1_i128` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:284:14
+   |
+LL |     let _n = 1isize % 0;
+   |              ^^^^^^^^^^ attempt to calculate the remainder of `1_isize` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:285:15
+   |
+LL |     let _n = &(1isize % 0);
+   |               ^^^^^^^^^^^^ attempt to calculate the remainder of `1_isize` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:287:14
+   |
+LL |     let _n = 1usize % 0;
+   |              ^^^^^^^^^^ attempt to calculate the remainder of `1_usize` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:288:15
+   |
+LL |     let _n = &(1usize % 0);
+   |               ^^^^^^^^^^^^ attempt to calculate the remainder of `1_usize` with a divisor of zero
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:292:14
+   |
+LL |     let _n = [1, 2, 3][4];
+   |              ^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 4
+
+error: this operation will panic at runtime
+  --> $DIR/lint-overflowing-ops.rs:293:15
+   |
+LL |     let _n = &([1, 2, 3][4]);
+   |               ^^^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 4
+
+error: aborting due to 170 previous errors
+
diff --git a/tests/ui/lint/lint-overflowing-ops.rs b/tests/ui/lint/lint-overflowing-ops.rs
new file mode 100644
index 00000000000..e64c210bade
--- /dev/null
+++ b/tests/ui/lint/lint-overflowing-ops.rs
@@ -0,0 +1,294 @@
+// Tests that overflowing or bound-exceeding operations
+// are correclty linted including when they are const promoted
+
+// We are using "-Z deduplicate-diagnostics=yes" because different
+// build configurations emit different number of duplicate diagnostics
+// and this flag lets us test them all with a single .rs file like this
+
+//@ revisions: noopt opt opt_with_overflow_checks
+//@ [noopt]compile-flags: -C opt-level=0 -Z deduplicate-diagnostics=yes
+//@ [opt]compile-flags: -O
+//@ [opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O -Z deduplicate-diagnostics=yes
+//@ build-fail
+//@ ignore-pass (test tests codegen-time behaviour)
+//@ normalize-stderr-test "shift left by `(64|32)_usize`, which" -> "shift left by `%BITS%`, which"
+//@ normalize-stderr-test "shift right by `(64|32)_usize`, which" -> "shift right by `%BITS%`, which"
+
+#![deny(arithmetic_overflow)]
+
+#[cfg(target_pointer_width = "32")]
+const BITS: usize = 32;
+#[cfg(target_pointer_width = "64")]
+const BITS: usize = 64;
+
+fn main() {
+    // Shift left
+    let _n = 1u8 << 8;   //~ ERROR: arithmetic operation will overflow
+    let _n = &(1u8 << 8);   //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1u16 << 16; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1u16 << 16); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1u32 << 32; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1u32 << 32); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1u64 << 64; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1u64 << 64); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1u128 << 128; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1u128 << 128); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1i8 << 8;   //~ ERROR: arithmetic operation will overflow
+    let _n = &(1i8 << 8);   //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1i16 << 16; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1i16 << 16); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1i32 << 32; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1i32 << 32); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1i64 << 64; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1i64 << 64); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1i128 << 128; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1i128 << 128); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1_isize << BITS; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1_isize << BITS); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1_usize << BITS; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1_usize << BITS); //~ ERROR: arithmetic operation will overflow
+
+
+    // Shift right
+    let _n = 1u8 >> 8;   //~ ERROR: arithmetic operation will overflow
+    let _n = &(1u8 >> 8);   //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1u16 >> 16; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1u16 >> 16); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1u32 >> 32; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1u32 >> 32); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1u64 >> 64; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1u64 >> 64); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1u128 >> 128; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1u128 >> 128); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1i8 >> 8;   //~ ERROR: arithmetic operation will overflow
+    let _n = &(1i8 >> 8);   //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1i16 >> 16; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1i16 >> 16); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1i32 >> 32; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1i32 >> 32); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1i64 >> 64; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1i64 >> 64); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1i128 >> 128; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1i128 >> 128); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1_isize >> BITS; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1_isize >> BITS); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1_usize >> BITS; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1_usize >> BITS); //~ ERROR: arithmetic operation will overflow
+
+
+    // Addition
+    let _n = 1u8 + u8::MAX;   //~ ERROR: arithmetic operation will overflow
+    let _n = &(1u8 + u8::MAX);   //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1u16 + u16::MAX; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1u16 + u16::MAX); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1u32 + u32::MAX; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1u32 + u32::MAX); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1u64 + u64::MAX; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1u64 + u64::MAX); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1u128 + u128::MAX; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1u128 + u128::MAX); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1i8 + i8::MAX;   //~ ERROR: arithmetic operation will overflow
+    let _n = &(1i8 + i8::MAX);   //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1i16 + i16::MAX; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1i16 + i16::MAX); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1i32 + i32::MAX; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1i32 + i32::MAX); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1i64 + i64::MAX; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1i64 + i64::MAX); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1i128 + i128::MAX; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1i128 + i128::MAX); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1isize + isize::MAX; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1isize + isize::MAX); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1usize + usize::MAX; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1usize + usize::MAX); //~ ERROR: arithmetic operation will overflow
+
+
+    // Subtraction
+    let _n = 1u8 - 5;   //~ ERROR: arithmetic operation will overflow
+    let _n = &(1u8 - 5);   //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1u16 - 5; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1u16 - 5); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1u32 - 5; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1u32 - 5); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1u64 - 5 ; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1u64 - 5); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1u128 - 5 ; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1u128 - 5); //~ ERROR: arithmetic operation will overflow
+
+    let _n = -5i8 - i8::MAX;   //~ ERROR: arithmetic operation will overflow
+    let _n = &(-5i8 - i8::MAX);   //~ ERROR: arithmetic operation will overflow
+
+    let _n = -5i16 - i16::MAX; //~ ERROR: arithmetic operation will overflow
+    let _n = &(-5i16 - i16::MAX); //~ ERROR: arithmetic operation will overflow
+
+    let _n = -5i32 - i32::MAX; //~ ERROR: arithmetic operation will overflow
+    let _n = &(-5i32 - i32::MAX); //~ ERROR: arithmetic operation will overflow
+
+    let _n = -5i64 - i64::MAX; //~ ERROR: arithmetic operation will overflow
+    let _n = &(-5i64 - i64::MAX); //~ ERROR: arithmetic operation will overflow
+
+    let _n = -5i128 - i128::MAX; //~ ERROR: arithmetic operation will overflow
+    let _n = &(-5i128 - i128::MAX); //~ ERROR: arithmetic operation will overflow
+
+    let _n = -5isize - isize::MAX; //~ ERROR: arithmetic operation will overflow
+    let _n = &(-5isize - isize::MAX); //~ ERROR: arithmetic operation will overflow
+
+    let _n = 1usize - 5; //~ ERROR: arithmetic operation will overflow
+    let _n = &(1usize - 5); //~ ERROR: arithmetic operation will overflow
+
+
+    // Multiplication
+    let _n = u8::MAX * 5; //~ ERROR: arithmetic operation will overflow
+    let _n = &(u8::MAX * 5); //~ ERROR: arithmetic operation will overflow
+
+    let _n = u16::MAX * 5; //~ ERROR: arithmetic operation will overflow
+    let _n = &(u16::MAX * 5); //~ ERROR: arithmetic operation will overflow
+
+    let _n = u32::MAX * 5; //~ ERROR: arithmetic operation will overflow
+    let _n = &(u32::MAX * 5); //~ ERROR: arithmetic operation will overflow
+
+    let _n = u64::MAX * 5; //~ ERROR: arithmetic operation will overflow
+    let _n = &(u64::MAX * 5); //~ ERROR: arithmetic operation will overflow
+
+    let _n = u128::MAX * 5; //~ ERROR: arithmetic operation will overflow
+    let _n = &(u128::MAX * 5); //~ ERROR: arithmetic operation will overflow
+
+    let _n = i8::MAX * i8::MAX;   //~ ERROR: arithmetic operation will overflow
+    let _n = &(i8::MAX * i8::MAX);   //~ ERROR: arithmetic operation will overflow
+
+    let _n = i16::MAX * 5; //~ ERROR: arithmetic operation will overflow
+    let _n = &(i16::MAX * 5); //~ ERROR: arithmetic operation will overflow
+
+    let _n = i32::MAX * 5; //~ ERROR: arithmetic operation will overflow
+    let _n = &(i32::MAX * 5); //~ ERROR: arithmetic operation will overflow
+
+    let _n = i64::MAX * 5; //~ ERROR: arithmetic operation will overflow
+    let _n = &(i64::MAX * 5); //~ ERROR: arithmetic operation will overflow
+
+    let _n = i128::MAX * 5; //~ ERROR: arithmetic operation will overflow
+    let _n = &(i128::MAX * 5); //~ ERROR: arithmetic operation will overflow
+
+    let _n = isize::MAX * 5; //~ ERROR: arithmetic operation will overflow
+    let _n = &(isize::MAX * 5); //~ ERROR: arithmetic operation will overflow
+
+    let _n = usize::MAX * 5; //~ ERROR: arithmetic operation will overflow
+    let _n = &(usize::MAX * 5); //~ ERROR: arithmetic operation will overflow
+
+
+    // Division
+    let _n = 1u8 / 0; //~ ERROR: this operation will panic at runtime
+    let _n = &(1u8 / 0); //~ ERROR: this operation will panic at runtime
+
+    let _n = 1u16 / 0; //~ ERROR: this operation will panic at runtime
+    let _n = &(1u16 / 0); //~ ERROR: this operation will panic at runtime
+
+    let _n = 1u32 / 0; //~ ERROR: this operation will panic at runtime
+    let _n = &(1u32 / 0); //~ ERROR: this operation will panic at runtime
+
+    let _n = 1u64 / 0; //~ ERROR: this operation will panic at runtime
+    let _n = &(1u64 / 0); //~ ERROR: this operation will panic at runtime
+
+    let _n = 1u128 / 0; //~ ERROR: this operation will panic at runtime
+    let _n = &(1u128 / 0); //~ ERROR: this operation will panic at runtime
+
+    let _n = 1i8 / 0;   //~ ERROR: this operation will panic at runtime
+    let _n = &(1i8 / 0);   //~ ERROR: this operation will panic at runtime
+
+    let _n = 1i16 / 0; //~ ERROR: this operation will panic at runtime
+    let _n = &(1i16 / 0); //~ ERROR: this operation will panic at runtime
+
+    let _n = 1i32 / 0; //~ ERROR: this operation will panic at runtime
+    let _n = &(1i32 / 0); //~ ERROR: this operation will panic at runtime
+
+    let _n = 1i64 / 0; //~ ERROR: this operation will panic at runtime
+    let _n = &(1i64 / 0); //~ ERROR: this operation will panic at runtime
+
+    let _n = 1i128 / 0; //~ ERROR: this operation will panic at runtime
+    let _n = &(1i128 / 0); //~ ERROR: this operation will panic at runtime
+
+    let _n = 1isize / 0; //~ ERROR: this operation will panic at runtime
+    let _n = &(1isize / 0); //~ ERROR: this operation will panic at runtime
+
+    let _n = 1usize / 0; //~ ERROR: this operation will panic at runtime
+    let _n = &(1usize / 0); //~ ERROR: this operation will panic at runtime
+
+
+    // Modulus
+    let _n = 1u8 % 0;   //~ ERROR: this operation will panic at runtime
+    let _n = &(1u8 % 0);   //~ ERROR: this operation will panic at runtime
+
+    let _n = 1u16 % 0; //~ ERROR: this operation will panic at runtime
+    let _n = &(1u16 % 0); //~ ERROR: this operation will panic at runtime
+
+    let _n = 1u32 % 0; //~ ERROR: this operation will panic at runtime
+    let _n = &(1u32 % 0); //~ ERROR: this operation will panic at runtime
+
+    let _n = 1u64 % 0; //~ ERROR: this operation will panic at runtime
+    let _n = &(1u64 % 0); //~ ERROR: this operation will panic at runtime
+
+    let _n = 1u128 % 0; //~ ERROR: this operation will panic at runtime
+    let _n = &(1u128 % 0); //~ ERROR: this operation will panic at runtime
+
+    let _n = 1i8 % 0;   //~ ERROR: this operation will panic at runtime
+    let _n = &(1i8 % 0);   //~ ERROR: this operation will panic at runtime
+
+    let _n = 1i16 % 0; //~ ERROR: this operation will panic at runtime
+    let _n = &(1i16 % 0); //~ ERROR: this operation will panic at runtime
+
+    let _n = 1i32 % 0; //~ ERROR: this operation will panic at runtime
+    let _n = &(1i32 % 0); //~ ERROR: this operation will panic at runtime
+
+    let _n = 1i64 % 0; //~ ERROR: this operation will panic at runtime
+    let _n = &(1i64 % 0); //~ ERROR: this operation will panic at runtime
+
+    let _n = 1i128 % 0; //~ ERROR: this operation will panic at runtime
+    let _n = &(1i128 % 0); //~ ERROR: this operation will panic at runtime
+
+    let _n = 1isize % 0; //~ ERROR: this operation will panic at runtime
+    let _n = &(1isize % 0); //~ ERROR: this operation will panic at runtime
+
+    let _n = 1usize % 0; //~ ERROR: this operation will panic at runtime
+    let _n = &(1usize % 0); //~ ERROR: this operation will panic at runtime
+
+
+    // Out of bounds access
+    let _n = [1, 2, 3][4]; //~ ERROR: this operation will panic at runtime
+    let _n = &([1, 2, 3][4]); //~ ERROR: this operation will panic at runtime
+}
diff --git a/tests/ui/numbers-arithmetic/promoted_overflow_opt.rs b/tests/ui/numbers-arithmetic/promoted_overflow_opt.rs
deleted file mode 100644
index 7004c9a3665..00000000000
--- a/tests/ui/numbers-arithmetic/promoted_overflow_opt.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-//@ run-pass
-
-//@ compile-flags: -O
-
-fn main() {
-    let x = &(0u32 - 1);
-    assert_eq!(*x, u32::MAX)
-}
diff --git a/tests/ui/reify-intrinsic.rs b/tests/ui/reify-intrinsic.rs
index 00398d272be..6c52651f060 100644
--- a/tests/ui/reify-intrinsic.rs
+++ b/tests/ui/reify-intrinsic.rs
@@ -13,10 +13,9 @@ fn b() {
 }
 
 fn c() {
-    let _ = [
-        std::intrinsics::likely,
+    let _: [unsafe extern "rust-intrinsic" fn(bool) -> bool; 2] = [
+        std::intrinsics::likely, //~ ERROR cannot coerce
         std::intrinsics::unlikely,
-        //~^ ERROR cannot coerce
     ];
 }
 
diff --git a/tests/ui/reify-intrinsic.stderr b/tests/ui/reify-intrinsic.stderr
index 310b6c224e0..0119a1a6650 100644
--- a/tests/ui/reify-intrinsic.stderr
+++ b/tests/ui/reify-intrinsic.stderr
@@ -16,14 +16,13 @@ LL |     let _ = std::mem::transmute as unsafe extern "rust-intrinsic" fn(isize)
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: cannot coerce intrinsics to function pointers
-  --> $DIR/reify-intrinsic.rs:18:9
+  --> $DIR/reify-intrinsic.rs:17:9
    |
-LL |         std::intrinsics::unlikely,
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot coerce intrinsics to function pointers
+LL |         std::intrinsics::likely,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^ cannot coerce intrinsics to function pointers
    |
-   = note: expected fn item `extern "rust-intrinsic" fn(_) -> _ {likely}`
-              found fn item `extern "rust-intrinsic" fn(_) -> _ {unlikely}`
-   = note: different fn items have unique types, even if their signatures are the same
+   = note: expected fn pointer `unsafe extern "rust-intrinsic" fn(_) -> _`
+                 found fn item `fn(_) -> _ {likely}`
 
 error: aborting due to 3 previous errors
 
diff --git a/triagebot.toml b/triagebot.toml
index 9f2be743a5a..1a30399e46c 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -480,12 +480,16 @@ cc = ["@lcnr", "@compiler-errors"]
 message = "Some changes occurred in diagnostic error codes"
 cc = ["@GuillaumeGomez"]
 
+[mentions."compiler/rustc_mir_build/src/build/matches"]
+message = "Some changes occurred in match lowering"
+cc = ["@Nadrieril"]
+
 [mentions."compiler/rustc_mir_build/src/thir/pattern"]
-message = "Some changes might have occurred in exhaustiveness checking"
+message = "Some changes occurred in match checking"
 cc = ["@Nadrieril"]
 
 [mentions."compiler/rustc_pattern_analysis"]
-message = "Some changes might have occurred in exhaustiveness checking"
+message = "Some changes occurred in exhaustiveness checking"
 cc = ["@Nadrieril"]
 
 [mentions."library/core/src/intrinsics/simd.rs"]
@@ -659,6 +663,7 @@ compiler-team = [
 ]
 compiler-team-contributors = [
     "@TaKO8Ki",
+    "@Nadrieril",
     "@nnethercote",
     "@fmease",
 ]