about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorStuart Cook <Zalathar@users.noreply.github.com>2025-09-11 14:06:33 +1000
committerGitHub <noreply@github.com>2025-09-11 14:06:33 +1000
commit613a3b6a42b5c7413fe4a8ffd4f16ec39c32a814 (patch)
tree07a3807eb1b0955402da5bda4c14c6c5a779acbc /compiler
parent5258dfc0b742bb814c823c4d740bff14942a8d2b (diff)
parentb38a86f4d7c28ae9ab153b87c7e45037e56306fb (diff)
downloadrust-613a3b6a42b5c7413fe4a8ffd4f16ec39c32a814.tar.gz
rust-613a3b6a42b5c7413fe4a8ffd4f16ec39c32a814.zip
Rollup merge of #146428 - jieyouxu:revert-assert-desugaring, r=estebank,jackh726
Revert `assert!` desugaring changes (#122661)

Reverts rust-lang/rust#122661 to prevent rust-lang/rust#145770 slipping into beta.

cc `@estebank` (FYI)

### Review remarks

- Commit 1 is the MCVE reported in rust-lang/rust#145770 added as a regression test `tests/ui/macros/assert-desugaring-145770.rs`. Against `master`, this test fails.
- Commit 2 reverts rust-lang/rust#122661 (with a merge conflict fixed). `tests/ui/macros/assert-desugaring-145770.rs` now passes.
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_builtin_macros/src/assert.rs35
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs40
2 files changed, 18 insertions, 57 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> {
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
index d71110521ff..e18e294635b 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
@@ -1618,18 +1618,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         {
             let e = self.tcx.erase_and_anonymize_regions(e);
             let f = self.tcx.erase_and_anonymize_regions(f);
-            let mut expected = with_forced_trimmed_paths!(e.sort_string(self.tcx));
-            let mut found = with_forced_trimmed_paths!(f.sort_string(self.tcx));
-            if let ObligationCauseCode::Pattern { span, .. } = cause.code()
-                && let Some(span) = span
-                && !span.from_expansion()
-                && cause.span.from_expansion()
-            {
-                // When the type error comes from a macro like `assert!()`, and we are pointing at
-                // code the user wrote the cause and effect are reversed as the expected value is
-                // what the macro expanded to.
-                (found, expected) = (expected, found);
-            }
+            let expected = with_forced_trimmed_paths!(e.sort_string(self.tcx));
+            let found = with_forced_trimmed_paths!(f.sort_string(self.tcx));
             if expected == found {
                 label_or_note(span, terr.to_string(self.tcx));
             } else {
@@ -2152,9 +2142,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
     ) -> Option<(DiagStyledString, DiagStyledString)> {
         match values {
             ValuePairs::Regions(exp_found) => self.expected_found_str(exp_found),
-            ValuePairs::Terms(exp_found) => {
-                self.expected_found_str_term(cause, exp_found, long_ty_path)
-            }
+            ValuePairs::Terms(exp_found) => self.expected_found_str_term(exp_found, long_ty_path),
             ValuePairs::Aliases(exp_found) => self.expected_found_str(exp_found),
             ValuePairs::ExistentialTraitRef(exp_found) => self.expected_found_str(exp_found),
             ValuePairs::ExistentialProjection(exp_found) => self.expected_found_str(exp_found),
@@ -2193,7 +2181,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
 
     fn expected_found_str_term(
         &self,
-        cause: &ObligationCause<'tcx>,
         exp_found: ty::error::ExpectedFound<ty::Term<'tcx>>,
         long_ty_path: &mut Option<PathBuf>,
     ) -> Option<(DiagStyledString, DiagStyledString)> {
@@ -2201,27 +2188,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         if exp_found.references_error() {
             return None;
         }
-        let (mut expected, mut found) = (exp_found.expected, exp_found.found);
-
-        if let ObligationCauseCode::Pattern { span, .. } = cause.code()
-            && let Some(span) = span
-            && !span.from_expansion()
-            && cause.span.from_expansion()
-        {
-            // When the type error comes from a macro like `assert!()`, and we are pointing at
-            // code the user wrote, the cause and effect are reversed as the expected value is
-            // what the macro expanded to. So if the user provided a `Type` when the macro is
-            // written in such a way that a `bool` was expected, we want to print:
-            // = note: expected `bool`
-            //            found `Type`"
-            // but as far as the compiler is concerned, after expansion what was expected was `Type`
-            // = note: expected `Type`
-            //            found `bool`"
-            // so we reverse them here to match user expectation.
-            (expected, found) = (found, expected);
-        }
 
-        Some(match (expected.kind(), found.kind()) {
+        Some(match (exp_found.expected.kind(), exp_found.found.kind()) {
             (ty::TermKind::Ty(expected), ty::TermKind::Ty(found)) => {
                 let (mut exp, mut fnd) = self.cmp(expected, found);
                 // Use the terminal width as the basis to determine when to compress the printed