@@ -36,6 +36,7 @@ macro_rules! throw_validation_failure {
3636 } } ;
3737}
3838
39+ /// Returns a validation failure for any Err value of $e.
3940macro_rules! try_validation {
4041 ( $e: expr, $what: expr, $where: expr $( , $details: expr ) ?) => { {
4142 match $e {
@@ -46,6 +47,24 @@ macro_rules! try_validation {
4647 }
4748 } } ;
4849}
50+ /// Like try_validation, but will throw a validation error if any of the patterns in $p are
51+ /// matched. Other errors are passed back to the caller, unchanged. This lets you use the patterns
52+ /// as a kind of validation blacklist:
53+ ///
54+ /// ```rust
55+ /// let v = try_validation_pat(some_fn(), Foo | Bar | Baz, "some failure", "some place");
56+ /// // Failures that match $p are thrown up as validation errors, but other errors are passed back
57+ /// // unchanged.
58+ /// ```
59+ macro_rules! try_validation_pat {
60+ ( $e: expr, $( $p: pat ) |* , $what: expr, $where: expr $( , $details: expr ) ?) => { {
61+ match $e {
62+ Ok ( x) => x,
63+ $( Err ( $p) ) |* if true => throw_validation_failure!( $what, $where $( , $details) ?) ,
64+ Err ( e) => Err :: <!, _>( e) ?,
65+ }
66+ } } ;
67+ }
4968
5069/// We want to show a nice path to the invalid field for diagnostics,
5170/// 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, '
474493 // We are conservative with undef for integers, but try to
475494 // actually enforce the strict rules for raw pointers (mostly because
476495 // that lets us re-use `ref_to_mplace`).
477- let place = try_validation ! (
496+ let place = try_validation_pat ! (
478497 self . ecx. ref_to_mplace( self . ecx. read_immediate( value) ?) ,
498+ _,
479499 "uninitialized raw pointer" ,
480500 self . path
481501 ) ;
0 commit comments