@@ -36,6 +36,7 @@ macro_rules! throw_validation_failure {
36
36
} } ;
37
37
}
38
38
39
+ /// Returns a validation failure for any Err value of $e.
39
40
macro_rules! try_validation {
40
41
( $e: expr, $what: expr, $where: expr $( , $details: expr ) ?) => { {
41
42
match $e {
@@ -46,6 +47,24 @@ macro_rules! try_validation {
46
47
}
47
48
} } ;
48
49
}
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
+ }
49
68
50
69
/// We want to show a nice path to the invalid field for diagnostics,
51
70
/// 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, '
474
493
// We are conservative with undef for integers, but try to
475
494
// actually enforce the strict rules for raw pointers (mostly because
476
495
// that lets us re-use `ref_to_mplace`).
477
- let place = try_validation ! (
496
+ let place = try_validation_pat ! (
478
497
self . ecx. ref_to_mplace( self . ecx. read_immediate( value) ?) ,
498
+ _,
479
499
"uninitialized raw pointer" ,
480
500
self . path
481
501
) ;
0 commit comments