From 14d90deab9cbbc1bfb45af52f9dc9fbce945da91 Mon Sep 17 00:00:00 2001
From: jumbatm <jumbatm@gmail.com>
Date: Thu, 23 Apr 2020 20:17:15 +1000
Subject: [PATCH 01/19] Don't duplicate macro for optional arg.

---
 src/librustc_mir/interpret/validity.rs | 30 ++++++--------------------
 1 file changed, 6 insertions(+), 24 deletions(-)

diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index df3c353220318..0b6422316ead7 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -24,43 +24,25 @@ use super::{
 };
 
 macro_rules! throw_validation_failure {
-    ($what:expr, $where:expr, $details:expr) => {{
-        let mut msg = format!("encountered {}", $what);
-        let where_ = &$where;
-        if !where_.is_empty() {
-            msg.push_str(" at ");
-            write_path(&mut msg, where_);
-        }
-        write!(&mut msg, ", but expected {}", $details).unwrap();
-        throw_ub!(ValidationFailure(msg))
-    }};
-    ($what:expr, $where:expr) => {{
+    ($what:expr, $where:expr $(, $details:expr )?) => {{
         let mut msg = format!("encountered {}", $what);
         let where_ = &$where;
         if !where_.is_empty() {
             msg.push_str(" at ");
             write_path(&mut msg, where_);
         }
+        $( write!(&mut msg, ", but expected {}", $details).unwrap(); )?
         throw_ub!(ValidationFailure(msg))
     }};
 }
 
 macro_rules! try_validation {
-    ($e:expr, $what:expr, $where:expr, $details:expr) => {{
-        match $e {
-            Ok(x) => x,
-            // We re-throw the error, so we are okay with allocation:
-            // this can only slow down builds that fail anyway.
-            Err(_) => throw_validation_failure!($what, $where, $details),
-        }
-    }};
-
-    ($e:expr, $what:expr, $where:expr) => {{
+    ($e:expr, $what:expr, $where:expr $(, $details:expr )?) => {{
         match $e {
             Ok(x) => x,
-            // We re-throw the error, so we are okay with allocation:
-            // this can only slow down builds that fail anyway.
-            Err(_) => throw_validation_failure!($what, $where),
+            // We catch the error and turn it into a validation failure. We are okay with
+            // allocation here as this can only slow down builds that fail anyway.
+            Err(_) => throw_validation_failure!($what, $where $(, $details)?),
         }
     }};
 }

From 326d38fa09cfdf9e611b8828604a7a05c7f55c85 Mon Sep 17 00:00:00 2001
From: jumbatm <jumbatm@gmail.com>
Date: Thu, 23 Apr 2020 22:00:06 +1000
Subject: [PATCH 02/19] Add try_validation_pat.

---
 src/librustc_mir/interpret/validity.rs | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index 0b6422316ead7..1e4c9367f6a6c 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -36,6 +36,7 @@ macro_rules! throw_validation_failure {
     }};
 }
 
+/// Returns a validation failure for any Err value of $e.
 macro_rules! try_validation {
     ($e:expr, $what:expr, $where:expr $(, $details:expr )?) => {{
         match $e {
@@ -46,6 +47,24 @@ macro_rules! try_validation {
         }
     }};
 }
+/// Like try_validation, but will throw a validation error if any of the patterns in $p are
+/// matched. Other errors are passed back to the caller, unchanged. This lets you use the patterns
+/// as a kind of validation blacklist:
+///
+/// ```rust
+/// let v = try_validation_pat(some_fn(), Foo | Bar | Baz, "some failure", "some place");
+/// // Failures that match $p are thrown up as validation errors, but other errors are passed back
+/// // unchanged.
+/// ```
+macro_rules! try_validation_pat {
+    ($e:expr, $( $p:pat )|*, $what:expr, $where:expr $(, $details:expr )?) => {{
+        match $e {
+            Ok(x) => x,
+            $( Err($p) )|* if true => throw_validation_failure!($what, $where $(, $details)?),
+            Err(e) =>  Err::<!, _>(e)?,
+        }
+    }};
+}
 
 /// We want to show a nice path to the invalid field for diagnostics,
 /// but avoid string operations in the happy case where no error happens.
@@ -474,8 +493,9 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
                 // We are conservative with undef for integers, but try to
                 // actually enforce the strict rules for raw pointers (mostly because
                 // that lets us re-use `ref_to_mplace`).
-                let place = try_validation!(
+                let place = try_validation_pat!(
                     self.ecx.ref_to_mplace(self.ecx.read_immediate(value)?),
+                    _,
                     "uninitialized raw pointer",
                     self.path
                 );

From e66e37cbf1806f4e0b7a9e6935c8198b3a6c4b2f Mon Sep 17 00:00:00 2001
From: jumbatm <jumbatm@gmail.com>
Date: Thu, 23 Apr 2020 22:52:27 +1000
Subject: [PATCH 03/19] Don't duplicate body of try_validation.

---
 src/librustc_mir/interpret/validity.rs | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index 1e4c9367f6a6c..42cdb1dc2a651 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -39,12 +39,7 @@ macro_rules! throw_validation_failure {
 /// Returns a validation failure for any Err value of $e.
 macro_rules! try_validation {
     ($e:expr, $what:expr, $where:expr $(, $details:expr )?) => {{
-        match $e {
-            Ok(x) => x,
-            // We catch the error and turn it into a validation failure. We are okay with
-            // allocation here as this can only slow down builds that fail anyway.
-            Err(_) => throw_validation_failure!($what, $where $(, $details)?),
-        }
+        try_validation_pat!($e, _, $what, $where $(, $details )?)
     }};
 }
 /// Like try_validation, but will throw a validation error if any of the patterns in $p are
@@ -60,6 +55,8 @@ macro_rules! try_validation_pat {
     ($e:expr, $( $p:pat )|*, $what:expr, $where:expr $(, $details:expr )?) => {{
         match $e {
             Ok(x) => x,
+            // We catch the error and turn it into a validation failure. We are okay with
+            // allocation here as this can only slow down builds that fail anyway.
             $( Err($p) )|* if true => throw_validation_failure!($what, $where $(, $details)?),
             Err(e) =>  Err::<!, _>(e)?,
         }

From bc7b7140b9a5ea4e764c9f53a915d26baa4326be Mon Sep 17 00:00:00 2001
From: jumbatm <jumbatm@gmail.com>
Date: Wed, 29 Apr 2020 09:45:13 +1000
Subject: [PATCH 04/19] Don't fail for UndefinedBehaviourInfo in validation.

---
 src/librustc_mir/interpret/validity.rs | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index 42cdb1dc2a651..d6202638fd912 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -842,9 +842,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         // Run it.
         match visitor.visit_value(op) {
             Ok(()) => Ok(()),
-            // We should only get validation errors here. Avoid other errors as
-            // those do not show *where* in the value the issue lies.
+            // Allow validation failures to be returned.
             Err(err) if matches!(err.kind, err_ub!(ValidationFailure { .. })) => Err(err),
+            // Also allow InvalidProgram to be returned, because it's likely that different callers
+            // will want to do different things in this situation.
+            Err(err) if matches!(err.kind, InterpError::InvalidProgram(_)) => Err(err),
+            // Avoid other errors as those do not show *where* in the value the issue lies.
             Err(err) => bug!("Unexpected error during validation: {}", err),
         }
     }

From 6b413d95fc3035fff80c0388049d5b7c178a3c59 Mon Sep 17 00:00:00 2001
From: jumbatm <jumbatm@gmail.com>
Date: Wed, 29 Apr 2020 09:41:01 +1000
Subject: [PATCH 05/19] Throw validation failure for InvalidUndefBytes.

---
 src/librustc_mir/interpret/validity.rs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index d6202638fd912..ab440cc5ebab8 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -11,6 +11,7 @@ use std::ops::RangeInclusive;
 
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
+use rustc_middle::mir::interpret::{InterpError, InterpErrorInfo};
 use rustc_middle::ty;
 use rustc_middle::ty::layout::TyAndLayout;
 use rustc_span::symbol::{sym, Symbol};
@@ -492,7 +493,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
                 // that lets us re-use `ref_to_mplace`).
                 let place = try_validation_pat!(
                     self.ecx.ref_to_mplace(self.ecx.read_immediate(value)?),
-                    _,
+                    InterpErrorInfo { kind: err_ub!(InvalidUndefBytes(..)), ..},
                     "uninitialized raw pointer",
                     self.path
                 );

From 2887d7923ebac8a1bed6e019550c177e3f2fa6b6 Mon Sep 17 00:00:00 2001
From: jumbatm <jumbatm@gmail.com>
Date: Wed, 29 Apr 2020 19:35:45 +1000
Subject: [PATCH 06/19] Partially unrevert #70566.

This partially reverts commit 4b5b6cbe60a8dd1822cfa46c41cf1ad58c113e18,
reversing some changes made to 62b362472dbf8bdf43b252ac5ea53b527a8dbee3.
---
 src/librustc_mir/transform/const_prop.rs      | 10 +--
 .../lint-exceeding-bitshifts.noopt.stderr     | 62 ++++++++++---------
 .../lint/lint-exceeding-bitshifts.opt.stderr  | 62 ++++++++++---------
 ...-bitshifts.opt_with_overflow_checks.stderr | 62 ++++++++++---------
 src/test/ui/lint/lint-exceeding-bitshifts.rs  | 53 ++++++++--------
 5 files changed, 133 insertions(+), 116 deletions(-)

diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index 09d8f89676a66..1573769a1570c 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -549,11 +549,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
             return None;
         }
 
-        // FIXME we need to revisit this for #67176
-        if rvalue.needs_subst() {
-            return None;
-        }
-
         // Perform any special handling for specific Rvalue types.
         // Generally, checks here fall into one of two categories:
         //   1. Additional checking to provide useful lints to the user
@@ -594,6 +589,11 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
             _ => {}
         }
 
+        // FIXME we need to revisit this for #67176
+        if rvalue.needs_subst() {
+            return None;
+        }
+
         self.use_ecx(|this| {
             trace!("calling eval_rvalue_into_place(rvalue = {:?}, place = {:?})", rvalue, place);
             this.ecx.eval_rvalue_into_place(rvalue, place)?;
diff --git a/src/test/ui/lint/lint-exceeding-bitshifts.noopt.stderr b/src/test/ui/lint/lint-exceeding-bitshifts.noopt.stderr
index ce9b02b6d82a7..a2fb5ad8b8b8b 100644
--- a/src/test/ui/lint/lint-exceeding-bitshifts.noopt.stderr
+++ b/src/test/ui/lint/lint-exceeding-bitshifts.noopt.stderr
@@ -1,146 +1,152 @@
-error: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:22:13
+warning: this arithmetic operation will overflow
+  --> $DIR/lint-exceeding-bitshifts.rs:18:20
    |
-LL |     let _ = x << 42;
-   |             ^^^^^^^ attempt to shift left with overflow
+LL |     const N: i32 = T::N << 42;
+   |                    ^^^^^^^^^^ attempt to shift left with overflow
    |
 note: the lint level is defined here
   --> $DIR/lint-exceeding-bitshifts.rs:9:9
    |
-LL | #![deny(arithmetic_overflow, const_err)]
+LL | #![warn(arithmetic_overflow, const_err)]
    |         ^^^^^^^^^^^^^^^^^^^
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
+  --> $DIR/lint-exceeding-bitshifts.rs:22:13
+   |
+LL |     let _ = x << 42;
+   |             ^^^^^^^ attempt to shift left with overflow
+
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:27:15
    |
 LL |       let n = 1u8 << 8;
    |               ^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:29:15
    |
 LL |       let n = 1u16 << 16;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:31:15
    |
 LL |       let n = 1u32 << 32;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:33:15
    |
 LL |       let n = 1u64 << 64;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:35:15
    |
 LL |       let n = 1i8 << 8;
    |               ^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:37:15
    |
 LL |       let n = 1i16 << 16;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:39:15
    |
 LL |       let n = 1i32 << 32;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:41:15
    |
 LL |       let n = 1i64 << 64;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:44:15
    |
 LL |       let n = 1u8 >> 8;
    |               ^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:46:15
    |
 LL |       let n = 1u16 >> 16;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:48:15
    |
 LL |       let n = 1u32 >> 32;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:50:15
    |
 LL |       let n = 1u64 >> 64;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:52:15
    |
 LL |       let n = 1i8 >> 8;
    |               ^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:54:15
    |
 LL |       let n = 1i16 >> 16;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:56:15
    |
 LL |       let n = 1i32 >> 32;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:58:15
    |
 LL |       let n = 1i64 >> 64;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:62:15
    |
 LL |       let n = n << 8;
    |               ^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:64:15
    |
 LL |       let n = 1u8 << -8;
    |               ^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:69:15
    |
 LL |       let n = 1u8 << (4+4);
    |               ^^^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:71:15
    |
 LL |       let n = 1i64 >> [64][0];
    |               ^^^^^^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:77:15
    |
 LL |       let n = 1_isize << BITS;
    |               ^^^^^^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:78:15
    |
 LL |       let n = 1_usize << BITS;
    |               ^^^^^^^^^^^^^^^ attempt to shift left with overflow
 
-error: aborting due to 23 previous errors
+warning: 24 warnings emitted
 
diff --git a/src/test/ui/lint/lint-exceeding-bitshifts.opt.stderr b/src/test/ui/lint/lint-exceeding-bitshifts.opt.stderr
index ce9b02b6d82a7..a2fb5ad8b8b8b 100644
--- a/src/test/ui/lint/lint-exceeding-bitshifts.opt.stderr
+++ b/src/test/ui/lint/lint-exceeding-bitshifts.opt.stderr
@@ -1,146 +1,152 @@
-error: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:22:13
+warning: this arithmetic operation will overflow
+  --> $DIR/lint-exceeding-bitshifts.rs:18:20
    |
-LL |     let _ = x << 42;
-   |             ^^^^^^^ attempt to shift left with overflow
+LL |     const N: i32 = T::N << 42;
+   |                    ^^^^^^^^^^ attempt to shift left with overflow
    |
 note: the lint level is defined here
   --> $DIR/lint-exceeding-bitshifts.rs:9:9
    |
-LL | #![deny(arithmetic_overflow, const_err)]
+LL | #![warn(arithmetic_overflow, const_err)]
    |         ^^^^^^^^^^^^^^^^^^^
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
+  --> $DIR/lint-exceeding-bitshifts.rs:22:13
+   |
+LL |     let _ = x << 42;
+   |             ^^^^^^^ attempt to shift left with overflow
+
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:27:15
    |
 LL |       let n = 1u8 << 8;
    |               ^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:29:15
    |
 LL |       let n = 1u16 << 16;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:31:15
    |
 LL |       let n = 1u32 << 32;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:33:15
    |
 LL |       let n = 1u64 << 64;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:35:15
    |
 LL |       let n = 1i8 << 8;
    |               ^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:37:15
    |
 LL |       let n = 1i16 << 16;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:39:15
    |
 LL |       let n = 1i32 << 32;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:41:15
    |
 LL |       let n = 1i64 << 64;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:44:15
    |
 LL |       let n = 1u8 >> 8;
    |               ^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:46:15
    |
 LL |       let n = 1u16 >> 16;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:48:15
    |
 LL |       let n = 1u32 >> 32;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:50:15
    |
 LL |       let n = 1u64 >> 64;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:52:15
    |
 LL |       let n = 1i8 >> 8;
    |               ^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:54:15
    |
 LL |       let n = 1i16 >> 16;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:56:15
    |
 LL |       let n = 1i32 >> 32;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:58:15
    |
 LL |       let n = 1i64 >> 64;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:62:15
    |
 LL |       let n = n << 8;
    |               ^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:64:15
    |
 LL |       let n = 1u8 << -8;
    |               ^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:69:15
    |
 LL |       let n = 1u8 << (4+4);
    |               ^^^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:71:15
    |
 LL |       let n = 1i64 >> [64][0];
    |               ^^^^^^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:77:15
    |
 LL |       let n = 1_isize << BITS;
    |               ^^^^^^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:78:15
    |
 LL |       let n = 1_usize << BITS;
    |               ^^^^^^^^^^^^^^^ attempt to shift left with overflow
 
-error: aborting due to 23 previous errors
+warning: 24 warnings emitted
 
diff --git a/src/test/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr b/src/test/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr
index ce9b02b6d82a7..a2fb5ad8b8b8b 100644
--- a/src/test/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr
+++ b/src/test/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr
@@ -1,146 +1,152 @@
-error: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:22:13
+warning: this arithmetic operation will overflow
+  --> $DIR/lint-exceeding-bitshifts.rs:18:20
    |
-LL |     let _ = x << 42;
-   |             ^^^^^^^ attempt to shift left with overflow
+LL |     const N: i32 = T::N << 42;
+   |                    ^^^^^^^^^^ attempt to shift left with overflow
    |
 note: the lint level is defined here
   --> $DIR/lint-exceeding-bitshifts.rs:9:9
    |
-LL | #![deny(arithmetic_overflow, const_err)]
+LL | #![warn(arithmetic_overflow, const_err)]
    |         ^^^^^^^^^^^^^^^^^^^
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
+  --> $DIR/lint-exceeding-bitshifts.rs:22:13
+   |
+LL |     let _ = x << 42;
+   |             ^^^^^^^ attempt to shift left with overflow
+
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:27:15
    |
 LL |       let n = 1u8 << 8;
    |               ^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:29:15
    |
 LL |       let n = 1u16 << 16;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:31:15
    |
 LL |       let n = 1u32 << 32;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:33:15
    |
 LL |       let n = 1u64 << 64;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:35:15
    |
 LL |       let n = 1i8 << 8;
    |               ^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:37:15
    |
 LL |       let n = 1i16 << 16;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:39:15
    |
 LL |       let n = 1i32 << 32;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:41:15
    |
 LL |       let n = 1i64 << 64;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:44:15
    |
 LL |       let n = 1u8 >> 8;
    |               ^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:46:15
    |
 LL |       let n = 1u16 >> 16;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:48:15
    |
 LL |       let n = 1u32 >> 32;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:50:15
    |
 LL |       let n = 1u64 >> 64;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:52:15
    |
 LL |       let n = 1i8 >> 8;
    |               ^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:54:15
    |
 LL |       let n = 1i16 >> 16;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:56:15
    |
 LL |       let n = 1i32 >> 32;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:58:15
    |
 LL |       let n = 1i64 >> 64;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:62:15
    |
 LL |       let n = n << 8;
    |               ^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:64:15
    |
 LL |       let n = 1u8 << -8;
    |               ^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:69:15
    |
 LL |       let n = 1u8 << (4+4);
    |               ^^^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:71:15
    |
 LL |       let n = 1i64 >> [64][0];
    |               ^^^^^^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:77:15
    |
 LL |       let n = 1_isize << BITS;
    |               ^^^^^^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:78:15
    |
 LL |       let n = 1_usize << BITS;
    |               ^^^^^^^^^^^^^^^ attempt to shift left with overflow
 
-error: aborting due to 23 previous errors
+warning: 24 warnings emitted
 
diff --git a/src/test/ui/lint/lint-exceeding-bitshifts.rs b/src/test/ui/lint/lint-exceeding-bitshifts.rs
index 7deee5320a878..565bef49c9f8c 100644
--- a/src/test/ui/lint/lint-exceeding-bitshifts.rs
+++ b/src/test/ui/lint/lint-exceeding-bitshifts.rs
@@ -2,11 +2,10 @@
 //[noopt]compile-flags: -C opt-level=0
 //[opt]compile-flags: -O
 //[opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O
-
-// build-fail
+// build-pass
 
 #![crate_type="lib"]
-#![deny(arithmetic_overflow, const_err)]
+#![warn(arithmetic_overflow, const_err)]
 #![allow(unused_variables)]
 #![allow(dead_code)]
 
@@ -15,65 +14,65 @@ pub trait Foo {
 }
 
 impl<T: Foo> Foo for Vec<T> {
-    const N: i32 = T::N << 42; // FIXME this should warn
+    const N: i32 = T::N << 42; //~ WARN: arithmetic operation will overflow
 }
 
 pub fn foo(x: i32) {
-    let _ = x << 42; //~ ERROR: arithmetic operation will overflow
+    let _ = x << 42; //~ WARN: arithmetic operation will overflow
 }
 
 pub fn main() {
       let n = 1u8 << 7;
-      let n = 1u8 << 8;   //~ ERROR: arithmetic operation will overflow
+      let n = 1u8 << 8;   //~ WARN: arithmetic operation will overflow
       let n = 1u16 << 15;
-      let n = 1u16 << 16; //~ ERROR: arithmetic operation will overflow
+      let n = 1u16 << 16; //~ WARN: arithmetic operation will overflow
       let n = 1u32 << 31;
-      let n = 1u32 << 32; //~ ERROR: arithmetic operation will overflow
+      let n = 1u32 << 32; //~ WARN: arithmetic operation will overflow
       let n = 1u64 << 63;
-      let n = 1u64 << 64; //~ ERROR: arithmetic operation will overflow
+      let n = 1u64 << 64; //~ WARN: arithmetic operation will overflow
       let n = 1i8 << 7;
-      let n = 1i8 << 8;   //~ ERROR: arithmetic operation will overflow
+      let n = 1i8 << 8;   //~ WARN: arithmetic operation will overflow
       let n = 1i16 << 15;
-      let n = 1i16 << 16; //~ ERROR: arithmetic operation will overflow
+      let n = 1i16 << 16; //~ WARN: arithmetic operation will overflow
       let n = 1i32 << 31;
-      let n = 1i32 << 32; //~ ERROR: arithmetic operation will overflow
+      let n = 1i32 << 32; //~ WARN: arithmetic operation will overflow
       let n = 1i64 << 63;
-      let n = 1i64 << 64; //~ ERROR: arithmetic operation will overflow
+      let n = 1i64 << 64; //~ WARN: arithmetic operation will overflow
 
       let n = 1u8 >> 7;
-      let n = 1u8 >> 8;   //~ ERROR: arithmetic operation will overflow
+      let n = 1u8 >> 8;   //~ WARN: arithmetic operation will overflow
       let n = 1u16 >> 15;
-      let n = 1u16 >> 16; //~ ERROR: arithmetic operation will overflow
+      let n = 1u16 >> 16; //~ WARN: arithmetic operation will overflow
       let n = 1u32 >> 31;
-      let n = 1u32 >> 32; //~ ERROR: arithmetic operation will overflow
+      let n = 1u32 >> 32; //~ WARN: arithmetic operation will overflow
       let n = 1u64 >> 63;
-      let n = 1u64 >> 64; //~ ERROR: arithmetic operation will overflow
+      let n = 1u64 >> 64; //~ WARN: arithmetic operation will overflow
       let n = 1i8 >> 7;
-      let n = 1i8 >> 8;   //~ ERROR: arithmetic operation will overflow
+      let n = 1i8 >> 8;   //~ WARN: arithmetic operation will overflow
       let n = 1i16 >> 15;
-      let n = 1i16 >> 16; //~ ERROR: arithmetic operation will overflow
+      let n = 1i16 >> 16; //~ WARN: arithmetic operation will overflow
       let n = 1i32 >> 31;
-      let n = 1i32 >> 32; //~ ERROR: arithmetic operation will overflow
+      let n = 1i32 >> 32; //~ WARN: arithmetic operation will overflow
       let n = 1i64 >> 63;
-      let n = 1i64 >> 64; //~ ERROR: arithmetic operation will overflow
+      let n = 1i64 >> 64; //~ WARN: arithmetic operation will overflow
 
       let n = 1u8;
       let n = n << 7;
-      let n = n << 8; //~ ERROR: arithmetic operation will overflow
+      let n = n << 8; //~ WARN: arithmetic operation will overflow
 
-      let n = 1u8 << -8; //~ ERROR: 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); //~ ERROR: arithmetic operation will overflow
+      let n = 1u8 << (4+4); //~ WARN: arithmetic operation will overflow
       let n = 1i64 >> [63][0];
-      let n = 1i64 >> [64][0]; //~ ERROR: arithmetic operation will overflow
+      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; //~ ERROR: arithmetic operation will overflow
-      let n = 1_usize << BITS; //~ ERROR: arithmetic operation will overflow
+      let n = 1_isize << BITS; //~ WARN: arithmetic operation will overflow
+      let n = 1_usize << BITS; //~ WARN: arithmetic operation will overflow
 }

From 5b1d6000a0095c81aeabee22f09f38110960415b Mon Sep 17 00:00:00 2001
From: jumbatm <jumbatm@gmail.com>
Date: Fri, 1 May 2020 20:09:09 +1000
Subject: [PATCH 07/19] Update stderrs.

---
 .../lint-exceeding-bitshifts.noopt.stderr     | 50 +++++++++----------
 .../lint/lint-exceeding-bitshifts.opt.stderr  | 50 +++++++++----------
 ...-bitshifts.opt_with_overflow_checks.stderr | 50 +++++++++----------
 3 files changed, 75 insertions(+), 75 deletions(-)

diff --git a/src/test/ui/lint/lint-exceeding-bitshifts.noopt.stderr b/src/test/ui/lint/lint-exceeding-bitshifts.noopt.stderr
index a2fb5ad8b8b8b..0c328a2594a46 100644
--- a/src/test/ui/lint/lint-exceeding-bitshifts.noopt.stderr
+++ b/src/test/ui/lint/lint-exceeding-bitshifts.noopt.stderr
@@ -1,149 +1,149 @@
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:18:20
+  --> $DIR/lint-exceeding-bitshifts.rs:17:20
    |
 LL |     const N: i32 = T::N << 42;
    |                    ^^^^^^^^^^ attempt to shift left with overflow
    |
 note: the lint level is defined here
-  --> $DIR/lint-exceeding-bitshifts.rs:9:9
+  --> $DIR/lint-exceeding-bitshifts.rs:8:9
    |
 LL | #![warn(arithmetic_overflow, const_err)]
    |         ^^^^^^^^^^^^^^^^^^^
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:22:13
+  --> $DIR/lint-exceeding-bitshifts.rs:21:13
    |
 LL |     let _ = x << 42;
    |             ^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:27:15
+  --> $DIR/lint-exceeding-bitshifts.rs:26:15
    |
 LL |       let n = 1u8 << 8;
    |               ^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:29:15
+  --> $DIR/lint-exceeding-bitshifts.rs:28:15
    |
 LL |       let n = 1u16 << 16;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:31:15
+  --> $DIR/lint-exceeding-bitshifts.rs:30:15
    |
 LL |       let n = 1u32 << 32;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:33:15
+  --> $DIR/lint-exceeding-bitshifts.rs:32:15
    |
 LL |       let n = 1u64 << 64;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:35:15
+  --> $DIR/lint-exceeding-bitshifts.rs:34:15
    |
 LL |       let n = 1i8 << 8;
    |               ^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:37:15
+  --> $DIR/lint-exceeding-bitshifts.rs:36:15
    |
 LL |       let n = 1i16 << 16;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:39:15
+  --> $DIR/lint-exceeding-bitshifts.rs:38:15
    |
 LL |       let n = 1i32 << 32;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:41:15
+  --> $DIR/lint-exceeding-bitshifts.rs:40:15
    |
 LL |       let n = 1i64 << 64;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:44:15
+  --> $DIR/lint-exceeding-bitshifts.rs:43:15
    |
 LL |       let n = 1u8 >> 8;
    |               ^^^^^^^^ attempt to shift right with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:46:15
+  --> $DIR/lint-exceeding-bitshifts.rs:45:15
    |
 LL |       let n = 1u16 >> 16;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:48:15
+  --> $DIR/lint-exceeding-bitshifts.rs:47:15
    |
 LL |       let n = 1u32 >> 32;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:50:15
+  --> $DIR/lint-exceeding-bitshifts.rs:49:15
    |
 LL |       let n = 1u64 >> 64;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:52:15
+  --> $DIR/lint-exceeding-bitshifts.rs:51:15
    |
 LL |       let n = 1i8 >> 8;
    |               ^^^^^^^^ attempt to shift right with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:54:15
+  --> $DIR/lint-exceeding-bitshifts.rs:53:15
    |
 LL |       let n = 1i16 >> 16;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:56:15
+  --> $DIR/lint-exceeding-bitshifts.rs:55:15
    |
 LL |       let n = 1i32 >> 32;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:58:15
+  --> $DIR/lint-exceeding-bitshifts.rs:57:15
    |
 LL |       let n = 1i64 >> 64;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:62:15
+  --> $DIR/lint-exceeding-bitshifts.rs:61:15
    |
 LL |       let n = n << 8;
    |               ^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:64:15
+  --> $DIR/lint-exceeding-bitshifts.rs:63:15
    |
 LL |       let n = 1u8 << -8;
    |               ^^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:69:15
+  --> $DIR/lint-exceeding-bitshifts.rs:68:15
    |
 LL |       let n = 1u8 << (4+4);
    |               ^^^^^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:71:15
+  --> $DIR/lint-exceeding-bitshifts.rs:70:15
    |
 LL |       let n = 1i64 >> [64][0];
    |               ^^^^^^^^^^^^^^^ attempt to shift right with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:77:15
+  --> $DIR/lint-exceeding-bitshifts.rs:76:15
    |
 LL |       let n = 1_isize << BITS;
    |               ^^^^^^^^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:78:15
+  --> $DIR/lint-exceeding-bitshifts.rs:77:15
    |
 LL |       let n = 1_usize << BITS;
    |               ^^^^^^^^^^^^^^^ attempt to shift left with overflow
diff --git a/src/test/ui/lint/lint-exceeding-bitshifts.opt.stderr b/src/test/ui/lint/lint-exceeding-bitshifts.opt.stderr
index a2fb5ad8b8b8b..0c328a2594a46 100644
--- a/src/test/ui/lint/lint-exceeding-bitshifts.opt.stderr
+++ b/src/test/ui/lint/lint-exceeding-bitshifts.opt.stderr
@@ -1,149 +1,149 @@
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:18:20
+  --> $DIR/lint-exceeding-bitshifts.rs:17:20
    |
 LL |     const N: i32 = T::N << 42;
    |                    ^^^^^^^^^^ attempt to shift left with overflow
    |
 note: the lint level is defined here
-  --> $DIR/lint-exceeding-bitshifts.rs:9:9
+  --> $DIR/lint-exceeding-bitshifts.rs:8:9
    |
 LL | #![warn(arithmetic_overflow, const_err)]
    |         ^^^^^^^^^^^^^^^^^^^
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:22:13
+  --> $DIR/lint-exceeding-bitshifts.rs:21:13
    |
 LL |     let _ = x << 42;
    |             ^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:27:15
+  --> $DIR/lint-exceeding-bitshifts.rs:26:15
    |
 LL |       let n = 1u8 << 8;
    |               ^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:29:15
+  --> $DIR/lint-exceeding-bitshifts.rs:28:15
    |
 LL |       let n = 1u16 << 16;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:31:15
+  --> $DIR/lint-exceeding-bitshifts.rs:30:15
    |
 LL |       let n = 1u32 << 32;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:33:15
+  --> $DIR/lint-exceeding-bitshifts.rs:32:15
    |
 LL |       let n = 1u64 << 64;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:35:15
+  --> $DIR/lint-exceeding-bitshifts.rs:34:15
    |
 LL |       let n = 1i8 << 8;
    |               ^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:37:15
+  --> $DIR/lint-exceeding-bitshifts.rs:36:15
    |
 LL |       let n = 1i16 << 16;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:39:15
+  --> $DIR/lint-exceeding-bitshifts.rs:38:15
    |
 LL |       let n = 1i32 << 32;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:41:15
+  --> $DIR/lint-exceeding-bitshifts.rs:40:15
    |
 LL |       let n = 1i64 << 64;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:44:15
+  --> $DIR/lint-exceeding-bitshifts.rs:43:15
    |
 LL |       let n = 1u8 >> 8;
    |               ^^^^^^^^ attempt to shift right with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:46:15
+  --> $DIR/lint-exceeding-bitshifts.rs:45:15
    |
 LL |       let n = 1u16 >> 16;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:48:15
+  --> $DIR/lint-exceeding-bitshifts.rs:47:15
    |
 LL |       let n = 1u32 >> 32;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:50:15
+  --> $DIR/lint-exceeding-bitshifts.rs:49:15
    |
 LL |       let n = 1u64 >> 64;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:52:15
+  --> $DIR/lint-exceeding-bitshifts.rs:51:15
    |
 LL |       let n = 1i8 >> 8;
    |               ^^^^^^^^ attempt to shift right with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:54:15
+  --> $DIR/lint-exceeding-bitshifts.rs:53:15
    |
 LL |       let n = 1i16 >> 16;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:56:15
+  --> $DIR/lint-exceeding-bitshifts.rs:55:15
    |
 LL |       let n = 1i32 >> 32;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:58:15
+  --> $DIR/lint-exceeding-bitshifts.rs:57:15
    |
 LL |       let n = 1i64 >> 64;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:62:15
+  --> $DIR/lint-exceeding-bitshifts.rs:61:15
    |
 LL |       let n = n << 8;
    |               ^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:64:15
+  --> $DIR/lint-exceeding-bitshifts.rs:63:15
    |
 LL |       let n = 1u8 << -8;
    |               ^^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:69:15
+  --> $DIR/lint-exceeding-bitshifts.rs:68:15
    |
 LL |       let n = 1u8 << (4+4);
    |               ^^^^^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:71:15
+  --> $DIR/lint-exceeding-bitshifts.rs:70:15
    |
 LL |       let n = 1i64 >> [64][0];
    |               ^^^^^^^^^^^^^^^ attempt to shift right with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:77:15
+  --> $DIR/lint-exceeding-bitshifts.rs:76:15
    |
 LL |       let n = 1_isize << BITS;
    |               ^^^^^^^^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:78:15
+  --> $DIR/lint-exceeding-bitshifts.rs:77:15
    |
 LL |       let n = 1_usize << BITS;
    |               ^^^^^^^^^^^^^^^ attempt to shift left with overflow
diff --git a/src/test/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr b/src/test/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr
index a2fb5ad8b8b8b..0c328a2594a46 100644
--- a/src/test/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr
+++ b/src/test/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr
@@ -1,149 +1,149 @@
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:18:20
+  --> $DIR/lint-exceeding-bitshifts.rs:17:20
    |
 LL |     const N: i32 = T::N << 42;
    |                    ^^^^^^^^^^ attempt to shift left with overflow
    |
 note: the lint level is defined here
-  --> $DIR/lint-exceeding-bitshifts.rs:9:9
+  --> $DIR/lint-exceeding-bitshifts.rs:8:9
    |
 LL | #![warn(arithmetic_overflow, const_err)]
    |         ^^^^^^^^^^^^^^^^^^^
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:22:13
+  --> $DIR/lint-exceeding-bitshifts.rs:21:13
    |
 LL |     let _ = x << 42;
    |             ^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:27:15
+  --> $DIR/lint-exceeding-bitshifts.rs:26:15
    |
 LL |       let n = 1u8 << 8;
    |               ^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:29:15
+  --> $DIR/lint-exceeding-bitshifts.rs:28:15
    |
 LL |       let n = 1u16 << 16;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:31:15
+  --> $DIR/lint-exceeding-bitshifts.rs:30:15
    |
 LL |       let n = 1u32 << 32;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:33:15
+  --> $DIR/lint-exceeding-bitshifts.rs:32:15
    |
 LL |       let n = 1u64 << 64;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:35:15
+  --> $DIR/lint-exceeding-bitshifts.rs:34:15
    |
 LL |       let n = 1i8 << 8;
    |               ^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:37:15
+  --> $DIR/lint-exceeding-bitshifts.rs:36:15
    |
 LL |       let n = 1i16 << 16;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:39:15
+  --> $DIR/lint-exceeding-bitshifts.rs:38:15
    |
 LL |       let n = 1i32 << 32;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:41:15
+  --> $DIR/lint-exceeding-bitshifts.rs:40:15
    |
 LL |       let n = 1i64 << 64;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:44:15
+  --> $DIR/lint-exceeding-bitshifts.rs:43:15
    |
 LL |       let n = 1u8 >> 8;
    |               ^^^^^^^^ attempt to shift right with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:46:15
+  --> $DIR/lint-exceeding-bitshifts.rs:45:15
    |
 LL |       let n = 1u16 >> 16;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:48:15
+  --> $DIR/lint-exceeding-bitshifts.rs:47:15
    |
 LL |       let n = 1u32 >> 32;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:50:15
+  --> $DIR/lint-exceeding-bitshifts.rs:49:15
    |
 LL |       let n = 1u64 >> 64;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:52:15
+  --> $DIR/lint-exceeding-bitshifts.rs:51:15
    |
 LL |       let n = 1i8 >> 8;
    |               ^^^^^^^^ attempt to shift right with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:54:15
+  --> $DIR/lint-exceeding-bitshifts.rs:53:15
    |
 LL |       let n = 1i16 >> 16;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:56:15
+  --> $DIR/lint-exceeding-bitshifts.rs:55:15
    |
 LL |       let n = 1i32 >> 32;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:58:15
+  --> $DIR/lint-exceeding-bitshifts.rs:57:15
    |
 LL |       let n = 1i64 >> 64;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:62:15
+  --> $DIR/lint-exceeding-bitshifts.rs:61:15
    |
 LL |       let n = n << 8;
    |               ^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:64:15
+  --> $DIR/lint-exceeding-bitshifts.rs:63:15
    |
 LL |       let n = 1u8 << -8;
    |               ^^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:69:15
+  --> $DIR/lint-exceeding-bitshifts.rs:68:15
    |
 LL |       let n = 1u8 << (4+4);
    |               ^^^^^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:71:15
+  --> $DIR/lint-exceeding-bitshifts.rs:70:15
    |
 LL |       let n = 1i64 >> [64][0];
    |               ^^^^^^^^^^^^^^^ attempt to shift right with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:77:15
+  --> $DIR/lint-exceeding-bitshifts.rs:76:15
    |
 LL |       let n = 1_isize << BITS;
    |               ^^^^^^^^^^^^^^^ attempt to shift left with overflow
 
 warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:78:15
+  --> $DIR/lint-exceeding-bitshifts.rs:77:15
    |
 LL |       let n = 1_usize << BITS;
    |               ^^^^^^^^^^^^^^^ attempt to shift left with overflow

From 894a83d4098a5b390484473ab8608fdd113ff9ba Mon Sep 17 00:00:00 2001
From: jumbatm <jumbatm@gmail.com>
Date: Thu, 30 Apr 2020 14:38:02 +1000
Subject: [PATCH 08/19] Apply suggestions from code review

Co-Authored-By: Ralf Jung <post@ralfj.de>
Co-Authored-By: Oliver Scherer <github35764891676564198441@oli-obk.de>
---
 src/librustc_mir/interpret/validity.rs | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index ab440cc5ebab8..ac05b3b1ff498 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -48,7 +48,7 @@ macro_rules! try_validation {
 /// as a kind of validation blacklist:
 ///
 /// ```rust
-/// let v = try_validation_pat(some_fn(), Foo | Bar | Baz, "some failure", "some place");
+/// let v = try_validation_pat(some_fn(), Foo | Bar | Baz, "some failure", path);
 /// // Failures that match $p are thrown up as validation errors, but other errors are passed back
 /// // unchanged.
 /// ```
@@ -59,7 +59,7 @@ macro_rules! try_validation_pat {
             // We catch the error and turn it into a validation failure. We are okay with
             // allocation here as this can only slow down builds that fail anyway.
             $( Err($p) )|* if true => throw_validation_failure!($what, $where $(, $details)?),
-            Err(e) =>  Err::<!, _>(e)?,
+            Err(e) => Err::<!, _>(e)?,
         }
     }};
 }
@@ -843,10 +843,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         // Run it.
         match visitor.visit_value(op) {
             Ok(()) => Ok(()),
-            // Allow validation failures to be returned.
+            // Pass through validation failures.
             Err(err) if matches!(err.kind, err_ub!(ValidationFailure { .. })) => Err(err),
-            // Also allow InvalidProgram to be returned, because it's likely that different callers
-            // will want to do different things in this situation.
+            // Also pass through InvalidProgram, those just indicate that we could not
+            // validate and each caller will know best what to do with them.
             Err(err) if matches!(err.kind, InterpError::InvalidProgram(_)) => Err(err),
             // Avoid other errors as those do not show *where* in the value the issue lies.
             Err(err) => bug!("Unexpected error during validation: {}", err),

From 656ab7639737bd406591a4198633cd3ab0ad0c41 Mon Sep 17 00:00:00 2001
From: jumbatm <jumbatm@gmail.com>
Date: Thu, 30 Apr 2020 00:00:08 +1000
Subject: [PATCH 09/19] Add FIXME about replacing all usages of try_validation.

---
 src/librustc_mir/interpret/validity.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index ac05b3b1ff498..80e39e83d47e8 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -38,6 +38,7 @@ macro_rules! throw_validation_failure {
 }
 
 /// Returns a validation failure for any Err value of $e.
+// FIXME: Replace all usages of try_validation! with try_validation_pat!.
 macro_rules! try_validation {
     ($e:expr, $what:expr, $where:expr $(, $details:expr )?) => {{
         try_validation_pat!($e, _, $what, $where $(, $details )?)

From eca147896f2582d1dc7735fd238956082ea92280 Mon Sep 17 00:00:00 2001
From: jumbatm <jumbatm@gmail.com>
Date: Thu, 30 Apr 2020 09:47:58 +1000
Subject: [PATCH 10/19] Match kind in try_validation_pat!.

Avoids having to repeat InterpErrorInfo { .. }
---
 src/librustc_mir/interpret/validity.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index 80e39e83d47e8..d6f73fa2d0258 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -49,7 +49,7 @@ macro_rules! try_validation {
 /// as a kind of validation blacklist:
 ///
 /// ```rust
-/// let v = try_validation_pat(some_fn(), Foo | Bar | Baz, "some failure", path);
+/// let v = try_validation_pat!(some_fn(), Foo | Bar | Baz, "some failure", path);
 /// // Failures that match $p are thrown up as validation errors, but other errors are passed back
 /// // unchanged.
 /// ```
@@ -59,7 +59,7 @@ macro_rules! try_validation_pat {
             Ok(x) => x,
             // We catch the error and turn it into a validation failure. We are okay with
             // allocation here as this can only slow down builds that fail anyway.
-            $( Err($p) )|* if true => throw_validation_failure!($what, $where $(, $details)?),
+            $( Err(InterpErrorInfo { kind: $p, .. }) )|* if true => throw_validation_failure!($what, $where $(, $details)?),
             Err(e) => Err::<!, _>(e)?,
         }
     }};
@@ -494,7 +494,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
                 // that lets us re-use `ref_to_mplace`).
                 let place = try_validation_pat!(
                     self.ecx.ref_to_mplace(self.ecx.read_immediate(value)?),
-                    InterpErrorInfo { kind: err_ub!(InvalidUndefBytes(..)), ..},
+                    err_ub!(InvalidUndefBytes(..)),
                     "uninitialized raw pointer",
                     self.path
                 );

From 9c898d65b8e83adf56576616d120d33945a28409 Mon Sep 17 00:00:00 2001
From: jumbatm <jumbatm@gmail.com>
Date: Thu, 30 Apr 2020 09:54:26 +1000
Subject: [PATCH 11/19] Allow unreachable_patterns instead of using `if true`

---
 src/librustc_mir/interpret/validity.rs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index d6f73fa2d0258..262a01eab3ca6 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -59,7 +59,8 @@ macro_rules! try_validation_pat {
             Ok(x) => x,
             // We catch the error and turn it into a validation failure. We are okay with
             // allocation here as this can only slow down builds that fail anyway.
-            $( Err(InterpErrorInfo { kind: $p, .. }) )|* if true => throw_validation_failure!($what, $where $(, $details)?),
+            $( Err(InterpErrorInfo { kind: $p, .. }) )|* => throw_validation_failure!($what, $where $(, $details)?),
+            #[allow(unreachable_patterns)]
             Err(e) => Err::<!, _>(e)?,
         }
     }};

From 9459b3778009cf067b4ae0cae7c27de683b5ced5 Mon Sep 17 00:00:00 2001
From: jumbatm <jumbatm@gmail.com>
Date: Thu, 30 Apr 2020 13:01:36 +1000
Subject: [PATCH 12/19] Fix comment to reflect error handling behaviour.

---
 src/librustc_mir/interpret/validity.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index 262a01eab3ca6..b931ed61cdd2e 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -802,7 +802,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
 
                                 throw_validation_failure!("uninitialized bytes", self.path)
                             }
-                            // Other errors shouldn't be possible
+                            // Propagate upwards (that will also check for unexpected errors).
                             _ => return Err(err),
                         }
                     }

From cb96d41fa1961974aff9405aa323779d6b3d6849 Mon Sep 17 00:00:00 2001
From: jumbatm <jumbatm@gmail.com>
Date: Thu, 30 Apr 2020 15:22:40 +1000
Subject: [PATCH 13/19] Apply suggestions for try_validation_pat!.

---
 src/librustc_mir/interpret/validity.rs | 23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index b931ed61cdd2e..5192dfaa4043d 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -25,14 +25,14 @@ use super::{
 };
 
 macro_rules! throw_validation_failure {
-    ($what:expr, $where:expr $(, $details:expr )?) => {{
+    ($what:expr, $where:expr $(, $expected:expr )?) => {{
         let mut msg = format!("encountered {}", $what);
         let where_ = &$where;
         if !where_.is_empty() {
             msg.push_str(" at ");
             write_path(&mut msg, where_);
         }
-        $( write!(&mut msg, ", but expected {}", $details).unwrap(); )?
+        $( write!(&mut msg, ", but expected {}", $expected).unwrap(); )?
         throw_ub!(ValidationFailure(msg))
     }};
 }
@@ -40,8 +40,10 @@ macro_rules! throw_validation_failure {
 /// Returns a validation failure for any Err value of $e.
 // FIXME: Replace all usages of try_validation! with try_validation_pat!.
 macro_rules! try_validation {
-    ($e:expr, $what:expr, $where:expr $(, $details:expr )?) => {{
-        try_validation_pat!($e, _, $what, $where $(, $details )?)
+    ($e:expr, $what:expr, $where:expr $(, $expected:expr )?) => {{
+        try_validation_pat!($e, $where, {
+            _ => { $what } $( expected { $expected } )?,
+        })
     }};
 }
 /// Like try_validation, but will throw a validation error if any of the patterns in $p are
@@ -54,12 +56,12 @@ macro_rules! try_validation {
 /// // unchanged.
 /// ```
 macro_rules! try_validation_pat {
-    ($e:expr, $( $p:pat )|*, $what:expr, $where:expr $(, $details:expr )?) => {{
+    ($e:expr, $where:expr, { $( $p:pat )|* => { $what:tt } $( expected { $expected:expr } )? $( , )?}) => {{
         match $e {
             Ok(x) => x,
             // We catch the error and turn it into a validation failure. We are okay with
             // allocation here as this can only slow down builds that fail anyway.
-            $( Err(InterpErrorInfo { kind: $p, .. }) )|* => throw_validation_failure!($what, $where $(, $details)?),
+            $( Err(InterpErrorInfo { kind: $p, .. }) )|* => throw_validation_failure!($what, $where $(, $expected)?),
             #[allow(unreachable_patterns)]
             Err(e) => Err::<!, _>(e)?,
         }
@@ -493,12 +495,9 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
                 // We are conservative with undef for integers, but try to
                 // actually enforce the strict rules for raw pointers (mostly because
                 // that lets us re-use `ref_to_mplace`).
-                let place = try_validation_pat!(
-                    self.ecx.ref_to_mplace(self.ecx.read_immediate(value)?),
-                    err_ub!(InvalidUndefBytes(..)),
-                    "uninitialized raw pointer",
-                    self.path
-                );
+                let place = try_validation_pat!(self.ecx.ref_to_mplace(self.ecx.read_immediate(value)?), self.path, {
+                    err_ub!(InvalidUndefBytes(..)) => { "uninitialized raw pointer" },
+                });
                 if place.layout.is_unsized() {
                     self.check_wide_ptr_meta(place.meta, place.layout)?;
                 }

From 425a99f1eb233659403329fb4f117b1d39c7362c Mon Sep 17 00:00:00 2001
From: jumbatm <jumbatm@gmail.com>
Date: Fri, 1 May 2020 17:52:42 +1000
Subject: [PATCH 14/19] Update try_validation_pat! doc comment.

---
 src/librustc_mir/interpret/validity.rs | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index 5192dfaa4043d..c64458bd98944 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -50,11 +50,22 @@ macro_rules! try_validation {
 /// matched. Other errors are passed back to the caller, unchanged. This lets you use the patterns
 /// as a kind of validation blacklist:
 ///
-/// ```rust
-/// let v = try_validation_pat!(some_fn(), Foo | Bar | Baz, "some failure", path);
+/// ```
+/// let v = try_validation_pat!(some_fn(), some_path, {
+///     Foo | Bar | Baz => { "some failure" },
+/// });
 /// // Failures that match $p are thrown up as validation errors, but other errors are passed back
 /// // unchanged.
 /// ```
+///
+/// An additional expected parameter can also be added to the failure message:
+///
+/// ```
+/// let v = try_validation_pat!(some_fn(), some_path, {
+///     Foo | Bar | Baz => { "some failure" } expected { "something that wasn't a failure" },
+/// });
+/// ```
+///
 macro_rules! try_validation_pat {
     ($e:expr, $where:expr, { $( $p:pat )|* => { $what:tt } $( expected { $expected:expr } )? $( , )?}) => {{
         match $e {

From 65c36f6e386cd3fad6515e66ddc4721328ae6ef9 Mon Sep 17 00:00:00 2001
From: jumbatm <jumbatm@gmail.com>
Date: Fri, 1 May 2020 20:07:17 +1000
Subject: [PATCH 15/19] Wrap try_validation_pat! args in format_args!

---
 src/librustc_mir/interpret/validity.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index c64458bd98944..731f6e6aede37 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -42,7 +42,7 @@ macro_rules! throw_validation_failure {
 macro_rules! try_validation {
     ($e:expr, $what:expr, $where:expr $(, $expected:expr )?) => {{
         try_validation_pat!($e, $where, {
-            _ => { $what } $( expected { $expected } )?,
+            _ => { "{}", $what } $( expected { $expected } )?,
         })
     }};
 }
@@ -67,12 +67,12 @@ macro_rules! try_validation {
 /// ```
 ///
 macro_rules! try_validation_pat {
-    ($e:expr, $where:expr, { $( $p:pat )|* => { $what:tt } $( expected { $expected:expr } )? $( , )?}) => {{
+    ($e:expr, $where:expr, { $( $p:pat )|* => { $( $what_fmt:expr ),* } $( expected { $expected:expr } )? $( , )?}) => {{
         match $e {
             Ok(x) => x,
             // We catch the error and turn it into a validation failure. We are okay with
             // allocation here as this can only slow down builds that fail anyway.
-            $( Err(InterpErrorInfo { kind: $p, .. }) )|* => throw_validation_failure!($what, $where $(, $expected)?),
+            $( Err(InterpErrorInfo { kind: $p, .. }) )|* => throw_validation_failure!(format_args!($( $what_fmt ),*), $where $(, $expected)?),
             #[allow(unreachable_patterns)]
             Err(e) => Err::<!, _>(e)?,
         }

From f1d778fef1c77412580142c25cf7711b89444c81 Mon Sep 17 00:00:00 2001
From: jumbatm <jumbatm@gmail.com>
Date: Fri, 1 May 2020 21:30:46 +1000
Subject: [PATCH 16/19] Also make expected param wrapped in format_args.

---
 src/librustc_mir/interpret/validity.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index 731f6e6aede37..239e5c4fa4aa6 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -42,7 +42,7 @@ macro_rules! throw_validation_failure {
 macro_rules! try_validation {
     ($e:expr, $what:expr, $where:expr $(, $expected:expr )?) => {{
         try_validation_pat!($e, $where, {
-            _ => { "{}", $what } $( expected { $expected } )?,
+            _ => { "{}", $what } $( expected { "{}", $expected } )?,
         })
     }};
 }
@@ -67,12 +67,12 @@ macro_rules! try_validation {
 /// ```
 ///
 macro_rules! try_validation_pat {
-    ($e:expr, $where:expr, { $( $p:pat )|* => { $( $what_fmt:expr ),* } $( expected { $expected:expr } )? $( , )?}) => {{
+    ($e:expr, $where:expr, { $( $p:pat )|* => { $( $what_fmt:expr ),* } $( expected { $( $expected_fmt:expr ),* } )? $( , )?}) => {{
         match $e {
             Ok(x) => x,
             // We catch the error and turn it into a validation failure. We are okay with
             // allocation here as this can only slow down builds that fail anyway.
-            $( Err(InterpErrorInfo { kind: $p, .. }) )|* => throw_validation_failure!(format_args!($( $what_fmt ),*), $where $(, $expected)?),
+            $( Err(InterpErrorInfo { kind: $p, .. }) )|* => throw_validation_failure!(format_args!($( $what_fmt ),*), $where $(, format_args!($( $expected_fmt ),*))?),
             #[allow(unreachable_patterns)]
             Err(e) => Err::<!, _>(e)?,
         }

From 8175c4ceec9e19193e99f054f2b743f77a42a54f Mon Sep 17 00:00:00 2001
From: jumbatm <jumbatm@gmail.com>
Date: Fri, 1 May 2020 21:32:15 +1000
Subject: [PATCH 17/19] Expect at least one expr for p, what_fmt and
 expected_fmt.

---
 src/librustc_mir/interpret/validity.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index 239e5c4fa4aa6..3395c19400a50 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -67,12 +67,12 @@ macro_rules! try_validation {
 /// ```
 ///
 macro_rules! try_validation_pat {
-    ($e:expr, $where:expr, { $( $p:pat )|* => { $( $what_fmt:expr ),* } $( expected { $( $expected_fmt:expr ),* } )? $( , )?}) => {{
+    ($e:expr, $where:expr, { $( $p:pat )|+ => { $( $what_fmt:expr ),+ } $( expected { $( $expected_fmt:expr ),+ } )? $( , )?}) => {{
         match $e {
             Ok(x) => x,
             // We catch the error and turn it into a validation failure. We are okay with
             // allocation here as this can only slow down builds that fail anyway.
-            $( Err(InterpErrorInfo { kind: $p, .. }) )|* => throw_validation_failure!(format_args!($( $what_fmt ),*), $where $(, format_args!($( $expected_fmt ),*))?),
+            $( Err(InterpErrorInfo { kind: $p, .. }) )|+ => throw_validation_failure!(format_args!($( $what_fmt ),+), $where $(, format_args!($( $expected_fmt ),+))?),
             #[allow(unreachable_patterns)]
             Err(e) => Err::<!, _>(e)?,
         }

From 830473959adef21d6d9a9e13faadc0776b64e925 Mon Sep 17 00:00:00 2001
From: jumbatm <jumbatm@gmail.com>
Date: Fri, 1 May 2020 21:45:55 +1000
Subject: [PATCH 18/19] Manually format macro to not go over text width.

---
 src/librustc_mir/interpret/validity.rs | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index 3395c19400a50..54da0ba9eedde 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -67,12 +67,18 @@ macro_rules! try_validation {
 /// ```
 ///
 macro_rules! try_validation_pat {
-    ($e:expr, $where:expr, { $( $p:pat )|+ => { $( $what_fmt:expr ),+ } $( expected { $( $expected_fmt:expr ),+ } )? $( , )?}) => {{
+    ($e:expr, $where:expr, { $( $p:pat )|+ =>
+        { $( $what_fmt:expr ),+ } $( expected { $( $expected_fmt:expr ),+ } )? $( , )?}) => {{
         match $e {
             Ok(x) => x,
             // We catch the error and turn it into a validation failure. We are okay with
             // allocation here as this can only slow down builds that fail anyway.
-            $( Err(InterpErrorInfo { kind: $p, .. }) )|+ => throw_validation_failure!(format_args!($( $what_fmt ),+), $where $(, format_args!($( $expected_fmt ),+))?),
+            $( Err(InterpErrorInfo { kind: $p, .. }) )|+ =>
+                throw_validation_failure!(
+                    format_args!($( $what_fmt ),+),
+                    $where
+                    $(, format_args!($( $expected_fmt ),+))?
+                ),
             #[allow(unreachable_patterns)]
             Err(e) => Err::<!, _>(e)?,
         }

From bd18ad4fef9ca3d618521b8268183497b6104ff9 Mon Sep 17 00:00:00 2001
From: jumbatm <jumbatm@gmail.com>
Date: Fri, 1 May 2020 21:49:42 +1000
Subject: [PATCH 19/19] Note that try_validation_pat can take a format str
 directly.

---
 src/librustc_mir/interpret/validity.rs | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index 54da0ba9eedde..fe584596f01b9 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -66,6 +66,15 @@ macro_rules! try_validation {
 /// });
 /// ```
 ///
+/// An additional nicety is that both parameters actually take format args, so you can just write
+/// the format string in directly:
+///
+/// ```
+/// let v = try_validation_pat!(some_fn(), some_path, {
+///     Foo | Bar | Baz => { "{:?}", some_failure } expected { "{}", expected_value },
+/// });
+/// ```
+///
 macro_rules! try_validation_pat {
     ($e:expr, $where:expr, { $( $p:pat )|+ =>
         { $( $what_fmt:expr ),+ } $( expected { $( $expected_fmt:expr ),+ } )? $( , )?}) => {{