]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_session/src/session.rs
rustc_error: make ErrorReported impossible to construct
[rust.git] / compiler / rustc_session / src / session.rs
index b72be735ce485088b1992b4dbd2b84dfb4c5c9df..7eeb6f90f99d9e5578ccbb39ba7bb3fbece00727 100644 (file)
@@ -19,7 +19,7 @@
 use rustc_errors::emitter::{Emitter, EmitterWriter, HumanReadableErrorType};
 use rustc_errors::json::JsonEmitter;
 use rustc_errors::registry::Registry;
-use rustc_errors::{Diagnostic, DiagnosticBuilder, DiagnosticId, ErrorReported};
+use rustc_errors::{Diagnostic, DiagnosticBuilder, DiagnosticId, ErrorGuaranteed};
 use rustc_macros::HashStable_Generic;
 pub use rustc_span::def_id::StableCrateId;
 use rustc_span::edition::Edition;
@@ -221,7 +221,7 @@ enum DiagnosticBuilderMethod {
 pub trait SessionDiagnostic<'a> {
     /// Write out as a diagnostic out of `sess`.
     #[must_use]
-    fn into_diagnostic(self, sess: &'a Session) -> DiagnosticBuilder<'a, ErrorReported>;
+    fn into_diagnostic(self, sess: &'a Session) -> DiagnosticBuilder<'a, ErrorGuaranteed>;
 }
 
 /// Diagnostic message ID, used by `Session.one_time_diagnostics` to avoid
@@ -262,7 +262,7 @@ fn check_miri_unleashed_features(&self) {
             }
             diag.emit();
             // If we should err, make sure we did.
-            if must_err && !self.has_errors() {
+            if must_err && !self.has_errors().is_some() {
                 // We have skipped a feature gate, and not run into other errors... reject.
                 self.err(
                     "`-Zunleash-the-miri-inside-of-you` may not be used to circumvent feature \
@@ -331,11 +331,18 @@ pub fn struct_span_allow<S: Into<MultiSpan>>(
     pub fn struct_allow(&self, msg: &str) -> DiagnosticBuilder<'_, ()> {
         self.diagnostic().struct_allow(msg)
     }
+    pub fn struct_expect(
+        &self,
+        msg: &str,
+        id: lint::LintExpectationId,
+    ) -> DiagnosticBuilder<'_, ()> {
+        self.diagnostic().struct_expect(msg, id)
+    }
     pub fn struct_span_err<S: Into<MultiSpan>>(
         &self,
         sp: S,
         msg: &str,
-    ) -> DiagnosticBuilder<'_, ErrorReported> {
+    ) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
         self.diagnostic().struct_span_err(sp, msg)
     }
     pub fn struct_span_err_with_code<S: Into<MultiSpan>>(
@@ -343,25 +350,25 @@ pub fn struct_span_err_with_code<S: Into<MultiSpan>>(
         sp: S,
         msg: &str,
         code: DiagnosticId,
-    ) -> DiagnosticBuilder<'_, ErrorReported> {
+    ) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
         self.diagnostic().struct_span_err_with_code(sp, msg, code)
     }
     // FIXME: This method should be removed (every error should have an associated error code).
-    pub fn struct_err(&self, msg: &str) -> DiagnosticBuilder<'_, ErrorReported> {
+    pub fn struct_err(&self, msg: &str) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
         self.diagnostic().struct_err(msg)
     }
     pub fn struct_err_with_code(
         &self,
         msg: &str,
         code: DiagnosticId,
-    ) -> DiagnosticBuilder<'_, ErrorReported> {
+    ) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
         self.diagnostic().struct_err_with_code(msg, code)
     }
     pub fn struct_span_fatal<S: Into<MultiSpan>>(
         &self,
         sp: S,
         msg: &str,
-    ) -> DiagnosticBuilder<'_, ErrorReported> {
+    ) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
         self.diagnostic().struct_span_fatal(sp, msg)
     }
     pub fn struct_span_fatal_with_code<S: Into<MultiSpan>>(
@@ -369,10 +376,10 @@ pub fn struct_span_fatal_with_code<S: Into<MultiSpan>>(
         sp: S,
         msg: &str,
         code: DiagnosticId,
-    ) -> DiagnosticBuilder<'_, ErrorReported> {
+    ) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
         self.diagnostic().struct_span_fatal_with_code(sp, msg, code)
     }
-    pub fn struct_fatal(&self, msg: &str) -> DiagnosticBuilder<'_, ErrorReported> {
+    pub fn struct_fatal(&self, msg: &str) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
         self.diagnostic().struct_fatal(msg)
     }
 
@@ -397,23 +404,23 @@ pub fn span_err_or_warn<S: Into<MultiSpan>>(&self, is_warning: bool, sp: S, msg:
             self.span_err(sp, msg);
         }
     }
-    pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
+    pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ErrorGuaranteed {
         self.diagnostic().span_err(sp, msg)
     }
     pub fn span_err_with_code<S: Into<MultiSpan>>(&self, sp: S, msg: &str, code: DiagnosticId) {
         self.diagnostic().span_err_with_code(sp, &msg, code)
     }
-    pub fn err(&self, msg: &str) {
+    pub fn err(&self, msg: &str) -> ErrorGuaranteed {
         self.diagnostic().err(msg)
     }
-    pub fn emit_err<'a>(&'a self, err: impl SessionDiagnostic<'a>) -> ErrorReported {
+    pub fn emit_err<'a>(&'a self, err: impl SessionDiagnostic<'a>) -> ErrorGuaranteed {
         err.into_diagnostic(self).emit()
     }
     #[inline]
     pub fn err_count(&self) -> usize {
         self.diagnostic().err_count()
     }
-    pub fn has_errors(&self) -> bool {
+    pub fn has_errors(&self) -> Option<ErrorGuaranteed> {
         self.diagnostic().has_errors()
     }
     pub fn has_errors_or_delayed_span_bugs(&self) -> bool {
@@ -422,22 +429,26 @@ pub fn has_errors_or_delayed_span_bugs(&self) -> bool {
     pub fn abort_if_errors(&self) {
         self.diagnostic().abort_if_errors();
     }
-    pub fn compile_status(&self) -> Result<(), ErrorReported> {
-        if self.diagnostic().has_errors_or_lint_errors() {
-            self.diagnostic().emit_stashed_diagnostics();
-            Err(ErrorReported)
+    pub fn compile_status(&self) -> Result<(), ErrorGuaranteed> {
+        if let Some(reported) = self.diagnostic().has_errors_or_lint_errors() {
+            let _ = self.diagnostic().emit_stashed_diagnostics();
+            Err(reported)
         } else {
             Ok(())
         }
     }
     // FIXME(matthewjasper) Remove this method, it should never be needed.
-    pub fn track_errors<F, T>(&self, f: F) -> Result<T, ErrorReported>
+    pub fn track_errors<F, T>(&self, f: F) -> Result<T, ErrorGuaranteed>
     where
         F: FnOnce() -> T,
     {
         let old_count = self.err_count();
         let result = f();
-        if self.err_count() == old_count { Ok(result) } else { Err(ErrorReported) }
+        if self.err_count() == old_count {
+            Ok(result)
+        } else {
+            Err(ErrorGuaranteed::unchecked_claim_error_was_emitted())
+        }
     }
     pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
         self.diagnostic().span_warn(sp, msg)
@@ -450,7 +461,7 @@ pub fn warn(&self, msg: &str) {
     }
     /// Delay a span_bug() call until abort_if_errors()
     #[track_caller]
-    pub fn delay_span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
+    pub fn delay_span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ErrorGuaranteed {
         self.diagnostic().delay_span_bug(sp, msg)
     }
 
@@ -1380,12 +1391,18 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
     let unsupported_sanitizers = sess.opts.debugging_opts.sanitizer - supported_sanitizers;
     match unsupported_sanitizers.into_iter().count() {
         0 => {}
-        1 => sess
-            .err(&format!("{} sanitizer is not supported for this target", unsupported_sanitizers)),
-        _ => sess.err(&format!(
-            "{} sanitizers are not supported for this target",
-            unsupported_sanitizers
-        )),
+        1 => {
+            sess.err(&format!(
+                "{} sanitizer is not supported for this target",
+                unsupported_sanitizers
+            ));
+        }
+        _ => {
+            sess.err(&format!(
+                "{} sanitizers are not supported for this target",
+                unsupported_sanitizers
+            ));
+        }
     }
     // Cannot mix and match sanitizers.
     let mut sanitizer_iter = sess.opts.debugging_opts.sanitizer.into_iter();
@@ -1439,7 +1456,7 @@ pub enum IncrCompSession {
     InvalidBecauseOfErrors { session_directory: PathBuf },
 }
 
-pub fn early_error_no_abort(output: config::ErrorOutputType, msg: &str) {
+pub fn early_error_no_abort(output: config::ErrorOutputType, msg: &str) -> ErrorGuaranteed {
     let emitter: Box<dyn Emitter + sync::Send> = match output {
         config::ErrorOutputType::HumanReadable(kind) => {
             let (short, color_config) = kind.unzip();
@@ -1450,7 +1467,8 @@ pub fn early_error_no_abort(output: config::ErrorOutputType, msg: &str) {
         }
     };
     let handler = rustc_errors::Handler::with_emitter(true, None, emitter);
-    handler.struct_fatal(msg).emit();
+    let reported = handler.struct_fatal(msg).emit();
+    reported
 }
 
 pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {