about summary refs log tree commit diff
path: root/compiler/rustc_builtin_macros/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_builtin_macros/src')
-rw-r--r--compiler/rustc_builtin_macros/src/asm.rs71
-rw-r--r--compiler/rustc_builtin_macros/src/assert.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/assert/context.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/cfg.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/compile_error.rs14
-rw-r--r--compiler/rustc_builtin_macros/src/concat.rs35
-rw-r--r--compiler/rustc_builtin_macros/src/concat_bytes.rs131
-rw-r--r--compiler/rustc_builtin_macros/src/concat_idents.rs12
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/default.rs53
-rw-r--r--compiler/rustc_builtin_macros/src/env.rs36
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs90
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/source_util.rs43
-rw-r--r--compiler/rustc_builtin_macros/src/type_ascribe.rs4
14 files changed, 248 insertions, 252 deletions
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index 263081ea19e..29bf5e9f304 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -13,7 +13,7 @@ use rustc_session::lint;
 use rustc_session::parse::ParseSess;
 use rustc_span::symbol::Ident;
 use rustc_span::symbol::{kw, sym, Symbol};
-use rustc_span::{InnerSpan, Span};
+use rustc_span::{ErrorGuaranteed, InnerSpan, Span};
 use rustc_target::asm::InlineAsmArch;
 use smallvec::smallvec;
 
@@ -433,7 +433,10 @@ fn parse_reg<'a>(
     Ok(result)
 }
 
-fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::InlineAsm> {
+fn expand_preparsed_asm(
+    ecx: &mut ExtCtxt<'_>,
+    args: AsmArgs,
+) -> Result<ast::InlineAsm, ErrorGuaranteed> {
     let mut template = vec![];
     // Register operands are implicitly used since they are not allowed to be
     // referenced in the template string.
@@ -459,10 +462,10 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
             match expr_to_spanned_string(ecx, template_expr, msg) {
                 Ok(template_part) => template_part,
                 Err(err) => {
-                    if let Some((err, _)) = err {
-                        err.emit();
-                    }
-                    return None;
+                    return Err(match err {
+                        Ok((err, _)) => err.emit(),
+                        Err(guar) => guar,
+                    });
                 }
             };
 
@@ -551,8 +554,8 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
                 let err_sp = template_span.from_inner(InnerSpan::new(span.start, span.end));
                 e.span_label(err_sp, label);
             }
-            e.emit();
-            return None;
+            let guar = e.emit();
+            return Err(guar);
         }
 
         curarg = parser.curarg;
@@ -719,7 +722,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
         }
     }
 
-    Some(ast::InlineAsm {
+    Ok(ast::InlineAsm {
         template,
         template_strs: template_strs.into_boxed_slice(),
         operands: args.operands,
@@ -736,22 +739,21 @@ pub(super) fn expand_asm<'cx>(
 ) -> Box<dyn base::MacResult + 'cx> {
     match parse_args(ecx, sp, tts, false) {
         Ok(args) => {
-            let expr = if let Some(inline_asm) = expand_preparsed_asm(ecx, args) {
-                P(ast::Expr {
+            let expr = match expand_preparsed_asm(ecx, args) {
+                Ok(inline_asm) => P(ast::Expr {
                     id: ast::DUMMY_NODE_ID,
                     kind: ast::ExprKind::InlineAsm(P(inline_asm)),
                     span: sp,
                     attrs: ast::AttrVec::new(),
                     tokens: None,
-                })
-            } else {
-                DummyResult::raw_expr(sp, true)
+                }),
+                Err(guar) => DummyResult::raw_expr(sp, Some(guar)),
             };
             MacEager::expr(expr)
         }
         Err(err) => {
-            err.emit();
-            DummyResult::any(sp)
+            let guar = err.emit();
+            DummyResult::any(sp, guar)
         }
     }
 }
@@ -762,28 +764,25 @@ pub(super) fn expand_global_asm<'cx>(
     tts: TokenStream,
 ) -> Box<dyn base::MacResult + 'cx> {
     match parse_args(ecx, sp, tts, true) {
-        Ok(args) => {
-            if let Some(inline_asm) = expand_preparsed_asm(ecx, args) {
-                MacEager::items(smallvec![P(ast::Item {
-                    ident: Ident::empty(),
-                    attrs: ast::AttrVec::new(),
-                    id: ast::DUMMY_NODE_ID,
-                    kind: ast::ItemKind::GlobalAsm(Box::new(inline_asm)),
-                    vis: ast::Visibility {
-                        span: sp.shrink_to_lo(),
-                        kind: ast::VisibilityKind::Inherited,
-                        tokens: None,
-                    },
-                    span: sp,
+        Ok(args) => match expand_preparsed_asm(ecx, args) {
+            Ok(inline_asm) => MacEager::items(smallvec![P(ast::Item {
+                ident: Ident::empty(),
+                attrs: ast::AttrVec::new(),
+                id: ast::DUMMY_NODE_ID,
+                kind: ast::ItemKind::GlobalAsm(Box::new(inline_asm)),
+                vis: ast::Visibility {
+                    span: sp.shrink_to_lo(),
+                    kind: ast::VisibilityKind::Inherited,
                     tokens: None,
-                })])
-            } else {
-                DummyResult::any(sp)
-            }
-        }
+                },
+                span: sp,
+                tokens: None,
+            })]),
+            Err(guar) => DummyResult::any(sp, guar),
+        },
         Err(err) => {
-            err.emit();
-            DummyResult::any(sp)
+            let guar = err.emit();
+            DummyResult::any(sp, guar)
         }
     }
 }
diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs
index 501d557f3ab..613ce43dec2 100644
--- a/compiler/rustc_builtin_macros/src/assert.rs
+++ b/compiler/rustc_builtin_macros/src/assert.rs
@@ -23,8 +23,8 @@ pub fn expand_assert<'cx>(
     let Assert { cond_expr, custom_message } = match parse_assert(cx, span, tts) {
         Ok(assert) => assert,
         Err(err) => {
-            err.emit();
-            return DummyResult::any(span);
+            let guar = err.emit();
+            return DummyResult::any(span, guar);
         }
     };
 
diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs
index 7737041090b..56c56b2704b 100644
--- a/compiler/rustc_builtin_macros/src/assert/context.rs
+++ b/compiler/rustc_builtin_macros/src/assert/context.rs
@@ -304,7 +304,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
             | ExprKind::ConstBlock(_)
             | ExprKind::Continue(_)
             | ExprKind::Dummy
-            | ExprKind::Err
+            | ExprKind::Err(_)
             | ExprKind::Field(_, _)
             | ExprKind::ForLoop { .. }
             | ExprKind::FormatArgs(_)
diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs
index 581d390992a..ca66bc0da0c 100644
--- a/compiler/rustc_builtin_macros/src/cfg.rs
+++ b/compiler/rustc_builtin_macros/src/cfg.rs
@@ -29,8 +29,8 @@ pub fn expand_cfg(
             MacEager::expr(cx.expr_bool(sp, matches_cfg))
         }
         Err(err) => {
-            err.emit();
-            DummyResult::any(sp)
+            let guar = err.emit();
+            DummyResult::any(sp, guar)
         }
     }
 }
diff --git a/compiler/rustc_builtin_macros/src/compile_error.rs b/compiler/rustc_builtin_macros/src/compile_error.rs
index f157575da79..66500351272 100644
--- a/compiler/rustc_builtin_macros/src/compile_error.rs
+++ b/compiler/rustc_builtin_macros/src/compile_error.rs
@@ -9,16 +9,14 @@ pub fn expand_compile_error<'cx>(
     sp: Span,
     tts: TokenStream,
 ) -> Box<dyn base::MacResult + 'cx> {
-    let Some(var) = get_single_str_from_tts(cx, sp, tts, "compile_error!") else {
-        return DummyResult::any(sp);
+    let var = match get_single_str_from_tts(cx, sp, tts, "compile_error!") {
+        Ok(var) => var,
+        Err(guar) => return DummyResult::any(sp, guar),
     };
 
-    #[expect(
-        rustc::diagnostic_outside_of_impl,
-        reason = "diagnostic message is specified by user"
-    )]
+    #[expect(rustc::diagnostic_outside_of_impl, reason = "diagnostic message is specified by user")]
     #[expect(rustc::untranslatable_diagnostic, reason = "diagnostic message is specified by user")]
-    cx.dcx().span_err(sp, var.to_string());
+    let guar = cx.dcx().span_err(sp, var.to_string());
 
-    DummyResult::any(sp)
+    DummyResult::any(sp, guar)
 }
diff --git a/compiler/rustc_builtin_macros/src/concat.rs b/compiler/rustc_builtin_macros/src/concat.rs
index 691142c03ed..dd4a0e7f228 100644
--- a/compiler/rustc_builtin_macros/src/concat.rs
+++ b/compiler/rustc_builtin_macros/src/concat.rs
@@ -11,12 +11,13 @@ pub fn expand_concat(
     sp: rustc_span::Span,
     tts: TokenStream,
 ) -> Box<dyn base::MacResult + 'static> {
-    let Some(es) = base::get_exprs_from_tts(cx, tts) else {
-        return DummyResult::any(sp);
+    let es = match base::get_exprs_from_tts(cx, tts) {
+        Ok(es) => es,
+        Err(guar) => return DummyResult::any(sp, guar),
     };
     let mut accumulator = String::new();
     let mut missing_literal = vec![];
-    let mut has_errors = false;
+    let mut guar = None;
     for e in es {
         match e.kind {
             ast::ExprKind::Lit(token_lit) => match ast::LitKind::from_token_lit(token_lit) {
@@ -33,19 +34,16 @@ pub fn expand_concat(
                     accumulator.push_str(&b.to_string());
                 }
                 Ok(ast::LitKind::CStr(..)) => {
-                    cx.dcx().emit_err(errors::ConcatCStrLit { span: e.span });
-                    has_errors = true;
+                    guar = Some(cx.dcx().emit_err(errors::ConcatCStrLit { span: e.span }));
                 }
                 Ok(ast::LitKind::Byte(..) | ast::LitKind::ByteStr(..)) => {
-                    cx.dcx().emit_err(errors::ConcatBytestr { span: e.span });
-                    has_errors = true;
+                    guar = Some(cx.dcx().emit_err(errors::ConcatBytestr { span: e.span }));
                 }
-                Ok(ast::LitKind::Err(_)) => {
-                    has_errors = true;
+                Ok(ast::LitKind::Err(guarantee)) => {
+                    guar = Some(guarantee);
                 }
                 Err(err) => {
-                    report_lit_error(&cx.sess.parse_sess, err, token_lit, e.span);
-                    has_errors = true;
+                    guar = Some(report_lit_error(&cx.sess.parse_sess, err, token_lit, e.span));
                 }
             },
             // We also want to allow negative numeric literals.
@@ -56,8 +54,7 @@ pub fn expand_concat(
                     Ok(ast::LitKind::Int(i, _)) => accumulator.push_str(&format!("-{i}")),
                     Ok(ast::LitKind::Float(f, _)) => accumulator.push_str(&format!("-{f}")),
                     Err(err) => {
-                        report_lit_error(&cx.sess.parse_sess, err, token_lit, e.span);
-                        has_errors = true;
+                        guar = Some(report_lit_error(&cx.sess.parse_sess, err, token_lit, e.span));
                     }
                     _ => missing_literal.push(e.span),
                 }
@@ -65,8 +62,8 @@ pub fn expand_concat(
             ast::ExprKind::IncludedBytes(..) => {
                 cx.dcx().emit_err(errors::ConcatBytestr { span: e.span });
             }
-            ast::ExprKind::Err => {
-                has_errors = true;
+            ast::ExprKind::Err(guarantee) => {
+                guar = Some(guarantee);
             }
             ast::ExprKind::Dummy => cx.dcx().span_bug(e.span, "concatenating `ExprKind::Dummy`"),
             _ => {
@@ -76,10 +73,10 @@ pub fn expand_concat(
     }
 
     if !missing_literal.is_empty() {
-        cx.dcx().emit_err(errors::ConcatMissingLiteral { spans: missing_literal });
-        return DummyResult::any(sp);
-    } else if has_errors {
-        return DummyResult::any(sp);
+        let guar = cx.dcx().emit_err(errors::ConcatMissingLiteral { spans: missing_literal });
+        return DummyResult::any(sp, guar);
+    } else if let Some(guar) = guar {
+        return DummyResult::any(sp, guar);
     }
     let sp = cx.with_def_site_ctxt(sp);
     base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&accumulator)))
diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs
index 8ce004586ce..32e17112d8c 100644
--- a/compiler/rustc_builtin_macros/src/concat_bytes.rs
+++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs
@@ -2,7 +2,7 @@ use rustc_ast as ast;
 use rustc_ast::{ptr::P, tokenstream::TokenStream};
 use rustc_expand::base::{self, DummyResult};
 use rustc_session::errors::report_lit_error;
-use rustc_span::Span;
+use rustc_span::{ErrorGuaranteed, Span};
 
 use crate::errors;
 
@@ -12,7 +12,7 @@ fn invalid_type_err(
     token_lit: ast::token::Lit,
     span: Span,
     is_nested: bool,
-) {
+) -> ErrorGuaranteed {
     use errors::{
         ConcatBytesInvalid, ConcatBytesInvalidSuggestion, ConcatBytesNonU8, ConcatBytesOob,
     };
@@ -22,12 +22,12 @@ fn invalid_type_err(
         Ok(ast::LitKind::CStr(_, _)) => {
             // Avoid ambiguity in handling of terminal `NUL` by refusing to
             // concatenate C string literals as bytes.
-            dcx.emit_err(errors::ConcatCStrLit { span: span });
+            dcx.emit_err(errors::ConcatCStrLit { span })
         }
         Ok(ast::LitKind::Char(_)) => {
             let sugg =
                 snippet.map(|snippet| ConcatBytesInvalidSuggestion::CharLit { span, snippet });
-            dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "character", sugg });
+            dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "character", sugg })
         }
         Ok(ast::LitKind::Str(_, _)) => {
             // suggestion would be invalid if we are nested
@@ -36,86 +36,79 @@ fn invalid_type_err(
             } else {
                 None
             };
-            dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "string", sugg });
+            dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "string", sugg })
         }
         Ok(ast::LitKind::Float(_, _)) => {
-            dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "float", sugg: None });
+            dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "float", sugg: None })
         }
         Ok(ast::LitKind::Bool(_)) => {
-            dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "boolean", sugg: None });
+            dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "boolean", sugg: None })
         }
-        Ok(ast::LitKind::Err(_)) => {}
         Ok(ast::LitKind::Int(_, _)) if !is_nested => {
             let sugg =
                 snippet.map(|snippet| ConcatBytesInvalidSuggestion::IntLit { span: span, snippet });
-            dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "numeric", sugg });
+            dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "numeric", sugg })
         }
         Ok(ast::LitKind::Int(
             val,
             ast::LitIntType::Unsuffixed | ast::LitIntType::Unsigned(ast::UintTy::U8),
         )) => {
             assert!(val.get() > u8::MAX.into()); // must be an error
-            dcx.emit_err(ConcatBytesOob { span });
-        }
-        Ok(ast::LitKind::Int(_, _)) => {
-            dcx.emit_err(ConcatBytesNonU8 { span });
+            dcx.emit_err(ConcatBytesOob { span })
         }
+        Ok(ast::LitKind::Int(_, _)) => dcx.emit_err(ConcatBytesNonU8 { span }),
         Ok(ast::LitKind::ByteStr(..) | ast::LitKind::Byte(_)) => unreachable!(),
-        Err(err) => {
-            report_lit_error(&cx.sess.parse_sess, err, token_lit, span);
-        }
+        Ok(ast::LitKind::Err(guar)) => guar,
+        Err(err) => report_lit_error(&cx.sess.parse_sess, err, token_lit, span),
     }
 }
 
+/// Returns `expr` as a *single* byte literal if applicable.
+///
+/// Otherwise, returns `None`, and either pushes the `expr`'s span to `missing_literals` or
+/// updates `guar` accordingly.
 fn handle_array_element(
     cx: &mut base::ExtCtxt<'_>,
-    has_errors: &mut bool,
+    guar: &mut Option<ErrorGuaranteed>,
     missing_literals: &mut Vec<rustc_span::Span>,
     expr: &P<rustc_ast::Expr>,
 ) -> Option<u8> {
     let dcx = cx.dcx();
-    match expr.kind {
-        ast::ExprKind::Array(_) | ast::ExprKind::Repeat(_, _) => {
-            if !*has_errors {
-                dcx.emit_err(errors::ConcatBytesArray { span: expr.span, bytestr: false });
-            }
-            *has_errors = true;
-            None
-        }
-        ast::ExprKind::Lit(token_lit) => match ast::LitKind::from_token_lit(token_lit) {
-            Ok(ast::LitKind::Int(
-                val,
-                ast::LitIntType::Unsuffixed | ast::LitIntType::Unsigned(ast::UintTy::U8),
-            )) if val.get() <= u8::MAX.into() => Some(val.get() as u8),
 
-            Ok(ast::LitKind::Byte(val)) => Some(val),
-            Ok(ast::LitKind::ByteStr(..)) => {
-                if !*has_errors {
-                    dcx.emit_err(errors::ConcatBytesArray { span: expr.span, bytestr: true });
+    match expr.kind {
+        ast::ExprKind::Lit(token_lit) => {
+            match ast::LitKind::from_token_lit(token_lit) {
+                Ok(ast::LitKind::Int(
+                    val,
+                    ast::LitIntType::Unsuffixed | ast::LitIntType::Unsigned(ast::UintTy::U8),
+                )) if let Ok(val) = u8::try_from(val.get()) => {
+                    return Some(val);
                 }
-                *has_errors = true;
-                None
-            }
-            _ => {
-                if !*has_errors {
-                    invalid_type_err(cx, token_lit, expr.span, true);
+                Ok(ast::LitKind::Byte(val)) => return Some(val),
+                Ok(ast::LitKind::ByteStr(..)) => {
+                    guar.get_or_insert_with(|| {
+                        dcx.emit_err(errors::ConcatBytesArray { span: expr.span, bytestr: true })
+                    });
                 }
-                *has_errors = true;
-                None
-            }
-        },
-        ast::ExprKind::IncludedBytes(..) => {
-            if !*has_errors {
-                dcx.emit_err(errors::ConcatBytesArray { span: expr.span, bytestr: false });
-            }
-            *has_errors = true;
-            None
+                _ => {
+                    guar.get_or_insert_with(|| invalid_type_err(cx, token_lit, expr.span, true));
+                }
+            };
         }
-        _ => {
-            missing_literals.push(expr.span);
-            None
+        ast::ExprKind::Array(_) | ast::ExprKind::Repeat(_, _) => {
+            guar.get_or_insert_with(|| {
+                dcx.emit_err(errors::ConcatBytesArray { span: expr.span, bytestr: false })
+            });
+        }
+        ast::ExprKind::IncludedBytes(..) => {
+            guar.get_or_insert_with(|| {
+                dcx.emit_err(errors::ConcatBytesArray { span: expr.span, bytestr: false })
+            });
         }
+        _ => missing_literals.push(expr.span),
     }
+
+    None
 }
 
 pub fn expand_concat_bytes(
@@ -123,18 +116,19 @@ pub fn expand_concat_bytes(
     sp: rustc_span::Span,
     tts: TokenStream,
 ) -> Box<dyn base::MacResult + 'static> {
-    let Some(es) = base::get_exprs_from_tts(cx, tts) else {
-        return DummyResult::any(sp);
+    let es = match base::get_exprs_from_tts(cx, tts) {
+        Ok(es) => es,
+        Err(guar) => return DummyResult::any(sp, guar),
     };
     let mut accumulator = Vec::new();
     let mut missing_literals = vec![];
-    let mut has_errors = false;
+    let mut guar = None;
     for e in es {
         match &e.kind {
             ast::ExprKind::Array(exprs) => {
                 for expr in exprs {
                     if let Some(elem) =
-                        handle_array_element(cx, &mut has_errors, &mut missing_literals, expr)
+                        handle_array_element(cx, &mut guar, &mut missing_literals, expr)
                     {
                         accumulator.push(elem);
                     }
@@ -146,14 +140,16 @@ pub fn expand_concat_bytes(
                         ast::LitKind::from_token_lit(token_lit)
                 {
                     if let Some(elem) =
-                        handle_array_element(cx, &mut has_errors, &mut missing_literals, expr)
+                        handle_array_element(cx, &mut guar, &mut missing_literals, expr)
                     {
                         for _ in 0..count_val.get() {
                             accumulator.push(elem);
                         }
                     }
                 } else {
-                    cx.dcx().emit_err(errors::ConcatBytesBadRepeat { span: count.value.span });
+                    guar = Some(
+                        cx.dcx().emit_err(errors::ConcatBytesBadRepeat { span: count.value.span }),
+                    );
                 }
             }
             &ast::ExprKind::Lit(token_lit) => match ast::LitKind::from_token_lit(token_lit) {
@@ -164,17 +160,14 @@ pub fn expand_concat_bytes(
                     accumulator.extend_from_slice(bytes);
                 }
                 _ => {
-                    if !has_errors {
-                        invalid_type_err(cx, token_lit, e.span, false);
-                    }
-                    has_errors = true;
+                    guar.get_or_insert_with(|| invalid_type_err(cx, token_lit, e.span, false));
                 }
             },
             ast::ExprKind::IncludedBytes(bytes) => {
                 accumulator.extend_from_slice(bytes);
             }
-            ast::ExprKind::Err => {
-                has_errors = true;
+            ast::ExprKind::Err(guarantee) => {
+                guar = Some(*guarantee);
             }
             ast::ExprKind::Dummy => cx.dcx().span_bug(e.span, "concatenating `ExprKind::Dummy`"),
             _ => {
@@ -183,10 +176,10 @@ pub fn expand_concat_bytes(
         }
     }
     if !missing_literals.is_empty() {
-        cx.dcx().emit_err(errors::ConcatBytesMissingLiteral { spans: missing_literals });
-        return base::MacEager::expr(DummyResult::raw_expr(sp, true));
-    } else if has_errors {
-        return base::MacEager::expr(DummyResult::raw_expr(sp, true));
+        let guar = cx.dcx().emit_err(errors::ConcatBytesMissingLiteral { spans: missing_literals });
+        return base::MacEager::expr(DummyResult::raw_expr(sp, Some(guar)));
+    } else if let Some(guar) = guar {
+        return base::MacEager::expr(DummyResult::raw_expr(sp, Some(guar)));
     }
     let sp = cx.with_def_site_ctxt(sp);
     base::MacEager::expr(cx.expr_byte_str(sp, accumulator))
diff --git a/compiler/rustc_builtin_macros/src/concat_idents.rs b/compiler/rustc_builtin_macros/src/concat_idents.rs
index 17fd3901cc6..29d3f6164aa 100644
--- a/compiler/rustc_builtin_macros/src/concat_idents.rs
+++ b/compiler/rustc_builtin_macros/src/concat_idents.rs
@@ -14,8 +14,8 @@ pub fn expand_concat_idents<'cx>(
     tts: TokenStream,
 ) -> Box<dyn base::MacResult + 'cx> {
     if tts.is_empty() {
-        cx.dcx().emit_err(errors::ConcatIdentsMissingArgs { span: sp });
-        return DummyResult::any(sp);
+        let guar = cx.dcx().emit_err(errors::ConcatIdentsMissingArgs { span: sp });
+        return DummyResult::any(sp, guar);
     }
 
     let mut res_str = String::new();
@@ -24,8 +24,8 @@ pub fn expand_concat_idents<'cx>(
             match e {
                 TokenTree::Token(Token { kind: token::Comma, .. }, _) => {}
                 _ => {
-                    cx.dcx().emit_err(errors::ConcatIdentsMissingComma { span: sp });
-                    return DummyResult::any(sp);
+                    let guar = cx.dcx().emit_err(errors::ConcatIdentsMissingComma { span: sp });
+                    return DummyResult::any(sp, guar);
                 }
             }
         } else {
@@ -36,8 +36,8 @@ pub fn expand_concat_idents<'cx>(
                 }
             }
 
-            cx.dcx().emit_err(errors::ConcatIdentsIdentArgs { span: sp });
-            return DummyResult::any(sp);
+            let guar = cx.dcx().emit_err(errors::ConcatIdentsIdentArgs { span: sp });
+            return DummyResult::any(sp, guar);
         }
     }
 
diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs
index 0bd2d423a29..386d4a54b65 100644
--- a/compiler/rustc_builtin_macros/src/deriving/default.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/default.rs
@@ -6,7 +6,7 @@ use rustc_ast::{attr, walk_list, EnumDef, VariantData};
 use rustc_expand::base::{Annotatable, DummyResult, ExtCtxt};
 use rustc_span::symbol::Ident;
 use rustc_span::symbol::{kw, sym};
-use rustc_span::Span;
+use rustc_span::{ErrorGuaranteed, Span};
 use smallvec::SmallVec;
 use thin_vec::{thin_vec, ThinVec};
 
@@ -83,16 +83,19 @@ fn default_enum_substructure(
     trait_span: Span,
     enum_def: &EnumDef,
 ) -> BlockOrExpr {
-    let expr = if let Ok(default_variant) = extract_default_variant(cx, enum_def, trait_span)
-        && let Ok(_) = validate_default_attribute(cx, default_variant)
-    {
-        // We now know there is exactly one unit variant with exactly one `#[default]` attribute.
-        cx.expr_path(cx.path(
-            default_variant.span,
-            vec![Ident::new(kw::SelfUpper, default_variant.span), default_variant.ident],
-        ))
-    } else {
-        DummyResult::raw_expr(trait_span, true)
+    let expr = match try {
+        let default_variant = extract_default_variant(cx, enum_def, trait_span)?;
+        validate_default_attribute(cx, default_variant)?;
+        default_variant
+    } {
+        Ok(default_variant) => {
+            // We now know there is exactly one unit variant with exactly one `#[default]` attribute.
+            cx.expr_path(cx.path(
+                default_variant.span,
+                vec![Ident::new(kw::SelfUpper, default_variant.span), default_variant.ident],
+            ))
+        }
+        Err(guar) => DummyResult::raw_expr(trait_span, Some(guar)),
     };
     BlockOrExpr::new_expr(expr)
 }
@@ -101,7 +104,7 @@ fn extract_default_variant<'a>(
     cx: &mut ExtCtxt<'_>,
     enum_def: &'a EnumDef,
     trait_span: Span,
-) -> Result<&'a rustc_ast::Variant, ()> {
+) -> Result<&'a rustc_ast::Variant, ErrorGuaranteed> {
     let default_variants: SmallVec<[_; 1]> = enum_def
         .variants
         .iter()
@@ -120,9 +123,9 @@ fn extract_default_variant<'a>(
             let suggs = possible_defaults
                 .map(|v| errors::NoDefaultVariantSugg { span: v.span, ident: v.ident })
                 .collect();
-            cx.dcx().emit_err(errors::NoDefaultVariant { span: trait_span, suggs });
+            let guar = cx.dcx().emit_err(errors::NoDefaultVariant { span: trait_span, suggs });
 
-            return Err(());
+            return Err(guar);
         }
         [first, rest @ ..] => {
             let suggs = default_variants
@@ -140,28 +143,28 @@ fn extract_default_variant<'a>(
                         .then_some(errors::MultipleDefaultsSugg { spans, ident: variant.ident })
                 })
                 .collect();
-            cx.dcx().emit_err(errors::MultipleDefaults {
+            let guar = cx.dcx().emit_err(errors::MultipleDefaults {
                 span: trait_span,
                 first: first.span,
                 additional: rest.iter().map(|v| v.span).collect(),
                 suggs,
             });
-            return Err(());
+            return Err(guar);
         }
     };
 
     if !matches!(variant.data, VariantData::Unit(..)) {
-        cx.dcx().emit_err(errors::NonUnitDefault { span: variant.ident.span });
-        return Err(());
+        let guar = cx.dcx().emit_err(errors::NonUnitDefault { span: variant.ident.span });
+        return Err(guar);
     }
 
     if let Some(non_exhaustive_attr) = attr::find_by_name(&variant.attrs, sym::non_exhaustive) {
-        cx.dcx().emit_err(errors::NonExhaustiveDefault {
+        let guar = cx.dcx().emit_err(errors::NonExhaustiveDefault {
             span: variant.ident.span,
             non_exhaustive: non_exhaustive_attr.span,
         });
 
-        return Err(());
+        return Err(guar);
     }
 
     Ok(variant)
@@ -170,7 +173,7 @@ fn extract_default_variant<'a>(
 fn validate_default_attribute(
     cx: &mut ExtCtxt<'_>,
     default_variant: &rustc_ast::Variant,
-) -> Result<(), ()> {
+) -> Result<(), ErrorGuaranteed> {
     let attrs: SmallVec<[_; 1]> =
         attr::filter_by_name(&default_variant.attrs, kw::Default).collect();
 
@@ -183,7 +186,7 @@ fn validate_default_attribute(
             let sugg = errors::MultipleDefaultAttrsSugg {
                 spans: rest.iter().map(|attr| attr.span).collect(),
             };
-            cx.dcx().emit_err(errors::MultipleDefaultAttrs {
+            let guar = cx.dcx().emit_err(errors::MultipleDefaultAttrs {
                 span: default_variant.ident.span,
                 first: first.span,
                 first_rest: rest[0].span,
@@ -192,13 +195,13 @@ fn validate_default_attribute(
                 sugg,
             });
 
-            return Err(());
+            return Err(guar);
         }
     };
     if !attr.is_word() {
-        cx.dcx().emit_err(errors::DefaultHasArg { span: attr.span });
+        let guar = cx.dcx().emit_err(errors::DefaultHasArg { span: attr.span });
 
-        return Err(());
+        return Err(guar);
     }
     Ok(())
 }
diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs
index a0fd0e3f9be..67ace546ad0 100644
--- a/compiler/rustc_builtin_macros/src/env.rs
+++ b/compiler/rustc_builtin_macros/src/env.rs
@@ -28,8 +28,9 @@ pub fn expand_option_env<'cx>(
     sp: Span,
     tts: TokenStream,
 ) -> Box<dyn base::MacResult + 'cx> {
-    let Some(var) = get_single_str_from_tts(cx, sp, tts, "option_env!") else {
-        return DummyResult::any(sp);
+    let var = match get_single_str_from_tts(cx, sp, tts, "option_env!") {
+        Ok(var) => var,
+        Err(guar) => return DummyResult::any(sp, guar),
     };
 
     let sp = cx.with_def_site_ctxt(sp);
@@ -65,24 +66,25 @@ pub fn expand_env<'cx>(
     tts: TokenStream,
 ) -> Box<dyn base::MacResult + 'cx> {
     let mut exprs = match get_exprs_from_tts(cx, tts) {
-        Some(exprs) if exprs.is_empty() || exprs.len() > 2 => {
-            cx.dcx().emit_err(errors::EnvTakesArgs { span: sp });
-            return DummyResult::any(sp);
+        Ok(exprs) if exprs.is_empty() || exprs.len() > 2 => {
+            let guar = cx.dcx().emit_err(errors::EnvTakesArgs { span: sp });
+            return DummyResult::any(sp, guar);
         }
-        None => return DummyResult::any(sp),
-        Some(exprs) => exprs.into_iter(),
+        Err(guar) => return DummyResult::any(sp, guar),
+        Ok(exprs) => exprs.into_iter(),
     };
 
     let var_expr = exprs.next().unwrap();
-    let Some((var, _)) = expr_to_string(cx, var_expr.clone(), "expected string literal") else {
-        return DummyResult::any(sp);
+    let var = match expr_to_string(cx, var_expr.clone(), "expected string literal") {
+        Ok((var, _)) => var,
+        Err(guar) => return DummyResult::any(sp, guar),
     };
 
     let custom_msg = match exprs.next() {
         None => None,
         Some(second) => match expr_to_string(cx, second, "expected string literal") {
-            None => return DummyResult::any(sp),
-            Some((s, _)) => Some(s),
+            Ok((s, _)) => Some(s),
+            Err(guar) => return DummyResult::any(sp, guar),
         },
     };
 
@@ -100,23 +102,23 @@ pub fn expand_env<'cx>(
                 unreachable!("`expr_to_string` ensures this is a string lit")
             };
 
-            if let Some(msg_from_user) = custom_msg {
-                cx.dcx().emit_err(errors::EnvNotDefinedWithUserMessage { span, msg_from_user });
+            let guar = if let Some(msg_from_user) = custom_msg {
+                cx.dcx().emit_err(errors::EnvNotDefinedWithUserMessage { span, msg_from_user })
             } else if is_cargo_env_var(var.as_str()) {
                 cx.dcx().emit_err(errors::EnvNotDefined::CargoEnvVar {
                     span,
                     var: *symbol,
                     var_expr: var_expr.ast_deref(),
-                });
+                })
             } else {
                 cx.dcx().emit_err(errors::EnvNotDefined::CustomEnvVar {
                     span,
                     var: *symbol,
                     var_expr: var_expr.ast_deref(),
-                });
-            }
+                })
+            };
 
-            return DummyResult::any(sp);
+            return DummyResult::any(sp, guar);
         }
         Some(value) => cx.expr_str(span, value),
     };
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index 3366378d38d..06c2b617706 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -13,7 +13,7 @@ use rustc_expand::base::{self, *};
 use rustc_parse::parser::Recovered;
 use rustc_parse_format as parse;
 use rustc_span::symbol::{Ident, Symbol};
-use rustc_span::{BytePos, InnerSpan, Span};
+use rustc_span::{BytePos, ErrorGuaranteed, InnerSpan, Span};
 
 use rustc_lint_defs::builtin::NAMED_ARGUMENTS_USED_POSITIONALLY;
 use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiagnostics, LintId};
@@ -160,7 +160,7 @@ fn make_format_args(
     ecx: &mut ExtCtxt<'_>,
     input: MacroInput,
     append_newline: bool,
-) -> Result<FormatArgs, ()> {
+) -> Result<FormatArgs, ErrorGuaranteed> {
     let msg = "format argument must be a string literal";
     let unexpanded_fmt_span = input.fmtstr.span;
 
@@ -173,38 +173,41 @@ fn make_format_args(
         }
         Ok(fmt) => fmt,
         Err(err) => {
-            if let Some((mut err, suggested)) = err {
-                if !suggested {
-                    if let ExprKind::Block(block, None) = &efmt.kind
-                        && block.stmts.len() == 1
-                        && let StmtKind::Expr(expr) = &block.stmts[0].kind
-                        && let ExprKind::Path(None, path) = &expr.kind
-                        && path.is_potential_trivial_const_arg()
-                    {
-                        err.multipart_suggestion(
-                            "quote your inlined format argument to use as string literal",
-                            vec![
-                                (unexpanded_fmt_span.shrink_to_hi(), "\"".to_string()),
-                                (unexpanded_fmt_span.shrink_to_lo(), "\"".to_string()),
-                            ],
-                            Applicability::MaybeIncorrect,
-                        );
-                    } else {
-                        let sugg_fmt = match args.explicit_args().len() {
-                            0 => "{}".to_string(),
-                            _ => format!("{}{{}}", "{} ".repeat(args.explicit_args().len())),
-                        };
-                        err.span_suggestion(
-                            unexpanded_fmt_span.shrink_to_lo(),
-                            "you might be missing a string literal to format with",
-                            format!("\"{sugg_fmt}\", "),
-                            Applicability::MaybeIncorrect,
-                        );
+            let guar = match err {
+                Ok((mut err, suggested)) => {
+                    if !suggested {
+                        if let ExprKind::Block(block, None) = &efmt.kind
+                            && block.stmts.len() == 1
+                            && let StmtKind::Expr(expr) = &block.stmts[0].kind
+                            && let ExprKind::Path(None, path) = &expr.kind
+                            && path.is_potential_trivial_const_arg()
+                        {
+                            err.multipart_suggestion(
+                                "quote your inlined format argument to use as string literal",
+                                vec![
+                                    (unexpanded_fmt_span.shrink_to_hi(), "\"".to_string()),
+                                    (unexpanded_fmt_span.shrink_to_lo(), "\"".to_string()),
+                                ],
+                                Applicability::MaybeIncorrect,
+                            );
+                        } else {
+                            let sugg_fmt = match args.explicit_args().len() {
+                                0 => "{}".to_string(),
+                                _ => format!("{}{{}}", "{} ".repeat(args.explicit_args().len())),
+                            };
+                            err.span_suggestion(
+                                unexpanded_fmt_span.shrink_to_lo(),
+                                "you might be missing a string literal to format with",
+                                format!("\"{sugg_fmt}\", "),
+                                Applicability::MaybeIncorrect,
+                            );
+                        }
                     }
+                    err.emit()
                 }
-                err.emit();
-            }
-            return Err(());
+                Err(guar) => guar,
+            };
+            return Err(guar);
         }
     };
 
@@ -293,8 +296,8 @@ fn make_format_args(
                 }
             }
         }
-        ecx.dcx().emit_err(e);
-        return Err(());
+        let guar = ecx.dcx().emit_err(e);
+        return Err(guar);
     }
 
     let to_span = |inner_span: rustc_parse_format::InnerSpan| {
@@ -353,9 +356,9 @@ fn make_format_args(
                     } else {
                         // For the moment capturing variables from format strings expanded from macros is
                         // disabled (see RFC #2795)
-                        ecx.dcx().emit_err(errors::FormatNoArgNamed { span, name });
+                        let guar = ecx.dcx().emit_err(errors::FormatNoArgNamed { span, name });
                         unnamed_arg_after_named_arg = true;
-                        DummyResult::raw_expr(span, true)
+                        DummyResult::raw_expr(span, Some(guar))
                     };
                     Ok(args.add(FormatArgument { kind: FormatArgumentKind::Captured(ident), expr }))
                 }
@@ -972,16 +975,13 @@ fn expand_format_args_impl<'cx>(
 ) -> Box<dyn base::MacResult + 'cx> {
     sp = ecx.with_def_site_ctxt(sp);
     match parse_args(ecx, sp, tts) {
-        Ok(input) => {
-            if let Ok(format_args) = make_format_args(ecx, input, nl) {
-                MacEager::expr(ecx.expr(sp, ExprKind::FormatArgs(P(format_args))))
-            } else {
-                MacEager::expr(DummyResult::raw_expr(sp, true))
-            }
-        }
+        Ok(input) => match make_format_args(ecx, input, nl) {
+            Ok(format_args) => MacEager::expr(ecx.expr(sp, ExprKind::FormatArgs(P(format_args)))),
+            Err(guar) => MacEager::expr(DummyResult::raw_expr(sp, Some(guar))),
+        },
         Err(err) => {
-            err.emit();
-            DummyResult::any(sp)
+            let guar = err.emit();
+            DummyResult::any(sp, guar)
         }
     }
 }
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index d30ccab2394..f344dbcd10c 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -15,6 +15,7 @@
 #![feature(lint_reasons)]
 #![feature(proc_macro_internals)]
 #![feature(proc_macro_quote)]
+#![feature(try_blocks)]
 
 extern crate proc_macro;
 
diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs
index 43d13569d1e..3860057e1d4 100644
--- a/compiler/rustc_builtin_macros/src/source_util.rs
+++ b/compiler/rustc_builtin_macros/src/source_util.rs
@@ -103,15 +103,16 @@ pub fn expand_include<'cx>(
     tts: TokenStream,
 ) -> Box<dyn base::MacResult + 'cx> {
     let sp = cx.with_def_site_ctxt(sp);
-    let Some(file) = get_single_str_from_tts(cx, sp, tts, "include!") else {
-        return DummyResult::any(sp);
+    let file = match get_single_str_from_tts(cx, sp, tts, "include!") {
+        Ok(file) => file,
+        Err(guar) => return DummyResult::any(sp, guar),
     };
     // The file will be added to the code map by the parser
     let file = match resolve_path(&cx.sess, file.as_str(), sp) {
         Ok(f) => f,
         Err(err) => {
-            err.emit();
-            return DummyResult::any(sp);
+            let guar = err.emit();
+            return DummyResult::any(sp, guar);
         }
     };
     let p = new_parser_from_file(cx.parse_sess(), &file, Some(sp));
@@ -130,7 +131,7 @@ pub fn expand_include<'cx>(
     }
     impl<'a> base::MacResult for ExpandResult<'a> {
         fn make_expr(mut self: Box<ExpandResult<'a>>) -> Option<P<ast::Expr>> {
-            let r = base::parse_expr(&mut self.p)?;
+            let expr = base::parse_expr(&mut self.p).ok()?;
             if self.p.token != token::Eof {
                 self.p.sess.buffer_lint(
                     INCOMPLETE_INCLUDE,
@@ -139,7 +140,7 @@ pub fn expand_include<'cx>(
                     "include macro expected single expression in source",
                 );
             }
-            Some(r)
+            Some(expr)
         }
 
         fn make_items(mut self: Box<ExpandResult<'a>>) -> Option<SmallVec<[P<ast::Item>; 1]>> {
@@ -176,14 +177,15 @@ pub fn expand_include_str(
     tts: TokenStream,
 ) -> Box<dyn base::MacResult + 'static> {
     let sp = cx.with_def_site_ctxt(sp);
-    let Some(file) = get_single_str_from_tts(cx, sp, tts, "include_str!") else {
-        return DummyResult::any(sp);
+    let file = match get_single_str_from_tts(cx, sp, tts, "include_str!") {
+        Ok(file) => file,
+        Err(guar) => return DummyResult::any(sp, guar),
     };
     let file = match resolve_path(&cx.sess, file.as_str(), sp) {
         Ok(f) => f,
         Err(err) => {
-            err.emit();
-            return DummyResult::any(sp);
+            let guar = err.emit();
+            return DummyResult::any(sp, guar);
         }
     };
     match cx.source_map().load_binary_file(&file) {
@@ -193,13 +195,13 @@ pub fn expand_include_str(
                 base::MacEager::expr(cx.expr_str(sp, interned_src))
             }
             Err(_) => {
-                cx.dcx().span_err(sp, format!("{} wasn't a utf-8 file", file.display()));
-                DummyResult::any(sp)
+                let guar = cx.dcx().span_err(sp, format!("{} wasn't a utf-8 file", file.display()));
+                DummyResult::any(sp, guar)
             }
         },
         Err(e) => {
-            cx.dcx().span_err(sp, format!("couldn't read {}: {}", file.display(), e));
-            DummyResult::any(sp)
+            let guar = cx.dcx().span_err(sp, format!("couldn't read {}: {}", file.display(), e));
+            DummyResult::any(sp, guar)
         }
     }
 }
@@ -210,14 +212,15 @@ pub fn expand_include_bytes(
     tts: TokenStream,
 ) -> Box<dyn base::MacResult + 'static> {
     let sp = cx.with_def_site_ctxt(sp);
-    let Some(file) = get_single_str_from_tts(cx, sp, tts, "include_bytes!") else {
-        return DummyResult::any(sp);
+    let file = match get_single_str_from_tts(cx, sp, tts, "include_bytes!") {
+        Ok(file) => file,
+        Err(guar) => return DummyResult::any(sp, guar),
     };
     let file = match resolve_path(&cx.sess, file.as_str(), sp) {
         Ok(f) => f,
         Err(err) => {
-            err.emit();
-            return DummyResult::any(sp);
+            let guar = err.emit();
+            return DummyResult::any(sp, guar);
         }
     };
     match cx.source_map().load_binary_file(&file) {
@@ -226,8 +229,8 @@ pub fn expand_include_bytes(
             base::MacEager::expr(expr)
         }
         Err(e) => {
-            cx.dcx().span_err(sp, format!("couldn't read {}: {}", file.display(), e));
-            DummyResult::any(sp)
+            let guar = cx.dcx().span_err(sp, format!("couldn't read {}: {}", file.display(), e));
+            DummyResult::any(sp, guar)
         }
     }
 }
diff --git a/compiler/rustc_builtin_macros/src/type_ascribe.rs b/compiler/rustc_builtin_macros/src/type_ascribe.rs
index 564797012ae..e8b8fe75338 100644
--- a/compiler/rustc_builtin_macros/src/type_ascribe.rs
+++ b/compiler/rustc_builtin_macros/src/type_ascribe.rs
@@ -13,8 +13,8 @@ pub fn expand_type_ascribe(
     let (expr, ty) = match parse_ascribe(cx, tts) {
         Ok(parsed) => parsed,
         Err(err) => {
-            err.emit();
-            return DummyResult::any(span);
+            let guar = err.emit();
+            return DummyResult::any(span, guar);
         }
     };