mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Add temporary scope to assert_matches
Addresses https://github.com/rust-lang/rust/issues/154406 in part. assert_eq will be done in a separate PR.
This commit is contained in:
@@ -168,7 +168,7 @@ macro_rules! assert_ne {
|
||||
#[allow_internal_unstable(panic_internals)]
|
||||
#[rustc_macro_transparency = "semiopaque"]
|
||||
pub macro assert_matches {
|
||||
($left:expr, $(|)? $( $pattern:pat_param )|+ $( if $guard: expr )? $(,)?) => {
|
||||
($left:expr, $(|)? $( $pattern:pat_param )|+ $( if $guard: expr )? $(,)?) => {{
|
||||
match $left {
|
||||
$( $pattern )|+ $( if $guard )? => {}
|
||||
ref left_val => {
|
||||
@@ -179,8 +179,8 @@ macro_rules! assert_ne {
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
($left:expr, $(|)? $( $pattern:pat_param )|+ $( if $guard: expr )?, $($arg:tt)+) => {
|
||||
}},
|
||||
($left:expr, $(|)? $( $pattern:pat_param )|+ $( if $guard: expr )?, $($arg:tt)+) => {{
|
||||
match $left {
|
||||
$( $pattern )|+ $( if $guard )? => {}
|
||||
ref left_val => {
|
||||
@@ -191,7 +191,7 @@ macro_rules! assert_ne {
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
}},
|
||||
}
|
||||
|
||||
/// Selects code at compile-time based on `cfg` predicates.
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#![allow(unused_must_use)]
|
||||
|
||||
use std::{assert_matches, debug_assert_matches};
|
||||
|
||||
#[allow(dead_code)]
|
||||
trait Trait {
|
||||
fn blah(&self);
|
||||
@@ -219,3 +221,24 @@ fn _matches_does_not_trigger_non_exhaustive_omitted_patterns_lint(o: core::sync:
|
||||
// Ordering is a #[non_exhaustive] enum from a separate crate
|
||||
let _m = matches!(o, core::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
|
||||
struct MutRefWithDrop<'a>(&'a mut u32);
|
||||
|
||||
// MutRefWithDrop needs to have a non-trivial drop to encounter potential lifetime issues if the
|
||||
// macros don't introduce a temporary scope.
|
||||
impl Drop for MutRefWithDrop<'_> {
|
||||
fn drop(&mut self) {
|
||||
*self.0 = u32::MAX;
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn temporary_scope_introduction() {
|
||||
// Fails to compile if the macros don't introduce a temporary scope, since `&mut val` would
|
||||
// create a second mutable borrow while `MutRefWithDrop` still holds a unique ref.
|
||||
let mut val = 0;
|
||||
|
||||
(assert_matches!(*MutRefWithDrop(&mut val).0, 0), std::mem::take(&mut val));
|
||||
|
||||
(debug_assert_matches!(*MutRefWithDrop(&mut val).0, 0), std::mem::take(&mut val));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user