Auto merge of #111928 - c410-f3r:dqewdas, r=eholk
[RFC-2011] Expand more expressions cc #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) ```
This commit is contained in:
commit
a525c7ddba
@ -233,10 +233,19 @@ impl<'cx, 'a> Context<'cx, 'a> {
|
|||||||
ExprKind::Cast(local_expr, _) => {
|
ExprKind::Cast(local_expr, _) => {
|
||||||
self.manage_cond_expr(local_expr);
|
self.manage_cond_expr(local_expr);
|
||||||
}
|
}
|
||||||
|
ExprKind::If(local_expr, _, _) => {
|
||||||
|
self.manage_cond_expr(local_expr);
|
||||||
|
}
|
||||||
ExprKind::Index(prefix, suffix) => {
|
ExprKind::Index(prefix, suffix) => {
|
||||||
self.manage_cond_expr(prefix);
|
self.manage_cond_expr(prefix);
|
||||||
self.manage_cond_expr(suffix);
|
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) => {
|
ExprKind::MethodCall(call) => {
|
||||||
for arg in &mut call.args {
|
for arg in &mut call.args {
|
||||||
self.manage_cond_expr(arg);
|
self.manage_cond_expr(arg);
|
||||||
@ -295,17 +304,14 @@ impl<'cx, 'a> Context<'cx, 'a> {
|
|||||||
| ExprKind::Continue(_)
|
| ExprKind::Continue(_)
|
||||||
| ExprKind::Err
|
| ExprKind::Err
|
||||||
| ExprKind::Field(_, _)
|
| ExprKind::Field(_, _)
|
||||||
| ExprKind::FormatArgs(_)
|
|
||||||
| ExprKind::ForLoop(_, _, _, _)
|
| ExprKind::ForLoop(_, _, _, _)
|
||||||
| ExprKind::If(_, _, _)
|
| ExprKind::FormatArgs(_)
|
||||||
| ExprKind::IncludedBytes(..)
|
| ExprKind::IncludedBytes(..)
|
||||||
| ExprKind::InlineAsm(_)
|
| ExprKind::InlineAsm(_)
|
||||||
| ExprKind::OffsetOf(_, _)
|
|
||||||
| ExprKind::Let(_, _, _)
|
|
||||||
| ExprKind::Lit(_)
|
| ExprKind::Lit(_)
|
||||||
| ExprKind::Loop(_, _, _)
|
| ExprKind::Loop(_, _, _)
|
||||||
| ExprKind::MacCall(_)
|
| ExprKind::MacCall(_)
|
||||||
| ExprKind::Match(_, _)
|
| ExprKind::OffsetOf(_, _)
|
||||||
| ExprKind::Path(_, _)
|
| ExprKind::Path(_, _)
|
||||||
| ExprKind::Ret(_)
|
| ExprKind::Ret(_)
|
||||||
| ExprKind::Try(_)
|
| ExprKind::Try(_)
|
||||||
|
@ -1427,7 +1427,7 @@ pub(crate) mod builtin {
|
|||||||
#[rustc_builtin_macro]
|
#[rustc_builtin_macro]
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
#[rustc_diagnostic_item = "assert_macro"]
|
#[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 {
|
macro_rules! assert {
|
||||||
($cond:expr $(,)?) => {{ /* compiler built-in */ }};
|
($cond:expr $(,)?) => {{ /* compiler built-in */ }};
|
||||||
($cond:expr, $($arg:tt)+) => {{ /* compiler built-in */ }};
|
($cond:expr, $($arg:tt)+) => {{ /* compiler built-in */ }};
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
// needs-unwind Asserting on contents of error message
|
// needs-unwind Asserting on contents of error message
|
||||||
|
|
||||||
#![allow(path_statements, unused_allocation)]
|
#![allow(path_statements, unused_allocation)]
|
||||||
#![feature(core_intrinsics, generic_assert, generic_assert_internals)]
|
#![feature(core_intrinsics, generic_assert)]
|
||||||
|
|
||||||
macro_rules! test {
|
macro_rules! test {
|
||||||
(
|
(
|
||||||
@ -51,6 +51,7 @@ macro_rules! tests {
|
|||||||
|
|
||||||
const FOO: Foo = Foo { bar: 1 };
|
const FOO: Foo = Foo { bar: 1 };
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
struct Foo {
|
struct Foo {
|
||||||
bar: i32
|
bar: i32
|
||||||
@ -83,9 +84,18 @@ fn main() {
|
|||||||
// cast
|
// cast
|
||||||
[ elem as i32 == 3 ] => "Assertion failed: elem as i32 == 3\nWith captures:\n elem = 1\n"
|
[ 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
|
// index
|
||||||
[ [1i32, 1][elem as usize] == 3 ] => "Assertion failed: [1i32, 1][elem as usize] == 3\nWith captures:\n elem = 1\n"
|
[ [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
|
// method call
|
||||||
[ FOO.add(elem, elem) == 3 ] => "Assertion failed: FOO.add(elem, elem) == 3\nWith captures:\n elem = 1\n"
|
[ FOO.add(elem, elem) == 3 ] => "Assertion failed: FOO.add(elem, elem) == 3\nWith captures:\n elem = 1\n"
|
||||||
|
|
||||||
@ -107,77 +117,4 @@ fn main() {
|
|||||||
// unary
|
// unary
|
||||||
[ -elem == -3 ] => "Assertion failed: -elem == -3\nWith captures:\n elem = 1\n"
|
[ -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
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
// run-pass
|
// run-pass
|
||||||
// needs-unwind Asserting on contents of error message
|
// needs-unwind Asserting on contents of error message
|
||||||
|
|
||||||
#![feature(core_intrinsics, generic_assert, generic_assert_internals)]
|
#![feature(core_intrinsics, generic_assert)]
|
||||||
|
|
||||||
extern crate common;
|
extern crate common;
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// compile-flags: --test
|
// compile-flags: --test
|
||||||
// run-pass
|
// run-pass
|
||||||
|
|
||||||
#![feature(core_intrinsics, generic_assert, generic_assert_internals)]
|
#![feature(core_intrinsics, generic_assert)]
|
||||||
|
|
||||||
#[should_panic(expected = "Custom user message")]
|
#[should_panic(expected = "Custom user message")]
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
// run-pass
|
// run-pass
|
||||||
// needs-unwind Asserting on contents of error message
|
// needs-unwind Asserting on contents of error message
|
||||||
|
|
||||||
#![feature(core_intrinsics, generic_assert, generic_assert_internals)]
|
#![feature(core_intrinsics, generic_assert)]
|
||||||
|
|
||||||
extern crate common;
|
extern crate common;
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// ignore-tidy-linelength
|
// ignore-tidy-linelength
|
||||||
// run-pass
|
// run-pass
|
||||||
|
|
||||||
#![feature(core_intrinsics, generic_assert, generic_assert_internals)]
|
#![feature(core_intrinsics, generic_assert)]
|
||||||
|
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// check-pass
|
// check-pass
|
||||||
// compile-flags: -Z unpretty=expanded
|
// 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() {
|
fn arbitrary_consuming_method_for_demonstration_purposes() {
|
||||||
let elem = 1i32;
|
let elem = 1i32;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
// check-pass
|
// check-pass
|
||||||
// compile-flags: -Z unpretty=expanded
|
// compile-flags: -Z unpretty=expanded
|
||||||
|
|
||||||
#![feature(core_intrinsics, generic_assert, generic_assert_internals)]
|
#![feature(core_intrinsics, generic_assert)]
|
||||||
#[prelude_import]
|
#[prelude_import]
|
||||||
use ::std::prelude::rust_2015::*;
|
use ::std::prelude::rust_2015::*;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user