From 114380d215931bef6037e2c9b16397a3071a1800 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 1 Dec 2023 14:08:10 +1100 Subject: [PATCH 01/13] Give `Handler::fatal` and `Session::fatal` the same return type. Currently, `Handler::fatal` returns `FatalError`. But `Session::fatal` returns `!`, because it calls `Handler::fatal` and then calls `raise` on the result. This inconsistency is unfortunate. This commit changes `Handler::fatal` to do the `raise` itself, changing its return type to `!`. This is safe because there are only two calls to `Handler::fatal`, one in `rustc_session` and one in `rustc_codegen_cranelift`, and they both call `raise` on the result. `HandlerInner::fatal` still returns `FatalError`, so I renamed it `fatal_no_raise` to emphasise the return type difference. --- .../src/concurrency_limiter.rs | 2 +- compiler/rustc_errors/src/lib.rs | 13 +++++++------ compiler/rustc_session/src/session.rs | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/concurrency_limiter.rs b/compiler/rustc_codegen_cranelift/src/concurrency_limiter.rs index 20f2ee4c76a57..978891f2b0db5 100644 --- a/compiler/rustc_codegen_cranelift/src/concurrency_limiter.rs +++ b/compiler/rustc_codegen_cranelift/src/concurrency_limiter.rs @@ -64,7 +64,7 @@ impl ConcurrencyLimiter { // Make sure to drop the mutex guard first to prevent poisoning the mutex. drop(state); if let Some(err) = err { - handler.fatal(err).raise(); + handler.fatal(err); } else { // The error was already emitted, but compilation continued. Raise a silent // fatal error. diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 5966fd80f979b..383bec2fa8fc9 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -1034,10 +1034,9 @@ impl Handler { db } - // NOTE: intentionally doesn't raise an error so rustc_codegen_ssa only reports fatal errors in the main thread #[rustc_lint_diagnostics] - pub fn fatal(&self, msg: impl Into) -> FatalError { - self.inner.borrow_mut().fatal(msg) + pub fn fatal(&self, msg: impl Into) -> ! { + self.inner.borrow_mut().fatal_no_raise(msg).raise() } #[rustc_lint_diagnostics] @@ -1469,10 +1468,10 @@ impl HandlerInner { DiagnosticMessage::Str(warnings), )), (_, 0) => { - let _ = self.fatal(errors); + let _ = self.fatal_no_raise(errors); } (_, _) => { - let _ = self.fatal(format!("{errors}; {warnings}")); + let _ = self.fatal_no_raise(format!("{errors}; {warnings}")); } } @@ -1631,7 +1630,9 @@ impl HandlerInner { self.emit_diagnostic(&mut Diagnostic::new(FailureNote, msg)); } - fn fatal(&mut self, msg: impl Into) -> FatalError { + // Note: unlike `Handler::fatal`, this doesn't return `!`, because that is + // inappropriate for some of its call sites. + fn fatal_no_raise(&mut self, msg: impl Into) -> FatalError { self.emit(Fatal, msg); FatalError } diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index c6f435a8f9204..a53160a5ab4a0 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -461,7 +461,7 @@ impl Session { } #[rustc_lint_diagnostics] pub fn fatal(&self, msg: impl Into) -> ! { - self.diagnostic().fatal(msg).raise() + self.diagnostic().fatal(msg) } #[rustc_lint_diagnostics] #[track_caller] From d4933aaf1fe182e32058928354b86b92f539c19b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Sun, 3 Dec 2023 22:01:57 +1100 Subject: [PATCH 02/13] Inline and remove `DiagnosticBuilder::new_diagnostic_*` functions. They each have a single call site. --- .../rustc_errors/src/diagnostic_builder.rs | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 3823a1707ec77..df40dda7f8994 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -254,13 +254,6 @@ impl<'a> DiagnosticBuilder<'a, Noted> { /// `struct_*` methods on [`Handler`]. pub(crate) fn new_note(handler: &'a Handler, message: impl Into) -> Self { let diagnostic = Diagnostic::new_with_code(Level::Note, None, message); - Self::new_diagnostic_note(handler, diagnostic) - } - - /// Creates a new `DiagnosticBuilder` with an already constructed - /// diagnostic. - pub(crate) fn new_diagnostic_note(handler: &'a Handler, diagnostic: Diagnostic) -> Self { - debug!("Created new diagnostic"); Self { inner: DiagnosticBuilderInner { state: DiagnosticBuilderState::Emittable(handler), @@ -305,13 +298,6 @@ impl<'a> DiagnosticBuilder<'a, Bug> { #[track_caller] pub(crate) fn new_bug(handler: &'a Handler, message: impl Into) -> Self { let diagnostic = Diagnostic::new_with_code(Level::Bug, None, message); - Self::new_diagnostic_bug(handler, diagnostic) - } - - /// Creates a new `DiagnosticBuilder` with an already constructed - /// diagnostic. - pub(crate) fn new_diagnostic_bug(handler: &'a Handler, diagnostic: Diagnostic) -> Self { - debug!("Created new diagnostic bug"); Self { inner: DiagnosticBuilderInner { state: DiagnosticBuilderState::Emittable(handler), @@ -394,16 +380,6 @@ impl<'a> DiagnosticBuilder<'a, rustc_span::fatal_error::FatalError> { message: impl Into, ) -> Self { let diagnostic = Diagnostic::new_with_code(Level::Fatal, None, message); - Self::new_diagnostic_almost_fatal(handler, diagnostic) - } - - /// Creates a new `DiagnosticBuilder` with an already constructed - /// diagnostic. - pub(crate) fn new_diagnostic_almost_fatal( - handler: &'a Handler, - diagnostic: Diagnostic, - ) -> Self { - debug!("Created new diagnostic"); Self { inner: DiagnosticBuilderInner { state: DiagnosticBuilderState::Emittable(handler), From ab640ca86b5915703b6adb75710dd57d3144def5 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Sun, 3 Dec 2023 22:26:34 +1100 Subject: [PATCH 03/13] Inline and remove more `DiagnosticBuilder::new_diagnostic_*` functions. They each have a single call site. Note: the `make_diagnostic_builder` calls in `lib.rs` will be replaced in a subsequent commit. --- .../rustc_errors/src/diagnostic_builder.rs | 105 +++++------------- compiler/rustc_errors/src/lib.rs | 6 +- 2 files changed, 28 insertions(+), 83 deletions(-) diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index df40dda7f8994..5e0d8c8b89340 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -116,26 +116,6 @@ pub trait EmissionGuarantee: Sized { } impl<'a> DiagnosticBuilder<'a, ErrorGuaranteed> { - /// Convenience function for internal use, clients should use one of the - /// `struct_*` methods on [`Handler`]. - #[track_caller] - pub(crate) fn new_guaranteeing_error>( - handler: &'a Handler, - message: M, - ) -> Self { - Self { - inner: DiagnosticBuilderInner { - state: DiagnosticBuilderState::Emittable(handler), - diagnostic: Box::new(Diagnostic::new_with_code( - Level::Error { lint: false }, - None, - message, - )), - }, - _marker: PhantomData, - } - } - /// Discard the guarantee `.emit()` would return, in favor of having the /// type `DiagnosticBuilder<'a, ()>`. This may be necessary whenever there /// is a common codepath handling both errors and warnings. @@ -189,7 +169,13 @@ impl EmissionGuarantee for ErrorGuaranteed { handler: &Handler, msg: impl Into, ) -> DiagnosticBuilder<'_, Self> { - DiagnosticBuilder::new_guaranteeing_error(handler, msg) + DiagnosticBuilder { + inner: DiagnosticBuilderInner { + state: DiagnosticBuilderState::Emittable(handler), + diagnostic: Box::new(Diagnostic::new(Level::Error { lint: false }, msg)), + }, + _marker: PhantomData, + } } } @@ -249,21 +235,6 @@ impl EmissionGuarantee for () { #[derive(Copy, Clone)] pub struct Noted; -impl<'a> DiagnosticBuilder<'a, Noted> { - /// Convenience function for internal use, clients should use one of the - /// `struct_*` methods on [`Handler`]. - pub(crate) fn new_note(handler: &'a Handler, message: impl Into) -> Self { - let diagnostic = Diagnostic::new_with_code(Level::Note, None, message); - Self { - inner: DiagnosticBuilderInner { - state: DiagnosticBuilderState::Emittable(handler), - diagnostic: Box::new(diagnostic), - }, - _marker: PhantomData, - } - } -} - impl EmissionGuarantee for Noted { fn diagnostic_builder_emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self { match db.inner.state { @@ -283,31 +254,21 @@ impl EmissionGuarantee for Noted { handler: &Handler, msg: impl Into, ) -> DiagnosticBuilder<'_, Self> { - DiagnosticBuilder::new_note(handler, msg) - } -} - -/// Marker type which enables implementation of `create_bug` and `emit_bug` functions for -/// bug struct diagnostics. -#[derive(Copy, Clone)] -pub struct Bug; - -impl<'a> DiagnosticBuilder<'a, Bug> { - /// Convenience function for internal use, clients should use one of the - /// `struct_*` methods on [`Handler`]. - #[track_caller] - pub(crate) fn new_bug(handler: &'a Handler, message: impl Into) -> Self { - let diagnostic = Diagnostic::new_with_code(Level::Bug, None, message); - Self { + DiagnosticBuilder { inner: DiagnosticBuilderInner { state: DiagnosticBuilderState::Emittable(handler), - diagnostic: Box::new(diagnostic), + diagnostic: Box::new(Diagnostic::new_with_code(Level::Note, None, msg)), }, _marker: PhantomData, } } } +/// Marker type which enables implementation of `create_bug` and `emit_bug` functions for +/// bug struct diagnostics. +#[derive(Copy, Clone)] +pub struct Bug; + impl EmissionGuarantee for Bug { fn diagnostic_builder_emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self { match db.inner.state { @@ -328,19 +289,10 @@ impl EmissionGuarantee for Bug { handler: &Handler, msg: impl Into, ) -> DiagnosticBuilder<'_, Self> { - DiagnosticBuilder::new_bug(handler, msg) - } -} - -impl<'a> DiagnosticBuilder<'a, !> { - /// Convenience function for internal use, clients should use one of the - /// `struct_*` methods on [`Handler`]. - #[track_caller] - pub(crate) fn new_fatal(handler: &'a Handler, message: impl Into) -> Self { - Self { + DiagnosticBuilder { inner: DiagnosticBuilderInner { state: DiagnosticBuilderState::Emittable(handler), - diagnostic: Box::new(Diagnostic::new_with_code(Level::Fatal, None, message)), + diagnostic: Box::new(Diagnostic::new_with_code(Level::Bug, None, msg)), }, _marker: PhantomData, } @@ -367,23 +319,10 @@ impl EmissionGuarantee for ! { handler: &Handler, msg: impl Into, ) -> DiagnosticBuilder<'_, Self> { - DiagnosticBuilder::new_fatal(handler, msg) - } -} - -impl<'a> DiagnosticBuilder<'a, rustc_span::fatal_error::FatalError> { - /// Convenience function for internal use, clients should use one of the - /// `struct_*` methods on [`Handler`]. - #[track_caller] - pub(crate) fn new_almost_fatal( - handler: &'a Handler, - message: impl Into, - ) -> Self { - let diagnostic = Diagnostic::new_with_code(Level::Fatal, None, message); - Self { + DiagnosticBuilder { inner: DiagnosticBuilderInner { state: DiagnosticBuilderState::Emittable(handler), - diagnostic: Box::new(diagnostic), + diagnostic: Box::new(Diagnostic::new_with_code(Level::Fatal, None, msg)), }, _marker: PhantomData, } @@ -410,7 +349,13 @@ impl EmissionGuarantee for rustc_span::fatal_error::FatalError { handler: &Handler, msg: impl Into, ) -> DiagnosticBuilder<'_, Self> { - DiagnosticBuilder::new_almost_fatal(handler, msg) + DiagnosticBuilder { + inner: DiagnosticBuilderInner { + state: DiagnosticBuilderState::Emittable(handler), + diagnostic: Box::new(Diagnostic::new_with_code(Level::Fatal, None, msg)), + }, + _marker: PhantomData, + } } } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 383bec2fa8fc9..d9baadc68d77d 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -776,7 +776,7 @@ impl Handler { #[rustc_lint_diagnostics] #[track_caller] pub fn struct_warn(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { - DiagnosticBuilder::new(self, Level::Warning(None), msg) + <()>::make_diagnostic_builder(self, msg) } /// Construct a builder at the `Warning` level with the `msg`. The `id` is used for @@ -847,7 +847,7 @@ impl Handler { &self, msg: impl Into, ) -> DiagnosticBuilder<'_, ErrorGuaranteed> { - DiagnosticBuilder::new_guaranteeing_error(self, msg) + ErrorGuaranteed::make_diagnostic_builder(self, msg) } /// This should only be used by `rustc_middle::lint::struct_lint_level`. Do not use it for hard errors. @@ -914,7 +914,7 @@ impl Handler { #[rustc_lint_diagnostics] #[track_caller] pub fn struct_fatal(&self, msg: impl Into) -> DiagnosticBuilder<'_, !> { - DiagnosticBuilder::new_fatal(self, msg) + ::make_diagnostic_builder(self, msg) } /// Construct a builder at the `Help` level with the `msg`. From 6a95dee395b65ecf68712a987df1a2d60debd597 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 4 Dec 2023 08:43:18 +1100 Subject: [PATCH 04/13] Rename some arguments. `sess` is a terribly misleading name for a `Handler`! This confused me for a bit. --- compiler/rustc_codegen_gcc/src/errors.rs | 4 ++-- compiler/rustc_codegen_llvm/src/errors.rs | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/errors.rs b/compiler/rustc_codegen_gcc/src/errors.rs index 4bf3b71f503d6..5fc4b12d7e699 100644 --- a/compiler/rustc_codegen_gcc/src/errors.rs +++ b/compiler/rustc_codegen_gcc/src/errors.rs @@ -111,8 +111,8 @@ pub(crate) struct TargetFeatureDisableOrEnable<'a> { pub(crate) struct MissingFeatures; impl IntoDiagnostic<'_, ErrorGuaranteed> for TargetFeatureDisableOrEnable<'_> { - fn into_diagnostic(self, sess: &'_ Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut diag = sess.struct_err(fluent::codegen_gcc_target_feature_disable_or_enable); + fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> { + let mut diag = handler.struct_err(fluent::codegen_gcc_target_feature_disable_or_enable); if let Some(span) = self.span { diag.set_span(span); }; diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index 10ca5ad802a05..e5407ba4dd12e 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -102,12 +102,12 @@ pub(crate) struct DynamicLinkingWithLTO; pub(crate) struct ParseTargetMachineConfig<'a>(pub LlvmError<'a>); impl IntoDiagnostic<'_, EM> for ParseTargetMachineConfig<'_> { - fn into_diagnostic(self, sess: &'_ Handler) -> DiagnosticBuilder<'_, EM> { - let diag: DiagnosticBuilder<'_, EM> = self.0.into_diagnostic(sess); + fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, EM> { + let diag: DiagnosticBuilder<'_, EM> = self.0.into_diagnostic(handler); let (message, _) = diag.styled_message().first().expect("`LlvmError` with no message"); - let message = sess.eagerly_translate_to_string(message.clone(), diag.args()); + let message = handler.eagerly_translate_to_string(message.clone(), diag.args()); - let mut diag = sess.struct_diagnostic(fluent::codegen_llvm_parse_target_machine_config); + let mut diag = handler.struct_diagnostic(fluent::codegen_llvm_parse_target_machine_config); diag.set_arg("error", message); diag } @@ -124,8 +124,8 @@ pub(crate) struct TargetFeatureDisableOrEnable<'a> { pub(crate) struct MissingFeatures; impl IntoDiagnostic<'_, ErrorGuaranteed> for TargetFeatureDisableOrEnable<'_> { - fn into_diagnostic(self, sess: &'_ Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut diag = sess.struct_err(fluent::codegen_llvm_target_feature_disable_or_enable); + fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> { + let mut diag = handler.struct_err(fluent::codegen_llvm_target_feature_disable_or_enable); if let Some(span) = self.span { diag.set_span(span); }; @@ -184,7 +184,7 @@ pub enum LlvmError<'a> { pub(crate) struct WithLlvmError<'a>(pub LlvmError<'a>, pub String); impl IntoDiagnostic<'_, EM> for WithLlvmError<'_> { - fn into_diagnostic(self, sess: &'_ Handler) -> DiagnosticBuilder<'_, EM> { + fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, EM> { use LlvmError::*; let msg_with_llvm_err = match &self.0 { WriteOutput { .. } => fluent::codegen_llvm_write_output_with_llvm_err, @@ -201,7 +201,7 @@ impl IntoDiagnostic<'_, EM> for WithLlvmError<'_> { PrepareThinLtoModule => fluent::codegen_llvm_prepare_thin_lto_module_with_llvm_err, ParseBitcode => fluent::codegen_llvm_parse_bitcode_with_llvm_err, }; - let mut diag = self.0.into_diagnostic(sess); + let mut diag = self.0.into_diagnostic(handler); diag.set_primary_message(msg_with_llvm_err); diag.set_arg("llvm_err", self.1); diag From ed95f397cf83a3ca52a66818963e3fd20d6705c3 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 4 Dec 2023 08:46:50 +1100 Subject: [PATCH 05/13] Always use `G` for `EmissionGuarantee` type variables. That's what is mostly used. This commit changes a few `EM` and `E` and `T` type variables to `G`. --- compiler/rustc_codegen_llvm/src/errors.rs | 10 +++++----- compiler/rustc_errors/src/diagnostic_builder.rs | 12 ++++++------ compiler/rustc_session/src/errors.rs | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index e5407ba4dd12e..2ba337a8edf78 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -101,9 +101,9 @@ pub(crate) struct DynamicLinkingWithLTO; pub(crate) struct ParseTargetMachineConfig<'a>(pub LlvmError<'a>); -impl IntoDiagnostic<'_, EM> for ParseTargetMachineConfig<'_> { - fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, EM> { - let diag: DiagnosticBuilder<'_, EM> = self.0.into_diagnostic(handler); +impl IntoDiagnostic<'_, G> for ParseTargetMachineConfig<'_> { + fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, G> { + let diag: DiagnosticBuilder<'_, G> = self.0.into_diagnostic(handler); let (message, _) = diag.styled_message().first().expect("`LlvmError` with no message"); let message = handler.eagerly_translate_to_string(message.clone(), diag.args()); @@ -183,8 +183,8 @@ pub enum LlvmError<'a> { pub(crate) struct WithLlvmError<'a>(pub LlvmError<'a>, pub String); -impl IntoDiagnostic<'_, EM> for WithLlvmError<'_> { - fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, EM> { +impl IntoDiagnostic<'_, G> for WithLlvmError<'_> { + fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, G> { use LlvmError::*; let msg_with_llvm_err = match &self.0 { WriteOutput { .. } => fluent::codegen_llvm_write_output_with_llvm_err, diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 5e0d8c8b89340..1366ef52261e1 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -18,18 +18,18 @@ use std::thread::panicking; /// Trait implemented by error types. This should not be implemented manually. Instead, use /// `#[derive(Diagnostic)]` -- see [rustc_macros::Diagnostic]. #[rustc_diagnostic_item = "IntoDiagnostic"] -pub trait IntoDiagnostic<'a, T: EmissionGuarantee = ErrorGuaranteed> { +pub trait IntoDiagnostic<'a, G: EmissionGuarantee = ErrorGuaranteed> { /// Write out as a diagnostic out of `Handler`. #[must_use] - fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, T>; + fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, G>; } -impl<'a, T, E> IntoDiagnostic<'a, E> for Spanned +impl<'a, T, G> IntoDiagnostic<'a, G> for Spanned where - T: IntoDiagnostic<'a, E>, - E: EmissionGuarantee, + T: IntoDiagnostic<'a, G>, + G: EmissionGuarantee, { - fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, E> { + fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, G> { let mut diag = self.node.into_diagnostic(handler); diag.set_span(self.span); diag diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index 70ee46ea902dc..f7934ce163d15 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -13,12 +13,12 @@ pub struct FeatureGateError { pub explain: DiagnosticMessage, } -impl<'a, T: EmissionGuarantee> IntoDiagnostic<'a, T> for FeatureGateError { +impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for FeatureGateError { #[track_caller] fn into_diagnostic( self, handler: &'a rustc_errors::Handler, - ) -> rustc_errors::DiagnosticBuilder<'a, T> { + ) -> rustc_errors::DiagnosticBuilder<'a, G> { let mut diag = handler.struct_diagnostic(self.explain); diag.set_span(self.span); diag.code(error_code!(E0658)); From 32dc78ede8c3e96475d2fbe818d25bb01faec3ad Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 4 Dec 2023 08:49:18 +1100 Subject: [PATCH 06/13] Avoid `Diagnostic::new_with_code(..., None, ...)`. `Diagnostic::new` can be used instead. --- compiler/rustc_errors/src/diagnostic_builder.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 1366ef52261e1..354fe1da2c998 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -188,7 +188,7 @@ impl<'a> DiagnosticBuilder<'a, ()> { level: Level, message: M, ) -> Self { - let diagnostic = Diagnostic::new_with_code(level, None, message); + let diagnostic = Diagnostic::new(level, message); Self::new_diagnostic(handler, diagnostic) } @@ -257,7 +257,7 @@ impl EmissionGuarantee for Noted { DiagnosticBuilder { inner: DiagnosticBuilderInner { state: DiagnosticBuilderState::Emittable(handler), - diagnostic: Box::new(Diagnostic::new_with_code(Level::Note, None, msg)), + diagnostic: Box::new(Diagnostic::new(Level::Note, msg)), }, _marker: PhantomData, } @@ -292,7 +292,7 @@ impl EmissionGuarantee for Bug { DiagnosticBuilder { inner: DiagnosticBuilderInner { state: DiagnosticBuilderState::Emittable(handler), - diagnostic: Box::new(Diagnostic::new_with_code(Level::Bug, None, msg)), + diagnostic: Box::new(Diagnostic::new(Level::Bug, msg)), }, _marker: PhantomData, } @@ -322,7 +322,7 @@ impl EmissionGuarantee for ! { DiagnosticBuilder { inner: DiagnosticBuilderInner { state: DiagnosticBuilderState::Emittable(handler), - diagnostic: Box::new(Diagnostic::new_with_code(Level::Fatal, None, msg)), + diagnostic: Box::new(Diagnostic::new(Level::Fatal, msg)), }, _marker: PhantomData, } @@ -352,7 +352,7 @@ impl EmissionGuarantee for rustc_span::fatal_error::FatalError { DiagnosticBuilder { inner: DiagnosticBuilderInner { state: DiagnosticBuilderState::Emittable(handler), - diagnostic: Box::new(Diagnostic::new_with_code(Level::Fatal, None, msg)), + diagnostic: Box::new(Diagnostic::new(Level::Fatal, msg)), }, _marker: PhantomData, } From d51b3dbfc61c2746ea8495a83d50c79f7e759359 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 4 Dec 2023 09:35:50 +1100 Subject: [PATCH 07/13] Remove some unused code, and downgrade some `pub`s. --- compiler/rustc_errors/src/diagnostic.rs | 43 +++---------------- .../rustc_errors/src/diagnostic_builder.rs | 7 --- compiler/rustc_expand/src/base.rs | 5 --- 3 files changed, 6 insertions(+), 49 deletions(-) diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 0aaa8ae69e16f..6aaf4a0f5cff2 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -239,7 +239,7 @@ impl Diagnostic { } #[track_caller] - pub fn new_with_code>( + pub(crate) fn new_with_code>( level: Level, code: Option, message: M, @@ -281,7 +281,7 @@ impl Diagnostic { } } - pub fn update_unstable_expectation_id( + pub(crate) fn update_unstable_expectation_id( &mut self, unstable_to_stable: &FxHashMap, ) { @@ -307,14 +307,14 @@ impl Diagnostic { } /// Indicates whether this diagnostic should show up in cargo's future breakage report. - pub fn has_future_breakage(&self) -> bool { + pub(crate) fn has_future_breakage(&self) -> bool { match self.code { Some(DiagnosticId::Lint { has_future_breakage, .. }) => has_future_breakage, _ => false, } } - pub fn is_force_warn(&self) -> bool { + pub(crate) fn is_force_warn(&self) -> bool { match self.code { Some(DiagnosticId::Lint { is_force_warn, .. }) => is_force_warn, _ => false, @@ -391,29 +391,6 @@ impl Diagnostic { self.note_expected_found_extra(expected_label, expected, found_label, found, &"", &"") } - pub fn note_unsuccessful_coercion( - &mut self, - expected: DiagnosticStyledString, - found: DiagnosticStyledString, - ) -> &mut Self { - let mut msg: Vec<_> = - vec![(Cow::from("required when trying to coerce from type `"), Style::NoStyle)]; - msg.extend(expected.0.iter().map(|x| match *x { - StringPart::Normal(ref s) => (Cow::from(s.clone()), Style::NoStyle), - StringPart::Highlighted(ref s) => (Cow::from(s.clone()), Style::Highlight), - })); - msg.push((Cow::from("` to type '"), Style::NoStyle)); - msg.extend(found.0.iter().map(|x| match *x { - StringPart::Normal(ref s) => (Cow::from(s.clone()), Style::NoStyle), - StringPart::Highlighted(ref s) => (Cow::from(s.clone()), Style::Highlight), - })); - msg.push((Cow::from("`"), Style::NoStyle)); - - // For now, just attach these as notes - self.highlighted_note(msg); - self - } - pub fn note_expected_found_extra( &mut self, expected_label: &dyn fmt::Display, @@ -475,7 +452,7 @@ impl Diagnostic { self } - pub fn highlighted_note>( + fn highlighted_note>( &mut self, msg: Vec<(M, Style)>, ) -> &mut Self { @@ -572,14 +549,6 @@ impl Diagnostic { self } - /// Clear any existing suggestions. - pub fn clear_suggestions(&mut self) -> &mut Self { - if let Ok(suggestions) = &mut self.suggestions { - suggestions.clear(); - } - self - } - /// Helper for pushing to `self.suggestions`, if available (not disable). fn push_suggestion(&mut self, suggestion: CodeSuggestion) { if let Ok(suggestions) = &mut self.suggestions { @@ -992,7 +961,7 @@ impl Diagnostic { /// Helper function that takes a `SubdiagnosticMessage` and returns a `DiagnosticMessage` by /// combining it with the primary message of the diagnostic (if translatable, otherwise it just /// passes the user's string along). - pub(crate) fn subdiagnostic_message_to_diagnostic_message( + fn subdiagnostic_message_to_diagnostic_message( &self, attr: impl Into, ) -> DiagnosticMessage { diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 354fe1da2c998..fefff8d152744 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -547,12 +547,6 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> { found_extra: &dyn fmt::Display, ) -> &mut Self); - forward!(pub fn note_unsuccessful_coercion( - &mut self, - expected: DiagnosticStyledString, - found: DiagnosticStyledString, - ) -> &mut Self); - forward!(pub fn note(&mut self, msg: impl Into) -> &mut Self); forward!(pub fn note_once(&mut self, msg: impl Into) -> &mut Self); forward!(pub fn span_note( @@ -581,7 +575,6 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> { forward!(pub fn set_is_lint(&mut self,) -> &mut Self); forward!(pub fn disable_suggestions(&mut self,) -> &mut Self); - forward!(pub fn clear_suggestions(&mut self,) -> &mut Self); forward!(pub fn multipart_suggestion( &mut self, diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 91f3ca1d1156e..74f46efb365b2 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -1145,11 +1145,6 @@ impl<'a> ExtCtxt<'a> { pub fn span_err>(&self, sp: S, msg: impl Into) { self.sess.diagnostic().span_err(sp, msg); } - #[rustc_lint_diagnostics] - #[track_caller] - pub fn span_warn>(&self, sp: S, msg: impl Into) { - self.sess.diagnostic().span_warn(sp, msg); - } pub fn span_bug>(&self, sp: S, msg: impl Into) -> ! { self.sess.diagnostic().span_bug(sp, msg); } From b7e18cabd2af625c2582ab0ce0fecc9b5437a512 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 4 Dec 2023 10:11:39 +1100 Subject: [PATCH 08/13] De-genericize some `IntoDiagnostic` impls. These impls are all needed for just a single `IntoDiagnostic` type, not a family of them. Note that `ErrorGuaranteed` is the default type parameter for `IntoDiagnostic`. --- compiler/rustc_builtin_macros/src/errors.rs | 10 +++++----- compiler/rustc_codegen_llvm/src/errors.rs | 8 ++++---- compiler/rustc_mir_transform/src/errors.rs | 6 +++--- compiler/rustc_parse/src/errors.rs | 10 +++++----- compiler/rustc_session/src/errors.rs | 6 +++--- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index fde4270334b67..0a3af2c2e1330 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -1,5 +1,5 @@ use rustc_errors::{ - AddToDiagnostic, DiagnosticBuilder, EmissionGuarantee, Handler, IntoDiagnostic, MultiSpan, + AddToDiagnostic, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic, MultiSpan, SingleLabelManySpans, }; use rustc_macros::{Diagnostic, Subdiagnostic}; @@ -446,9 +446,9 @@ pub(crate) struct EnvNotDefinedWithUserMessage { } // Hand-written implementation to support custom user messages. -impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for EnvNotDefinedWithUserMessage { +impl<'a> IntoDiagnostic<'a> for EnvNotDefinedWithUserMessage { #[track_caller] - fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, G> { + fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> { #[expect( rustc::untranslatable_diagnostic, reason = "cannot translate user-provided messages" @@ -801,8 +801,8 @@ pub(crate) struct AsmClobberNoReg { pub(crate) clobbers: Vec, } -impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for AsmClobberNoReg { - fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, G> { +impl<'a> IntoDiagnostic<'a> for AsmClobberNoReg { + fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> { let mut diag = handler.struct_diagnostic(crate::fluent_generated::builtin_macros_asm_clobber_no_reg); diag.set_span(self.spans.clone()); diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index 2ba337a8edf78..57ea13ddcd6a8 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -5,7 +5,7 @@ use std::path::Path; use crate::fluent_generated as fluent; use rustc_data_structures::small_c_str::SmallCStr; use rustc_errors::{ - DiagnosticBuilder, EmissionGuarantee, ErrorGuaranteed, Handler, IntoDiagnostic, + DiagnosticBuilder, EmissionGuarantee, ErrorGuaranteed, FatalError, Handler, IntoDiagnostic, }; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::Span; @@ -101,9 +101,9 @@ pub(crate) struct DynamicLinkingWithLTO; pub(crate) struct ParseTargetMachineConfig<'a>(pub LlvmError<'a>); -impl IntoDiagnostic<'_, G> for ParseTargetMachineConfig<'_> { - fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, G> { - let diag: DiagnosticBuilder<'_, G> = self.0.into_diagnostic(handler); +impl IntoDiagnostic<'_, FatalError> for ParseTargetMachineConfig<'_> { + fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, FatalError> { + let diag: DiagnosticBuilder<'_, FatalError> = self.0.into_diagnostic(handler); let (message, _) = diag.styled_message().first().expect("`LlvmError` with no message"); let message = handler.eagerly_translate_to_string(message.clone(), diag.args()); diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs index 3a5270f105ae4..2358661738a55 100644 --- a/compiler/rustc_mir_transform/src/errors.rs +++ b/compiler/rustc_mir_transform/src/errors.rs @@ -2,7 +2,7 @@ use std::borrow::Cow; use rustc_errors::{ Applicability, DecorateLint, DiagnosticArgValue, DiagnosticBuilder, DiagnosticMessage, - EmissionGuarantee, Handler, IntoDiagnostic, + EmissionGuarantee, ErrorGuaranteed, Handler, IntoDiagnostic, }; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::mir::{AssertKind, UnsafetyViolationDetails}; @@ -62,9 +62,9 @@ pub(crate) struct RequiresUnsafe { // so we need to eagerly translate the label here, which isn't supported by the derive API // We could also exhaustively list out the primary messages for all unsafe violations, // but this would result in a lot of duplication. -impl<'sess, G: EmissionGuarantee> IntoDiagnostic<'sess, G> for RequiresUnsafe { +impl<'sess> IntoDiagnostic<'sess> for RequiresUnsafe { #[track_caller] - fn into_diagnostic(self, handler: &'sess Handler) -> DiagnosticBuilder<'sess, G> { + fn into_diagnostic(self, handler: &'sess Handler) -> DiagnosticBuilder<'sess, ErrorGuaranteed> { let mut diag = handler.struct_diagnostic(fluent::mir_transform_requires_unsafe); diag.code(rustc_errors::DiagnosticId::Error("E0133".to_string())); diag.set_span(self.span); diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 03e047b297dc5..b6369a8036fe7 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -2,7 +2,7 @@ use std::borrow::Cow; use rustc_ast::token::Token; use rustc_ast::{Path, Visibility}; -use rustc_errors::{AddToDiagnostic, Applicability, EmissionGuarantee, IntoDiagnostic}; +use rustc_errors::{AddToDiagnostic, Applicability, ErrorGuaranteed, IntoDiagnostic}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::edition::{Edition, LATEST_STABLE_EDITION}; @@ -1038,12 +1038,12 @@ pub(crate) struct ExpectedIdentifier { pub help_cannot_start_number: Option, } -impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedIdentifier { +impl<'a> IntoDiagnostic<'a> for ExpectedIdentifier { #[track_caller] fn into_diagnostic( self, handler: &'a rustc_errors::Handler, - ) -> rustc_errors::DiagnosticBuilder<'a, G> { + ) -> rustc_errors::DiagnosticBuilder<'a, ErrorGuaranteed> { let token_descr = TokenDescription::from_token(&self.token); let mut diag = handler.struct_diagnostic(match token_descr { @@ -1095,12 +1095,12 @@ pub(crate) struct ExpectedSemi { pub sugg: ExpectedSemiSugg, } -impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedSemi { +impl<'a> IntoDiagnostic<'a> for ExpectedSemi { #[track_caller] fn into_diagnostic( self, handler: &'a rustc_errors::Handler, - ) -> rustc_errors::DiagnosticBuilder<'a, G> { + ) -> rustc_errors::DiagnosticBuilder<'a, ErrorGuaranteed> { let token_descr = TokenDescription::from_token(&self.token); let mut diag = handler.struct_diagnostic(match token_descr { diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index f7934ce163d15..72c013eb54916 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -3,7 +3,7 @@ use std::num::NonZeroU32; use crate::parse::ParseSess; use rustc_ast::token; use rustc_ast::util::literal::LitError; -use rustc_errors::{error_code, DiagnosticMessage, EmissionGuarantee, IntoDiagnostic, MultiSpan}; +use rustc_errors::{error_code, DiagnosticMessage, ErrorGuaranteed, IntoDiagnostic, MultiSpan}; use rustc_macros::Diagnostic; use rustc_span::{BytePos, Span, Symbol}; use rustc_target::spec::{SplitDebuginfo, StackProtector, TargetTriple}; @@ -13,12 +13,12 @@ pub struct FeatureGateError { pub explain: DiagnosticMessage, } -impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for FeatureGateError { +impl<'a> IntoDiagnostic<'a> for FeatureGateError { #[track_caller] fn into_diagnostic( self, handler: &'a rustc_errors::Handler, - ) -> rustc_errors::DiagnosticBuilder<'a, G> { + ) -> rustc_errors::DiagnosticBuilder<'a, ErrorGuaranteed> { let mut diag = handler.struct_diagnostic(self.explain); diag.set_span(self.span); diag.code(error_code!(E0658)); From 8c20ad6a08702a44a4557a12b5bf7de1a0909461 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 4 Dec 2023 10:44:57 +1100 Subject: [PATCH 09/13] Use `DiagnosticBuilder::new` more. By making it generic, instead of only for `EmissionGuarantee = ()`, we can use it everywhere. --- .../rustc_errors/src/diagnostic_builder.rs | 94 ++++++------------- compiler/rustc_errors/src/lib.rs | 10 +- 2 files changed, 36 insertions(+), 68 deletions(-) diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index fefff8d152744..b8bd86a72e4df 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -169,41 +169,7 @@ impl EmissionGuarantee for ErrorGuaranteed { handler: &Handler, msg: impl Into, ) -> DiagnosticBuilder<'_, Self> { - DiagnosticBuilder { - inner: DiagnosticBuilderInner { - state: DiagnosticBuilderState::Emittable(handler), - diagnostic: Box::new(Diagnostic::new(Level::Error { lint: false }, msg)), - }, - _marker: PhantomData, - } - } -} - -impl<'a> DiagnosticBuilder<'a, ()> { - /// Convenience function for internal use, clients should use one of the - /// `struct_*` methods on [`Handler`]. - #[track_caller] - pub(crate) fn new>( - handler: &'a Handler, - level: Level, - message: M, - ) -> Self { - let diagnostic = Diagnostic::new(level, message); - Self::new_diagnostic(handler, diagnostic) - } - - /// Creates a new `DiagnosticBuilder` with an already constructed - /// diagnostic. - #[track_caller] - pub(crate) fn new_diagnostic(handler: &'a Handler, diagnostic: Diagnostic) -> Self { - debug!("Created new diagnostic"); - Self { - inner: DiagnosticBuilderInner { - state: DiagnosticBuilderState::Emittable(handler), - diagnostic: Box::new(diagnostic), - }, - _marker: PhantomData, - } + DiagnosticBuilder::new(handler, Level::Error { lint: false }, msg) } } @@ -254,13 +220,7 @@ impl EmissionGuarantee for Noted { handler: &Handler, msg: impl Into, ) -> DiagnosticBuilder<'_, Self> { - DiagnosticBuilder { - inner: DiagnosticBuilderInner { - state: DiagnosticBuilderState::Emittable(handler), - diagnostic: Box::new(Diagnostic::new(Level::Note, msg)), - }, - _marker: PhantomData, - } + DiagnosticBuilder::new(handler, Level::Note, msg) } } @@ -289,13 +249,7 @@ impl EmissionGuarantee for Bug { handler: &Handler, msg: impl Into, ) -> DiagnosticBuilder<'_, Self> { - DiagnosticBuilder { - inner: DiagnosticBuilderInner { - state: DiagnosticBuilderState::Emittable(handler), - diagnostic: Box::new(Diagnostic::new(Level::Bug, msg)), - }, - _marker: PhantomData, - } + DiagnosticBuilder::new(handler, Level::Bug, msg) } } @@ -319,13 +273,7 @@ impl EmissionGuarantee for ! { handler: &Handler, msg: impl Into, ) -> DiagnosticBuilder<'_, Self> { - DiagnosticBuilder { - inner: DiagnosticBuilderInner { - state: DiagnosticBuilderState::Emittable(handler), - diagnostic: Box::new(Diagnostic::new(Level::Fatal, msg)), - }, - _marker: PhantomData, - } + DiagnosticBuilder::new(handler, Level::Fatal, msg) } } @@ -349,13 +297,7 @@ impl EmissionGuarantee for rustc_span::fatal_error::FatalError { handler: &Handler, msg: impl Into, ) -> DiagnosticBuilder<'_, Self> { - DiagnosticBuilder { - inner: DiagnosticBuilderInner { - state: DiagnosticBuilderState::Emittable(handler), - diagnostic: Box::new(Diagnostic::new(Level::Fatal, msg)), - }, - _marker: PhantomData, - } + DiagnosticBuilder::new(handler, Level::Fatal, msg) } } @@ -397,6 +339,32 @@ impl DerefMut for DiagnosticBuilder<'_, G> { } impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> { + /// Convenience function for internal use, clients should use one of the + /// `struct_*` methods on [`Handler`]. + #[track_caller] + pub(crate) fn new>( + handler: &'a Handler, + level: Level, + message: M, + ) -> Self { + let diagnostic = Diagnostic::new(level, message); + Self::new_diagnostic(handler, diagnostic) + } + + /// Creates a new `DiagnosticBuilder` with an already constructed + /// diagnostic. + #[track_caller] + pub(crate) fn new_diagnostic(handler: &'a Handler, diagnostic: Diagnostic) -> Self { + debug!("Created new diagnostic"); + Self { + inner: DiagnosticBuilderInner { + state: DiagnosticBuilderState::Emittable(handler), + diagnostic: Box::new(diagnostic), + }, + _marker: PhantomData, + } + } + /// Emit the diagnostic. #[track_caller] pub fn emit(&mut self) -> G { diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index d9baadc68d77d..cfd730eb4ab2d 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -776,7 +776,7 @@ impl Handler { #[rustc_lint_diagnostics] #[track_caller] pub fn struct_warn(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { - <()>::make_diagnostic_builder(self, msg) + DiagnosticBuilder::new(self, Level::Warning(None), msg) } /// Construct a builder at the `Warning` level with the `msg`. The `id` is used for @@ -847,7 +847,7 @@ impl Handler { &self, msg: impl Into, ) -> DiagnosticBuilder<'_, ErrorGuaranteed> { - ErrorGuaranteed::make_diagnostic_builder(self, msg) + DiagnosticBuilder::new(self, Level::Error { lint: false }, msg) } /// This should only be used by `rustc_middle::lint::struct_lint_level`. Do not use it for hard errors. @@ -914,7 +914,7 @@ impl Handler { #[rustc_lint_diagnostics] #[track_caller] pub fn struct_fatal(&self, msg: impl Into) -> DiagnosticBuilder<'_, !> { - ::make_diagnostic_builder(self, msg) + DiagnosticBuilder::new(self, Level::Fatal, msg) } /// Construct a builder at the `Help` level with the `msg`. @@ -1046,12 +1046,12 @@ impl Handler { #[rustc_lint_diagnostics] pub fn warn(&self, msg: impl Into) { - DiagnosticBuilder::new(self, Warning(None), msg).emit(); + DiagnosticBuilder::<()>::new(self, Warning(None), msg).emit(); } #[rustc_lint_diagnostics] pub fn note(&self, msg: impl Into) { - DiagnosticBuilder::new(self, Note, msg).emit(); + DiagnosticBuilder::<()>::new(self, Note, msg).emit(); } pub fn bug(&self, msg: impl Into) -> ! { From a8ff867d5c3f88224cfec66f36b697cac0c6f75e Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 4 Dec 2023 14:06:28 +1100 Subject: [PATCH 10/13] Move some `HandlerInner` functions to `Handler`. `Handler` is a wrapper around `HanderInner`. Some functions on on `Handler` just forward to the samed-named functions on `HandlerInner`. This commit removes as many of those as possible, implementing functions on `Handler` where possible, to avoid the boilerplate required for forwarding. The commit is moderately large but it's very mechanical. --- compiler/rustc_errors/src/lib.rs | 376 ++++++++++++++----------------- 1 file changed, 164 insertions(+), 212 deletions(-) diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index cfd730eb4ab2d..5ff99f065256d 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -554,7 +554,8 @@ impl Drop for HandlerInner { // instead of "require some error happened". Sadly that isn't ideal, as // lints can be `#[allow]`'d, potentially leading to this triggering. // Also, "good path" should be replaced with a better naming. - if !self.has_any_message() && !self.suppressed_expected_diag && !std::thread::panicking() { + let has_any_message = self.err_count > 0 || self.lint_err_count > 0 || self.warn_count > 0; + if !has_any_message && !self.suppressed_expected_diag && !std::thread::panicking() { let bugs = std::mem::replace(&mut self.good_path_delayed_bugs, Vec::new()); self.flush_delayed( bugs, @@ -675,15 +676,46 @@ impl Handler { /// Stash a given diagnostic with the given `Span` and [`StashKey`] as the key. /// Retrieve a stashed diagnostic with `steal_diagnostic`. pub fn stash_diagnostic(&self, span: Span, key: StashKey, diag: Diagnostic) { - self.inner.borrow_mut().stash((span.with_parent(None), key), diag); + let mut inner = self.inner.borrow_mut(); + + let key = (span.with_parent(None), key); + + if diag.is_error() { + if matches!(diag.level, Level::Error { lint: true }) { + inner.lint_err_count += 1; + } else { + inner.err_count += 1; + } + } else { + // Warnings are only automatically flushed if they're forced. + if diag.is_force_warn() { + inner.warn_count += 1; + } + } + + // FIXME(Centril, #69537): Consider reintroducing panic on overwriting a stashed diagnostic + // if/when we have a more robust macro-friendly replacement for `(span, key)` as a key. + // See the PR for a discussion. + inner.stashed_diagnostics.insert(key, diag); } /// Steal a previously stashed diagnostic with the given `Span` and [`StashKey`] as the key. pub fn steal_diagnostic(&self, span: Span, key: StashKey) -> Option> { - self.inner - .borrow_mut() - .steal((span.with_parent(None), key)) - .map(|diag| DiagnosticBuilder::new_diagnostic(self, diag)) + let mut inner = self.inner.borrow_mut(); + let key = (span.with_parent(None), key); + let diag = inner.stashed_diagnostics.remove(&key)?; + if diag.is_error() { + if matches!(diag.level, Level::Error { lint: true }) { + inner.lint_err_count -= 1; + } else { + inner.err_count -= 1; + } + } else { + if diag.is_force_warn() { + inner.warn_count -= 1; + } + } + Some(DiagnosticBuilder::new_diagnostic(self, diag)) } pub fn has_stashed_diagnostic(&self, span: Span, key: StashKey) -> bool { @@ -996,19 +1028,42 @@ impl Handler { } /// For documentation on this, see `Session::span_delayed_bug`. + /// + /// Note: this function used to be called `delay_span_bug`. It was renamed + /// to match similar functions like `span_bug`, `span_err`, etc. #[track_caller] pub fn span_delayed_bug( &self, - span: impl Into, + sp: impl Into, msg: impl Into, ) -> ErrorGuaranteed { - self.inner.borrow_mut().span_delayed_bug(span, msg) + let mut inner = self.inner.borrow_mut(); + + // This is technically `self.treat_err_as_bug()` but `span_delayed_bug` is called before + // incrementing `err_count` by one, so we need to +1 the comparing. + // FIXME: Would be nice to increment err_count in a more coherent way. + if inner.flags.treat_err_as_bug.is_some_and(|c| { + inner.err_count + inner.lint_err_count + inner.delayed_bug_count() + 1 >= c.get() + }) { + // FIXME: don't abort here if report_delayed_bugs is off + inner.span_bug(sp, msg.into()); + } + let mut diagnostic = Diagnostic::new(Level::DelayedBug, msg.into()); + diagnostic.set_span(sp.into()); + inner.emit_diagnostic(&mut diagnostic).unwrap() } // FIXME(eddyb) note the comment inside `impl Drop for HandlerInner`, that's // where the explanation of what "good path" is (also, it should be renamed). pub fn good_path_delayed_bug(&self, msg: impl Into) { - self.inner.borrow_mut().good_path_delayed_bug(msg) + let mut inner = self.inner.borrow_mut(); + + let mut diagnostic = Diagnostic::new(Level::DelayedBug, msg); + if inner.flags.report_delayed_bugs { + inner.emit_diagnostic(&mut diagnostic); + } + let backtrace = std::backtrace::Backtrace::capture(); + inner.good_path_delayed_bugs.push(DelayedDiagnostic::with_backtrace(diagnostic, backtrace)); } #[track_caller] @@ -1041,7 +1096,7 @@ impl Handler { #[rustc_lint_diagnostics] pub fn err(&self, msg: impl Into) -> ErrorGuaranteed { - self.inner.borrow_mut().err(msg) + self.inner.borrow_mut().emit(Error { lint: false }, msg) } #[rustc_lint_diagnostics] @@ -1060,7 +1115,7 @@ impl Handler { #[inline] pub fn err_count(&self) -> usize { - self.inner.borrow().err_count() + self.inner.borrow().err_count } pub fn has_errors(&self) -> Option { @@ -1071,26 +1126,103 @@ impl Handler { } pub fn has_errors_or_lint_errors(&self) -> Option { - self.inner.borrow().has_errors_or_lint_errors().then(|| { + let inner = self.inner.borrow(); + let has_errors_or_lint_errors = inner.has_errors() || inner.lint_err_count > 0; + has_errors_or_lint_errors.then(|| { #[allow(deprecated)] ErrorGuaranteed::unchecked_claim_error_was_emitted() }) } + pub fn has_errors_or_span_delayed_bugs(&self) -> Option { - self.inner.borrow().has_errors_or_span_delayed_bugs().then(|| { + let inner = self.inner.borrow(); + let has_errors_or_span_delayed_bugs = + inner.has_errors() || !inner.span_delayed_bugs.is_empty(); + has_errors_or_span_delayed_bugs.then(|| { #[allow(deprecated)] ErrorGuaranteed::unchecked_claim_error_was_emitted() }) } + pub fn is_compilation_going_to_fail(&self) -> Option { - self.inner.borrow().is_compilation_going_to_fail().then(|| { + let inner = self.inner.borrow(); + let will_fail = + inner.has_errors() || inner.lint_err_count > 0 || !inner.span_delayed_bugs.is_empty(); + will_fail.then(|| { #[allow(deprecated)] ErrorGuaranteed::unchecked_claim_error_was_emitted() }) } pub fn print_error_count(&self, registry: &Registry) { - self.inner.borrow_mut().print_error_count(registry) + let mut inner = self.inner.borrow_mut(); + + inner.emit_stashed_diagnostics(); + + let warnings = match inner.deduplicated_warn_count { + 0 => Cow::from(""), + 1 => Cow::from("1 warning emitted"), + count => Cow::from(format!("{count} warnings emitted")), + }; + let errors = match inner.deduplicated_err_count { + 0 => Cow::from(""), + 1 => Cow::from("aborting due to 1 previous error"), + count => Cow::from(format!("aborting due to {count} previous errors")), + }; + if inner.treat_err_as_bug() { + return; + } + + match (errors.len(), warnings.len()) { + (0, 0) => return, + (0, _) => inner.emitter.emit_diagnostic(&Diagnostic::new( + Level::Warning(None), + DiagnosticMessage::Str(warnings), + )), + (_, 0) => { + let _ = inner.fatal_no_raise(errors); + } + (_, _) => { + let _ = inner.fatal_no_raise(format!("{errors}; {warnings}")); + } + } + + let can_show_explain = inner.emitter.should_show_explain(); + let are_there_diagnostics = !inner.emitted_diagnostic_codes.is_empty(); + if can_show_explain && are_there_diagnostics { + let mut error_codes = inner + .emitted_diagnostic_codes + .iter() + .filter_map(|x| match &x { + DiagnosticId::Error(s) if registry.try_find_description(s).is_ok() => { + Some(s.clone()) + } + _ => None, + }) + .collect::>(); + if !error_codes.is_empty() { + error_codes.sort(); + if error_codes.len() > 1 { + let limit = if error_codes.len() > 9 { 9 } else { error_codes.len() }; + inner.failure_note(format!( + "Some errors have detailed explanations: {}{}", + error_codes[..limit].join(", "), + if error_codes.len() > 9 { "..." } else { "." } + )); + inner.failure_note(format!( + "For more information about an error, try \ + `rustc --explain {}`.", + &error_codes[0] + )); + } else { + inner.failure_note(format!( + "For more information about this error, try \ + `rustc --explain {}`.", + &error_codes[0] + )); + } + } + } } pub fn take_future_breakage_diagnostics(&self) -> Vec { @@ -1098,7 +1230,11 @@ impl Handler { } pub fn abort_if_errors(&self) { - self.inner.borrow_mut().abort_if_errors() + let mut inner = self.inner.borrow_mut(); + inner.emit_stashed_diagnostics(); + if inner.has_errors() { + FatalError.raise(); + } } /// `true` if we haven't taught a diagnostic with this code already. @@ -1107,11 +1243,11 @@ impl Handler { /// Used to suppress emitting the same error multiple times with extended explanation when /// calling `-Zteach`. pub fn must_teach(&self, code: &DiagnosticId) -> bool { - self.inner.borrow_mut().must_teach(code) + self.inner.borrow_mut().taught_diagnostics.insert(code.clone()) } pub fn force_print_diagnostic(&self, db: Diagnostic) { - self.inner.borrow_mut().force_print_diagnostic(db) + self.inner.borrow_mut().emitter.emit_diagnostic(&db); } pub fn emit_diagnostic(&self, diagnostic: &mut Diagnostic) -> Option { @@ -1195,11 +1331,11 @@ impl Handler { mut diag: Diagnostic, sp: impl Into, ) -> Option { - self.inner.borrow_mut().emit_diagnostic(diag.set_span(sp)) + self.emit_diagnostic(diag.set_span(sp)) } pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) { - self.inner.borrow_mut().emit_artifact_notification(path, artifact_type) + self.inner.borrow_mut().emitter.emit_artifact_notification(path, artifact_type); } pub fn emit_future_breakage_report(&self, diags: Vec) { @@ -1218,7 +1354,7 @@ impl Handler { inner.bump_err_count(); } - inner.emit_unused_externs(lint_level, unused_externs) + inner.emitter.emit_unused_externs(lint_level, unused_externs) } pub fn update_unstable_expectation_id( @@ -1269,15 +1405,11 @@ impl Handler { } } +// Note: we prefer implementing operations on `Handler`, rather than +// `HandlerInner`, whenever possible. This minimizes functions where +// `Handler::foo()` just borrows `inner` and forwards a call to +// `HanderInner::foo`. impl HandlerInner { - fn must_teach(&mut self, code: &DiagnosticId) -> bool { - self.taught_diagnostics.insert(code.clone()) - } - - fn force_print_diagnostic(&mut self, db: Diagnostic) { - self.emitter.emit_diagnostic(&db); - } - /// Emit all stashed diagnostics. fn emit_stashed_diagnostics(&mut self) -> Option { let has_errors = self.has_errors(); @@ -1426,17 +1558,9 @@ impl HandlerInner { guaranteed } - fn emit_artifact_notification(&mut self, path: &Path, artifact_type: &str) { - self.emitter.emit_artifact_notification(path, artifact_type); - } - - fn emit_unused_externs(&mut self, lint_level: rustc_lint_defs::Level, unused_externs: &[&str]) { - self.emitter.emit_unused_externs(lint_level, unused_externs); - } - fn treat_err_as_bug(&self) -> bool { self.flags.treat_err_as_bug.is_some_and(|c| { - self.err_count() + self.lint_err_count + self.delayed_bug_count() >= c.get() + self.err_count + self.lint_err_count + self.delayed_bug_count() >= c.get() }) } @@ -1444,141 +1568,8 @@ impl HandlerInner { self.span_delayed_bugs.len() + self.good_path_delayed_bugs.len() } - fn print_error_count(&mut self, registry: &Registry) { - self.emit_stashed_diagnostics(); - - let warnings = match self.deduplicated_warn_count { - 0 => Cow::from(""), - 1 => Cow::from("1 warning emitted"), - count => Cow::from(format!("{count} warnings emitted")), - }; - let errors = match self.deduplicated_err_count { - 0 => Cow::from(""), - 1 => Cow::from("aborting due to 1 previous error"), - count => Cow::from(format!("aborting due to {count} previous errors")), - }; - if self.treat_err_as_bug() { - return; - } - - match (errors.len(), warnings.len()) { - (0, 0) => return, - (0, _) => self.emitter.emit_diagnostic(&Diagnostic::new( - Level::Warning(None), - DiagnosticMessage::Str(warnings), - )), - (_, 0) => { - let _ = self.fatal_no_raise(errors); - } - (_, _) => { - let _ = self.fatal_no_raise(format!("{errors}; {warnings}")); - } - } - - let can_show_explain = self.emitter.should_show_explain(); - let are_there_diagnostics = !self.emitted_diagnostic_codes.is_empty(); - if can_show_explain && are_there_diagnostics { - let mut error_codes = self - .emitted_diagnostic_codes - .iter() - .filter_map(|x| match &x { - DiagnosticId::Error(s) if registry.try_find_description(s).is_ok() => { - Some(s.clone()) - } - _ => None, - }) - .collect::>(); - if !error_codes.is_empty() { - error_codes.sort(); - if error_codes.len() > 1 { - let limit = if error_codes.len() > 9 { 9 } else { error_codes.len() }; - self.failure_note(format!( - "Some errors have detailed explanations: {}{}", - error_codes[..limit].join(", "), - if error_codes.len() > 9 { "..." } else { "." } - )); - self.failure_note(format!( - "For more information about an error, try \ - `rustc --explain {}`.", - &error_codes[0] - )); - } else { - self.failure_note(format!( - "For more information about this error, try \ - `rustc --explain {}`.", - &error_codes[0] - )); - } - } - } - } - - fn stash(&mut self, key: (Span, StashKey), diagnostic: Diagnostic) { - // Track the diagnostic for counts, but don't panic-if-treat-err-as-bug - // yet; that happens when we actually emit the diagnostic. - if diagnostic.is_error() { - if matches!(diagnostic.level, Level::Error { lint: true }) { - self.lint_err_count += 1; - } else { - self.err_count += 1; - } - } else { - // Warnings are only automatically flushed if they're forced. - if diagnostic.is_force_warn() { - self.warn_count += 1; - } - } - - // FIXME(Centril, #69537): Consider reintroducing panic on overwriting a stashed diagnostic - // if/when we have a more robust macro-friendly replacement for `(span, key)` as a key. - // See the PR for a discussion. - self.stashed_diagnostics.insert(key, diagnostic); - } - - fn steal(&mut self, key: (Span, StashKey)) -> Option { - let diagnostic = self.stashed_diagnostics.remove(&key)?; - if diagnostic.is_error() { - if matches!(diagnostic.level, Level::Error { lint: true }) { - self.lint_err_count -= 1; - } else { - self.err_count -= 1; - } - } else { - if diagnostic.is_force_warn() { - self.warn_count -= 1; - } - } - Some(diagnostic) - } - - #[inline] - fn err_count(&self) -> usize { - self.err_count - } - fn has_errors(&self) -> bool { - self.err_count() > 0 - } - fn has_errors_or_lint_errors(&self) -> bool { - self.has_errors() || self.lint_err_count > 0 - } - fn has_errors_or_span_delayed_bugs(&self) -> bool { - self.has_errors() || !self.span_delayed_bugs.is_empty() - } - fn has_any_message(&self) -> bool { - self.err_count() > 0 || self.lint_err_count > 0 || self.warn_count > 0 - } - - fn is_compilation_going_to_fail(&self) -> bool { - self.has_errors() || self.lint_err_count > 0 || !self.span_delayed_bugs.is_empty() - } - - fn abort_if_errors(&mut self) { - self.emit_stashed_diagnostics(); - - if self.has_errors() { - FatalError.raise(); - } + self.err_count > 0 } #[track_caller] @@ -1591,41 +1582,6 @@ impl HandlerInner { self.emit_diagnostic(diag.set_span(sp)); } - /// For documentation on this, see `Session::span_delayed_bug`. - /// - /// Note: this function used to be called `delay_span_bug`. It was renamed - /// to match similar functions like `span_bug`, `span_err`, etc. - #[track_caller] - fn span_delayed_bug( - &mut self, - sp: impl Into, - msg: impl Into, - ) -> ErrorGuaranteed { - // This is technically `self.treat_err_as_bug()` but `span_delayed_bug` is called before - // incrementing `err_count` by one, so we need to +1 the comparing. - // FIXME: Would be nice to increment err_count in a more coherent way. - if self.flags.treat_err_as_bug.is_some_and(|c| { - self.err_count() + self.lint_err_count + self.delayed_bug_count() + 1 >= c.get() - }) { - // FIXME: don't abort here if report_delayed_bugs is off - self.span_bug(sp, msg.into()); - } - let mut diagnostic = Diagnostic::new(Level::DelayedBug, msg.into()); - diagnostic.set_span(sp.into()); - self.emit_diagnostic(&mut diagnostic).unwrap() - } - - // FIXME(eddyb) note the comment inside `impl Drop for HandlerInner`, that's - // where the explanation of what "good path" is (also, it should be renamed). - fn good_path_delayed_bug(&mut self, msg: impl Into) { - let mut diagnostic = Diagnostic::new(Level::DelayedBug, msg); - if self.flags.report_delayed_bugs { - self.emit_diagnostic(&mut diagnostic); - } - let backtrace = std::backtrace::Backtrace::capture(); - self.good_path_delayed_bugs.push(DelayedDiagnostic::with_backtrace(diagnostic, backtrace)); - } - fn failure_note(&mut self, msg: impl Into) { self.emit_diagnostic(&mut Diagnostic::new(FailureNote, msg)); } @@ -1637,10 +1593,6 @@ impl HandlerInner { FatalError } - fn err(&mut self, msg: impl Into) -> ErrorGuaranteed { - self.emit(Error { lint: false }, msg) - } - /// Emit an error; level should be `Error` or `Fatal`. fn emit(&mut self, level: Level, msg: impl Into) -> ErrorGuaranteed { if self.treat_err_as_bug() { @@ -1724,7 +1676,7 @@ impl HandlerInner { fn panic_if_treat_err_as_bug(&self) { if self.treat_err_as_bug() { match ( - self.err_count() + self.lint_err_count, + self.err_count + self.lint_err_count, self.delayed_bug_count(), self.flags.treat_err_as_bug.map(|c| c.get()).unwrap(), ) { From 883bdb7fda9b2eda5e3c1846ed653e7edf4936c4 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 4 Dec 2023 14:27:43 +1100 Subject: [PATCH 11/13] Remove `HandlerInner::emit`. This is weird: `HandlerInner::emit` calls `HandlerInner::emit_diagnostic`, but only after doing a `treat-err-as-bug` check. Which is fine, *except* that there are multiple others paths for an `Error` or `Fatal` diagnostic to be passed to `HandlerInner::emit_diagnostic` without going through `HandlerInner::emit`, e.g. `Handler::span_err` call `Handler::emit_diag_at_span`, which calls `emit_diagnostic`. So that suggests that the coverage for `treat-err-as-bug` is incomplete. This commit removes `HandlerInner::emit` and moves the `treat-err-as-bug` check to `HandlerInner::emit_diagnostic`, so it cannot by bypassed. --- compiler/rustc_errors/src/lib.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 5ff99f065256d..11ac5239445c7 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -1096,7 +1096,10 @@ impl Handler { #[rustc_lint_diagnostics] pub fn err(&self, msg: impl Into) -> ErrorGuaranteed { - self.inner.borrow_mut().emit(Error { lint: false }, msg) + self.inner + .borrow_mut() + .emit_diagnostic(&mut Diagnostic::new(Error { lint: false }, msg)) + .unwrap() } #[rustc_lint_diagnostics] @@ -1126,7 +1129,7 @@ impl Handler { } pub fn has_errors_or_lint_errors(&self) -> Option { - let inner = self.inner.borrow(); + let inner = self.inner.borrow(); let has_errors_or_lint_errors = inner.has_errors() || inner.lint_err_count > 0; has_errors_or_lint_errors.then(|| { #[allow(deprecated)] @@ -1135,7 +1138,7 @@ impl Handler { } pub fn has_errors_or_span_delayed_bugs(&self) -> Option { - let inner = self.inner.borrow(); + let inner = self.inner.borrow(); let has_errors_or_span_delayed_bugs = inner.has_errors() || !inner.span_delayed_bugs.is_empty(); has_errors_or_span_delayed_bugs.then(|| { @@ -1443,6 +1446,11 @@ impl HandlerInner { // FIXME(eddyb) this should ideally take `diagnostic` by value. fn emit_diagnostic(&mut self, diagnostic: &mut Diagnostic) -> Option { + if matches!(diagnostic.level, Level::Error { .. } | Level::Fatal) && self.treat_err_as_bug() + { + diagnostic.level = Level::Bug; + } + // The `LintExpectationId` can be stable or unstable depending on when it was created. // Diagnostics created before the definition of `HirId`s are unstable and can not yet // be stored. Instead, they are buffered until the `LintExpectationId` is replaced by @@ -1589,18 +1597,10 @@ impl HandlerInner { // Note: unlike `Handler::fatal`, this doesn't return `!`, because that is // inappropriate for some of its call sites. fn fatal_no_raise(&mut self, msg: impl Into) -> FatalError { - self.emit(Fatal, msg); + self.emit_diagnostic(&mut Diagnostic::new(Fatal, msg)); FatalError } - /// Emit an error; level should be `Error` or `Fatal`. - fn emit(&mut self, level: Level, msg: impl Into) -> ErrorGuaranteed { - if self.treat_err_as_bug() { - self.bug(msg); - } - self.emit_diagnostic(&mut Diagnostic::new(level, msg)).unwrap() - } - fn bug(&mut self, msg: impl Into) -> ! { self.emit_diagnostic(&mut Diagnostic::new(Bug, msg)); panic::panic_any(ExplicitBug); From 3ab05caa4d196340dd61ce10543f64cb56878676 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 4 Dec 2023 14:48:11 +1100 Subject: [PATCH 12/13] Make `Handler::{err,bug}` more like `Handler::{warn,note}`. --- compiler/rustc_errors/src/lib.rs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 11ac5239445c7..e6faefa612f3d 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -1096,10 +1096,7 @@ impl Handler { #[rustc_lint_diagnostics] pub fn err(&self, msg: impl Into) -> ErrorGuaranteed { - self.inner - .borrow_mut() - .emit_diagnostic(&mut Diagnostic::new(Error { lint: false }, msg)) - .unwrap() + DiagnosticBuilder::::new(self, Error { lint: false }, msg).emit() } #[rustc_lint_diagnostics] @@ -1113,7 +1110,8 @@ impl Handler { } pub fn bug(&self, msg: impl Into) -> ! { - self.inner.borrow_mut().bug(msg) + DiagnosticBuilder::::new(self, Bug, msg).emit(); + panic::panic_any(ExplicitBug); } #[inline] @@ -1601,11 +1599,6 @@ impl HandlerInner { FatalError } - fn bug(&mut self, msg: impl Into) -> ! { - self.emit_diagnostic(&mut Diagnostic::new(Bug, msg)); - panic::panic_any(ExplicitBug); - } - fn flush_delayed( &mut self, bugs: impl IntoIterator, From 7811c976d1a6b014bff0fdada7aaaa1774d31b82 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 4 Dec 2023 15:36:46 +1100 Subject: [PATCH 13/13] Inline and remove `fatal_no_raise`. This makes `Handler::fatal` more like `Handler::{err,warn,bug,note}`. --- compiler/rustc_errors/src/lib.rs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index e6faefa612f3d..daa8a7706eb47 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -1091,7 +1091,7 @@ impl Handler { #[rustc_lint_diagnostics] pub fn fatal(&self, msg: impl Into) -> ! { - self.inner.borrow_mut().fatal_no_raise(msg).raise() + DiagnosticBuilder::::new(self, Fatal, msg).emit().raise() } #[rustc_lint_diagnostics] @@ -1181,10 +1181,10 @@ impl Handler { DiagnosticMessage::Str(warnings), )), (_, 0) => { - let _ = inner.fatal_no_raise(errors); + inner.emit_diagnostic(&mut Diagnostic::new(Fatal, errors)); } (_, _) => { - let _ = inner.fatal_no_raise(format!("{errors}; {warnings}")); + inner.emit_diagnostic(&mut Diagnostic::new(Fatal, format!("{errors}; {warnings}"))); } } @@ -1592,13 +1592,6 @@ impl HandlerInner { self.emit_diagnostic(&mut Diagnostic::new(FailureNote, msg)); } - // Note: unlike `Handler::fatal`, this doesn't return `!`, because that is - // inappropriate for some of its call sites. - fn fatal_no_raise(&mut self, msg: impl Into) -> FatalError { - self.emit_diagnostic(&mut Diagnostic::new(Fatal, msg)); - FatalError - } - fn flush_delayed( &mut self, bugs: impl IntoIterator,