Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions library/core/src/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {
Expand All @@ -179,8 +179,8 @@ pub macro assert_matches {
);
}
}
},
($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 => {
Expand All @@ -191,7 +191,7 @@ pub macro assert_matches {
);
}
}
},
}},
}

/// Selects code at compile-time based on `cfg` predicates.
Expand Down
23 changes: 23 additions & 0 deletions library/coretests/tests/macros.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#![allow(unused_must_use)]

use std::{assert_matches, debug_assert_matches};

#[allow(dead_code)]
trait Trait {
fn blah(&self);
Expand Down Expand Up @@ -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.
Comment thread
Voultapher marked this conversation as resolved.
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));
Comment thread
Voultapher marked this conversation as resolved.
}
Loading