about summary refs log tree commit diff
path: root/compiler/rustc_attr_parsing/src/context.rs
diff options
context:
space:
mode:
authorJana Dönszelmann <jana@donsz.nl>2025-08-11 11:46:30 +0200
committerJana Dönszelmann <jana@donsz.nl>2025-08-24 09:14:49 +0200
commit3bf61444616fc0b9de1e09031f40be0943823fc5 (patch)
treec7fb122fb12ddd2a76e0bd1c350b48ee648eee07 /compiler/rustc_attr_parsing/src/context.rs
parent4eedad312695d773b6e2e17a4f8082660470c101 (diff)
downloadrust-3bf61444616fc0b9de1e09031f40be0943823fc5.tar.gz
rust-3bf61444616fc0b9de1e09031f40be0943823fc5.zip
Allow errors to be emitted as fatal during attribute parsing
Diffstat (limited to 'compiler/rustc_attr_parsing/src/context.rs')
-rw-r--r--compiler/rustc_attr_parsing/src/context.rs40
1 files changed, 29 insertions, 11 deletions
diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs
index bb701df6053..f30edbfaaa1 100644
--- a/compiler/rustc_attr_parsing/src/context.rs
+++ b/compiler/rustc_attr_parsing/src/context.rs
@@ -5,7 +5,7 @@ use std::sync::LazyLock;
 
 use private::Sealed;
 use rustc_ast::{AttrStyle, MetaItemLit, NodeId};
-use rustc_errors::Diagnostic;
+use rustc_errors::{Diag, Diagnostic, Level};
 use rustc_feature::AttributeTemplate;
 use rustc_hir::attrs::AttributeKind;
 use rustc_hir::lints::{AttributeLint, AttributeLintKind};
@@ -263,11 +263,7 @@ impl Stage for Early {
         sess: &'sess Session,
         diag: impl for<'x> Diagnostic<'x>,
     ) -> ErrorGuaranteed {
-        if self.emit_errors.should_emit() {
-            sess.dcx().emit_err(diag)
-        } else {
-            sess.dcx().create_err(diag).delay_as_bug()
-        }
+        self.should_emit().emit_err_or_delay(sess.dcx().create_err(diag))
     }
 
     fn should_emit(&self) -> ShouldEmit {
@@ -333,7 +329,7 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {
     /// must be delayed until after HIR is built. This method will take care of the details of
     /// that.
     pub(crate) fn emit_lint(&mut self, lint: AttributeLintKind, span: Span) {
-        if !self.stage.should_emit().should_emit() {
+        if matches!(self.stage.should_emit(), ShouldEmit::Nothing) {
             return;
         }
         let id = self.target_id;
@@ -651,8 +647,13 @@ pub enum OmitDoc {
     Skip,
 }
 
-#[derive(Copy, Clone)]
+#[derive(Copy, Clone, Debug)]
 pub enum ShouldEmit {
+    /// The operations will emit errors, and lints, and errors are fatal.
+    ///
+    /// Only relevant when early parsing, in late parsing equivalent to `ErrorsAndLints`.
+    /// Late parsing is never fatal, and instead tries to emit as many diagnostics as possible.
+    EarlyFatal,
     /// The operation will emit errors and lints.
     /// This is usually what you need.
     ErrorsAndLints,
@@ -662,10 +663,27 @@ pub enum ShouldEmit {
 }
 
 impl ShouldEmit {
-    pub fn should_emit(&self) -> bool {
+    pub(crate) fn emit_err_or_delay(&self, diag: Diag<'_>) -> ErrorGuaranteed {
+        match self {
+            ShouldEmit::EarlyFatal if diag.level() == Level::DelayedBug => diag.emit(),
+            ShouldEmit::EarlyFatal => diag.upgrade_to_fatal().emit(),
+            ShouldEmit::ErrorsAndLints => diag.emit(),
+            ShouldEmit::Nothing => diag.delay_as_bug(),
+        }
+    }
+
+    pub(crate) fn maybe_emit_err(&self, diag: Diag<'_>) {
         match self {
-            ShouldEmit::ErrorsAndLints => true,
-            ShouldEmit::Nothing => false,
+            ShouldEmit::EarlyFatal if diag.level() == Level::DelayedBug => {
+                diag.emit();
+            }
+            ShouldEmit::EarlyFatal => {
+                diag.upgrade_to_fatal().emit();
+            }
+            ShouldEmit::ErrorsAndLints => {
+                diag.emit();
+            }
+            ShouldEmit::Nothing => {}
         }
     }
 }