Skip to content

Commit

Permalink
Rollup merge of rust-lang#121732 - Voultapher:improve-assert_matches-…
Browse files Browse the repository at this point in the history
…documentation, r=cuviper

Improve assert_matches! documentation

This new documentation tries to limit the impact of the conceptual pitfall, that the if guard relaxes the constraint, when really it tightens it. This is achieved by changing the text and examples. The previous documentation also chose a rather weird and non-representative example for the if guard, that made it needlessly complicated to understand.
  • Loading branch information
matthiaskrgr authored Mar 4, 2024
2 parents edb71a6 + c45f0a9 commit 448ea9b
Showing 1 changed file with 58 additions and 32 deletions.
90 changes: 58 additions & 32 deletions library/core/src/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,16 +112,19 @@ macro_rules! assert_ne {
};
}

/// Asserts that an expression matches any of the given patterns.
/// Asserts that an expression matches the provided pattern.
///
/// Like in a `match` expression, the pattern can be optionally followed by `if`
/// and a guard expression that has access to names bound by the pattern.
/// This macro is generally preferable to `assert!(matches!(value, pattern))`, because it can print
/// the debug representation of the actual value shape that did not meet expectations. In contrast,
/// using [`assert!`] will only print that expectations were not met, but not why.
///
/// On panic, this macro will print the value of the expression with its
/// debug representation.
/// The pattern syntax is exactly the same as found in a match arm and the `matches!` macro. The
/// optional if guard can be used to add additional checks that must be true for the matched value,
/// otherwise this macro will panic.
///
/// Like [`assert!`], this macro has a second form, where a custom
/// panic message can be provided.
/// On panic, this macro will print the value of the expression with its debug representation.
///
/// Like [`assert!`], this macro has a second form, where a custom panic message can be provided.
///
/// # Examples
///
Expand All @@ -130,13 +133,20 @@ macro_rules! assert_ne {
///
/// use std::assert_matches::assert_matches;
///
/// let a = 1u32.checked_add(2);
/// let b = 1u32.checked_sub(2);
/// let a = Some(345);
/// let b = Some(56);
/// assert_matches!(a, Some(_));
/// assert_matches!(b, None);
/// assert_matches!(b, Some(_));
///
/// assert_matches!(a, Some(345));
/// assert_matches!(a, Some(345) | None);
///
/// // assert_matches!(a, None); // panics
/// // assert_matches!(b, Some(345)); // panics
/// // assert_matches!(b, Some(345) | None); // panics
///
/// let c = Ok("abc".to_string());
/// assert_matches!(c, Ok(x) | Err(x) if x.len() < 100);
/// assert_matches!(a, Some(x) if x > 100);
/// // assert_matches!(a, Some(x) if x < 100); // panics
/// ```
#[unstable(feature = "assert_matches", issue = "82775")]
#[allow_internal_unstable(panic_internals)]
Expand Down Expand Up @@ -369,21 +379,25 @@ macro_rules! debug_assert_ne {
};
}

/// Asserts that an expression matches any of the given patterns.
/// Asserts that an expression matches the provided pattern.
///
/// Like in a `match` expression, the pattern can be optionally followed by `if`
/// and a guard expression that has access to names bound by the pattern.
/// This macro is generally preferable to `debug_assert!(matches!(value, pattern))`, because it can
/// print the debug representation of the actual value shape that did not meet expectations. In
/// contrast, using [`debug_assert!`] will only print that expectations were not met, but not why.
///
/// On panic, this macro will print the value of the expression with its
/// debug representation.
/// The pattern syntax is exactly the same as found in a match arm and the `matches!` macro. The
/// optional if guard can be used to add additional checks that must be true for the matched value,
/// otherwise this macro will panic.
///
/// Unlike [`assert_matches!`], `debug_assert_matches!` statements are only
/// enabled in non optimized builds by default. An optimized build will not
/// execute `debug_assert_matches!` statements unless `-C debug-assertions` is
/// passed to the compiler. This makes `debug_assert_matches!` useful for
/// checks that are too expensive to be present in a release build but may be
/// helpful during development. The result of expanding `debug_assert_matches!`
/// is always type checked.
/// On panic, this macro will print the value of the expression with its debug representation.
///
/// Like [`assert!`], this macro has a second form, where a custom panic message can be provided.
///
/// Unlike [`assert_matches!`], `debug_assert_matches!` statements are only enabled in non optimized
/// builds by default. An optimized build will not execute `debug_assert_matches!` statements unless
/// `-C debug-assertions` is passed to the compiler. This makes `debug_assert_matches!` useful for
/// checks that are too expensive to be present in a release build but may be helpful during
/// development. The result of expanding `debug_assert_matches!` is always type checked.
///
/// # Examples
///
Expand All @@ -392,13 +406,20 @@ macro_rules! debug_assert_ne {
///
/// use std::assert_matches::debug_assert_matches;
///
/// let a = 1u32.checked_add(2);
/// let b = 1u32.checked_sub(2);
/// let a = Some(345);
/// let b = Some(56);
/// debug_assert_matches!(a, Some(_));
/// debug_assert_matches!(b, None);
/// debug_assert_matches!(b, Some(_));
///
/// debug_assert_matches!(a, Some(345));
/// debug_assert_matches!(a, Some(345) | None);
///
/// let c = Ok("abc".to_string());
/// debug_assert_matches!(c, Ok(x) | Err(x) if x.len() < 100);
/// // debug_assert_matches!(a, None); // panics
/// // debug_assert_matches!(b, Some(345)); // panics
/// // debug_assert_matches!(b, Some(345) | None); // panics
///
/// debug_assert_matches!(a, Some(x) if x > 100);
/// // debug_assert_matches!(a, Some(x) if x < 100); // panics
/// ```
#[unstable(feature = "assert_matches", issue = "82775")]
#[allow_internal_unstable(assert_matches)]
Expand All @@ -409,10 +430,15 @@ pub macro debug_assert_matches($($arg:tt)*) {
}
}

/// Returns whether the given expression matches any of the given patterns.
/// Returns whether the given expression matches the provided pattern.
///
/// The pattern syntax is exactly the same as found in a match arm. The optional if guard can be
/// used to add additional checks that must be true for the matched value, otherwise this macro will
/// return `false`.
///
/// Like in a `match` expression, the pattern can be optionally followed by `if`
/// and a guard expression that has access to names bound by the pattern.
/// When testing that a value matches a pattern, it's generally preferable to use
/// [`assert_matches!`] as it will print the debug representation of the value if the assertion
/// fails.
///
/// # Examples
///
Expand Down

0 comments on commit 448ea9b

Please sign in to comment.