about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorjumbatm <jumbatm@gmail.com>2020-04-23 22:00:06 +1000
committerjumbatm <jumbatm@gmail.com>2020-05-01 21:52:43 +1000
commit326d38fa09cfdf9e611b8828604a7a05c7f55c85 (patch)
tree3fe9df1e239a0c0a548150d7d1def722a04a7a3c /src
parent14d90deab9cbbc1bfb45af52f9dc9fbce945da91 (diff)
downloadrust-326d38fa09cfdf9e611b8828604a7a05c7f55c85.tar.gz
rust-326d38fa09cfdf9e611b8828604a7a05c7f55c85.zip
Add try_validation_pat.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/interpret/validity.rs22
1 files changed, 21 insertions, 1 deletions
diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index 0b6422316ea..1e4c9367f6a 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
                 );