about summary refs log tree commit diff
path: root/compiler/rustc_builtin_macros/src/assert.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_builtin_macros/src/assert.rs')
-rw-r--r--compiler/rustc_builtin_macros/src/assert.rs35
1 files changed, 14 insertions, 21 deletions
diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs
index 013258a1b4e..855da5caa31 100644
--- a/compiler/rustc_builtin_macros/src/assert.rs
+++ b/compiler/rustc_builtin_macros/src/assert.rs
@@ -1,8 +1,8 @@
 mod context;
 
-use rustc_ast::token::{self, Delimiter};
+use rustc_ast::token::Delimiter;
 use rustc_ast::tokenstream::{DelimSpan, TokenStream};
-use rustc_ast::{DelimArgs, Expr, ExprKind, MacCall, Path, PathSegment};
+use rustc_ast::{DelimArgs, Expr, ExprKind, MacCall, Path, PathSegment, UnOp, token};
 use rustc_ast_pretty::pprust;
 use rustc_errors::PResult;
 use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult};
@@ -29,7 +29,7 @@ pub(crate) fn expand_assert<'cx>(
 
     // `core::panic` and `std::panic` are different macros, so we use call-site
     // context to pick up whichever is currently in scope.
-    let call_site_span = cx.with_call_site_ctxt(cond_expr.span);
+    let call_site_span = cx.with_call_site_ctxt(span);
 
     let panic_path = || {
         if use_panic_2021(span) {
@@ -63,7 +63,7 @@ pub(crate) fn expand_assert<'cx>(
                 }),
             })),
         );
-        assert_cond_check(cx, call_site_span, cond_expr, then)
+        expr_if_not(cx, call_site_span, cond_expr, then, None)
     }
     // If `generic_assert` is enabled, generates rich captured outputs
     //
@@ -88,33 +88,26 @@ pub(crate) fn expand_assert<'cx>(
                 )),
             )],
         );
-        assert_cond_check(cx, call_site_span, cond_expr, then)
+        expr_if_not(cx, call_site_span, cond_expr, then, None)
     };
 
     ExpandResult::Ready(MacEager::expr(expr))
 }
 
-/// `assert!($cond_expr, $custom_message)`
 struct Assert {
     cond_expr: Box<Expr>,
     custom_message: Option<TokenStream>,
 }
 
-/// `match <cond> { true => {} _ => <then> }`
-fn assert_cond_check(cx: &ExtCtxt<'_>, span: Span, cond: Box<Expr>, then: Box<Expr>) -> Box<Expr> {
-    // Instead of expanding to `if !<cond> { <then> }`, we expand to
-    // `match <cond> { true => {} _ => <then> }`.
-    // This allows us to always complain about mismatched types instead of "cannot apply unary
-    // operator `!` to type `X`" when passing an invalid `<cond>`, while also allowing `<cond>` to
-    // be `&true`.
-    let els = cx.expr_block(cx.block(span, thin_vec![]));
-    let mut arms = thin_vec![];
-    arms.push(cx.arm(span, cx.pat_lit(span, cx.expr_bool(span, true)), els));
-    arms.push(cx.arm(span, cx.pat_wild(span), then));
-
-    // We wrap the `match` in a statement to limit the length of any borrows introduced in the
-    // condition.
-    cx.expr_block(cx.block(span, [cx.stmt_expr(cx.expr_match(span, cond, arms))].into()))
+// if !{ ... } { ... } else { ... }
+fn expr_if_not(
+    cx: &ExtCtxt<'_>,
+    span: Span,
+    cond: Box<Expr>,
+    then: Box<Expr>,
+    els: Option<Box<Expr>>,
+) -> Box<Expr> {
+    cx.expr_if(span, cx.expr(span, ExprKind::Unary(UnOp::Not, cond)), then, els)
 }
 
 fn parse_assert<'a>(cx: &ExtCtxt<'a>, sp: Span, stream: TokenStream) -> PResult<'a, Assert> {