Skip to content

Commit

Permalink
Rollup merge of rust-lang#111928 - c410-f3r:dqewdas, r=eholk
Browse files Browse the repository at this point in the history
[RFC-2011] Expand more expressions

cc rust-lang#44838

Expands `if`, `let`, `match` and also makes `generic_assert_internals` an allowed feature when using `assert!`. `#![feature(generic_assert)]` is still needed to activate everything.

```rust
#![feature(generic_assert)]

fn fun(a: Option<i32>, b: Option<i32>, c: Option<i32>) {
  assert!(
    if a.is_some() { 1 } else { 2 } == 3
      && if let Some(elem) = b { elem == 4 } else { false }
      && match c { Some(_) => true, None => false }
  );
}

fn main() {
  fun(Some(1), None, Some(2));
}

// Assertion failed: assert!(
//   if a.is_some() { 1 } else { 2 } == 3
//     && if let Some(elem) = b { elem == 4 } else { false }
//     && match c { Some(_) => true, None => false }
// );
//
// With captures:
//   a = Some(1)
//   b = None
//   c = Some(2)
```
  • Loading branch information
compiler-errors authored May 26, 2023
2 parents 05f1b00 + 462a96c commit e6b85ab
Show file tree
Hide file tree
Showing 9 changed files with 29 additions and 86 deletions.
16 changes: 11 additions & 5 deletions compiler/rustc_builtin_macros/src/assert/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,10 +233,19 @@ impl<'cx, 'a> Context<'cx, 'a> {
ExprKind::Cast(local_expr, _) => {
self.manage_cond_expr(local_expr);
}
ExprKind::If(local_expr, _, _) => {
self.manage_cond_expr(local_expr);
}
ExprKind::Index(prefix, suffix) => {
self.manage_cond_expr(prefix);
self.manage_cond_expr(suffix);
}
ExprKind::Let(_, local_expr, _) => {
self.manage_cond_expr(local_expr);
}
ExprKind::Match(local_expr, _) => {
self.manage_cond_expr(local_expr);
}
ExprKind::MethodCall(call) => {
for arg in &mut call.args {
self.manage_cond_expr(arg);
Expand Down Expand Up @@ -295,17 +304,14 @@ impl<'cx, 'a> Context<'cx, 'a> {
| ExprKind::Continue(_)
| ExprKind::Err
| ExprKind::Field(_, _)
| ExprKind::FormatArgs(_)
| ExprKind::ForLoop(_, _, _, _)
| ExprKind::If(_, _, _)
| ExprKind::FormatArgs(_)
| ExprKind::IncludedBytes(..)
| ExprKind::InlineAsm(_)
| ExprKind::OffsetOf(_, _)
| ExprKind::Let(_, _, _)
| ExprKind::Lit(_)
| ExprKind::Loop(_, _, _)
| ExprKind::MacCall(_)
| ExprKind::Match(_, _)
| ExprKind::OffsetOf(_, _)
| ExprKind::Path(_, _)
| ExprKind::Ret(_)
| ExprKind::Try(_)
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1427,7 +1427,7 @@ pub(crate) mod builtin {
#[rustc_builtin_macro]
#[macro_export]
#[rustc_diagnostic_item = "assert_macro"]
#[allow_internal_unstable(core_panic, edition_panic)]
#[allow_internal_unstable(core_panic, edition_panic, generic_assert_internals)]
macro_rules! assert {
($cond:expr $(,)?) => {{ /* compiler built-in */ }};
($cond:expr, $($arg:tt)+) => {{ /* compiler built-in */ }};
Expand Down
85 changes: 11 additions & 74 deletions tests/ui/macros/rfc-2011-nicer-assert-messages/all-expr-kinds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// needs-unwind Asserting on contents of error message

#![allow(path_statements, unused_allocation)]
#![feature(core_intrinsics, generic_assert, generic_assert_internals)]
#![feature(core_intrinsics, generic_assert)]

macro_rules! test {
(
Expand Down Expand Up @@ -51,6 +51,7 @@ macro_rules! tests {

const FOO: Foo = Foo { bar: 1 };


#[derive(Clone, Copy, Debug, PartialEq)]
struct Foo {
bar: i32
Expand Down Expand Up @@ -83,9 +84,18 @@ fn main() {
// cast
[ elem as i32 == 3 ] => "Assertion failed: elem as i32 == 3\nWith captures:\n elem = 1\n"

// if
[ if elem == 3 { true } else { false } ] => "Assertion failed: if elem == 3 { true } else { false }\nWith captures:\n elem = 1\n"

// index
[ [1i32, 1][elem as usize] == 3 ] => "Assertion failed: [1i32, 1][elem as usize] == 3\nWith captures:\n elem = 1\n"

// let
[ if let 3 = elem { true } else { false } ] => "Assertion failed: if let 3 = elem { true } else { false }\nWith captures:\n elem = 1\n"

// match
[ match elem { 3 => true, _ => false, } ] => "Assertion failed: match elem { 3 => true, _ => false, }\nWith captures:\n elem = 1\n"

// method call
[ FOO.add(elem, elem) == 3 ] => "Assertion failed: FOO.add(elem, elem) == 3\nWith captures:\n elem = 1\n"

Expand All @@ -107,77 +117,4 @@ fn main() {
// unary
[ -elem == -3 ] => "Assertion failed: -elem == -3\nWith captures:\n elem = 1\n"
);

// ***** Disallowed *****

tests!(
let mut elem = 1i32;

// assign
[ { let local = elem; local } == 3 ] => "Assertion failed: { let local = elem; local } == 3"

// assign op
[ { elem += 1; elem } == 3 ] => "Assertion failed: { elem += 1; elem } == 3"

// async
[ { let _ = async { elem }; elem } == 3 ] => "Assertion failed: { let _ = async { elem }; elem } == 3"

// await

// block
[ { elem } == 3 ] => "Assertion failed: { elem } == 3"

// break
[ loop { break elem; } == 3 ] => "Assertion failed: loop { break elem; } == 3"

// closure
[(|| elem)() == 3 ] => "Assertion failed: (|| elem)() == 3"

// const block

// continue

// err

// field
[ FOO.bar == 3 ] => "Assertion failed: FOO.bar == 3"

// for loop
[ { for _ in 0..elem { elem; } elem } == 3 ] => "Assertion failed: { for _ in 0..elem { elem; } elem } == 3"

// if
[ if true { elem } else { elem } == 3 ] => "Assertion failed: if true { elem } else { elem } == 3"

// inline asm

// let
[ if let true = true { elem } else { elem } == 3 ] => "Assertion failed: if let true = true { elem } else { elem } == 3"

// lit

// loop
[ loop { elem; break elem; } == 3 ] => "Assertion failed: loop { elem; break elem; } == 3"

// mac call

// match
[ match elem { _ => elem } == 3 ] => "Assertion failed: (match elem { _ => elem, }) == 3"

// ret
[ (|| { return elem; })() == 3 ] => "Assertion failed: (|| { return elem; })() == 3"

// try
[ (|| { Some(Some(elem)?) })() == Some(3) ] => "Assertion failed: (|| { Some(Some(elem)?) })() == Some(3)"

// try block

// underscore

// while
[ { while false { elem; break; } elem } == 3 ] => "Assertion failed: { while false { elem; break; } elem } == 3"

// yeet

// yield
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// run-pass
// needs-unwind Asserting on contents of error message

#![feature(core_intrinsics, generic_assert, generic_assert_internals)]
#![feature(core_intrinsics, generic_assert)]

extern crate common;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// compile-flags: --test
// run-pass

#![feature(core_intrinsics, generic_assert, generic_assert_internals)]
#![feature(core_intrinsics, generic_assert)]

#[should_panic(expected = "Custom user message")]
#[test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// run-pass
// needs-unwind Asserting on contents of error message

#![feature(core_intrinsics, generic_assert, generic_assert_internals)]
#![feature(core_intrinsics, generic_assert)]

extern crate common;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// ignore-tidy-linelength
// run-pass

#![feature(core_intrinsics, generic_assert, generic_assert_internals)]
#![feature(core_intrinsics, generic_assert)]

use std::fmt::{Debug, Formatter};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// check-pass
// compile-flags: -Z unpretty=expanded

#![feature(core_intrinsics, generic_assert, generic_assert_internals)]
#![feature(core_intrinsics, generic_assert)]

fn arbitrary_consuming_method_for_demonstration_purposes() {
let elem = 1i32;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// check-pass
// compile-flags: -Z unpretty=expanded

#![feature(core_intrinsics, generic_assert, generic_assert_internals)]
#![feature(core_intrinsics, generic_assert)]
#[prelude_import]
use ::std::prelude::rust_2015::*;
#[macro_use]
Expand Down

0 comments on commit e6b85ab

Please sign in to comment.