diff options
| author | Jhonny Bill Mena <jhonnybillm@gmail.com> | 2022-11-23 01:07:36 -0500 |
|---|---|---|
| committer | Jhonny Bill Mena <jhonnybillm@gmail.com> | 2022-12-27 20:59:22 -0500 |
| commit | 27744460e2d0b960a55a28637ba46835484e4335 (patch) | |
| tree | ed12681ff7abedc39bcd136261aed2d1720dda4f /compiler/rustc_errors/src | |
| parent | d1030fab229d25d3ca14b1aaa2fc8e5a6ec932a8 (diff) | |
| download | rust-27744460e2d0b960a55a28637ba46835484e4335.tar.gz rust-27744460e2d0b960a55a28637ba46835484e4335.zip | |
ADD - create and emit Bug support for Diagnostics
UPDATE - migrate constant span_bug to translatable diagnostic.
Diffstat (limited to 'compiler/rustc_errors/src')
| -rw-r--r-- | compiler/rustc_errors/src/diagnostic_builder.rs | 55 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/lib.rs | 14 |
2 files changed, 68 insertions, 1 deletions
diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index a2ed988643f..cbfee582d87 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -1,7 +1,7 @@ use crate::diagnostic::IntoDiagnosticArg; use crate::{ Diagnostic, DiagnosticId, DiagnosticMessage, DiagnosticStyledString, ErrorGuaranteed, - SubdiagnosticMessage, + ExplicitBug, SubdiagnosticMessage, }; use crate::{Handler, Level, MultiSpan, StashKey}; use rustc_lint_defs::Applicability; @@ -12,6 +12,7 @@ use std::borrow::Cow; use std::fmt::{self, Debug}; use std::marker::PhantomData; use std::ops::{Deref, DerefMut}; +use std::panic; use std::thread::panicking; /// Trait implemented by error types. This should not be implemented manually. Instead, use @@ -308,6 +309,58 @@ impl EmissionGuarantee for Noted { } } +/// 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<DiagnosticMessage>) -> 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), + diagnostic: Box::new(diagnostic), + }, + _marker: PhantomData, + } + } +} + +impl EmissionGuarantee for Bug { + fn diagnostic_builder_emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self { + match db.inner.state { + // First `.emit()` call, the `&Handler` is still available. + DiagnosticBuilderState::Emittable(handler) => { + db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation; + + handler.emit_diagnostic(&mut db.inner.diagnostic); + } + // `.emit()` was previously called, disallowed from repeating it. + DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {} + } + // Then panic. No need to return the marker type. + panic::panic_any(ExplicitBug); + } + + fn make_diagnostic_builder( + handler: &Handler, + msg: impl Into<DiagnosticMessage>, + ) -> 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`]. diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index b03352d5fec..cf9741366a1 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -1127,6 +1127,20 @@ impl Handler { self.create_fatal(fatal).emit() } + pub fn create_bug<'a>( + &'a self, + bug: impl IntoDiagnostic<'a, diagnostic_builder::Bug>, + ) -> DiagnosticBuilder<'a, diagnostic_builder::Bug> { + bug.into_diagnostic(self) + } + + pub fn emit_bug<'a>( + &'a self, + bug: impl IntoDiagnostic<'a, diagnostic_builder::Bug>, + ) -> diagnostic_builder::Bug { + self.create_bug(bug).emit() + } + fn emit_diag_at_span( &self, mut diag: Diagnostic, |
