diff options
Diffstat (limited to 'compiler/rustc_errors/src')
| -rw-r--r-- | compiler/rustc_errors/src/diagnostic.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/diagnostic_builder.rs | 53 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/diagnostic_impls.rs | 18 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/lib.rs | 41 |
4 files changed, 99 insertions, 15 deletions
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 4ad24c1400d..df949e46fbd 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -1051,6 +1051,7 @@ impl Diagnostic { ) -> ( &Level, &[(DiagnosticMessage, Style)], + Vec<(&Cow<'static, str>, &DiagnosticArgValue<'static>)>, &Option<DiagnosticId>, &MultiSpan, &Result<Vec<CodeSuggestion>, SuggestionsDisabled>, @@ -1059,6 +1060,7 @@ impl Diagnostic { ( &self.level, &self.message, + self.args().collect(), &self.code, &self.span, &self.suggestions, diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index cbfee582d87..c9d662ad43f 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -408,6 +408,59 @@ impl EmissionGuarantee for ! { } } +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<DiagnosticMessage>, + ) -> 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), + diagnostic: Box::new(diagnostic), + }, + _marker: PhantomData, + } + } +} + +impl EmissionGuarantee for rustc_span::fatal_error::FatalError { + 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 fatally error.. + rustc_span::fatal_error::FatalError + } + + fn make_diagnostic_builder( + handler: &Handler, + msg: impl Into<DiagnosticMessage>, + ) -> DiagnosticBuilder<'_, Self> { + DiagnosticBuilder::new_almost_fatal(handler, msg) + } +} + /// In general, the `DiagnosticBuilder` uses deref to allow access to /// the fields and methods of the embedded `diagnostic` in a /// transparent way. *However,* many of the methods are intended to diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index d5a5ef3b445..7a94ce3777a 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -159,12 +159,6 @@ impl IntoDiagnosticArg for ast::Path { } } -impl IntoDiagnosticArg for &ast::Path { - fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { - DiagnosticArgValue::Str(Cow::Owned(pprust::path_to_string(self))) - } -} - impl IntoDiagnosticArg for ast::token::Token { fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { DiagnosticArgValue::Str(pprust::token_to_string(&self)) @@ -183,6 +177,18 @@ impl IntoDiagnosticArg for type_ir::FloatTy { } } +impl IntoDiagnosticArg for std::ffi::CString { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self.to_string_lossy().into_owned())) + } +} + +impl IntoDiagnosticArg for rustc_data_structures::small_c_str::SmallCStr { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self.to_string_lossy().into_owned())) + } +} + impl IntoDiagnosticArg for Level { fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { DiagnosticArgValue::Str(Cow::Borrowed(self.to_cmd_flag())) diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 57732db5aca..ec04e865d53 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -617,22 +617,24 @@ impl Handler { } } - /// Translate `message` eagerly with `args`. + /// Translate `message` eagerly with `args` to `SubdiagnosticMessage::Eager`. pub fn eagerly_translate<'a>( &self, message: DiagnosticMessage, args: impl Iterator<Item = DiagnosticArg<'a, 'static>>, ) -> SubdiagnosticMessage { + SubdiagnosticMessage::Eager(self.eagerly_translate_to_string(message, args)) + } + + /// Translate `message` eagerly with `args` to `String`. + pub fn eagerly_translate_to_string<'a>( + &self, + message: DiagnosticMessage, + args: impl Iterator<Item = DiagnosticArg<'a, 'static>>, + ) -> String { let inner = self.inner.borrow(); let args = crate::translation::to_fluent_args(args); - SubdiagnosticMessage::Eager( - inner - .emitter - .translate_message(&message, &args) - .map_err(Report::new) - .unwrap() - .to_string(), - ) + inner.emitter.translate_message(&message, &args).map_err(Report::new).unwrap().to_string() } // This is here to not allow mutation of flags; @@ -1010,6 +1012,7 @@ impl Handler { } #[track_caller] + #[rustc_lint_diagnostics] pub fn span_note_without_error( &self, span: impl Into<MultiSpan>, @@ -1019,6 +1022,7 @@ impl Handler { } #[track_caller] + #[rustc_lint_diagnostics] pub fn span_note_diag( &self, span: Span, @@ -1030,19 +1034,23 @@ impl Handler { } // 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<DiagnosticMessage>) -> FatalError { self.inner.borrow_mut().fatal(msg) } + #[rustc_lint_diagnostics] pub fn err(&self, msg: impl Into<DiagnosticMessage>) -> ErrorGuaranteed { self.inner.borrow_mut().err(msg) } + #[rustc_lint_diagnostics] pub fn warn(&self, msg: impl Into<DiagnosticMessage>) { let mut db = DiagnosticBuilder::new(self, Warning(None), msg); db.emit(); } + #[rustc_lint_diagnostics] pub fn note_without_error(&self, msg: impl Into<DiagnosticMessage>) { DiagnosticBuilder::new(self, Note, msg).emit(); } @@ -1059,6 +1067,7 @@ impl Handler { pub fn has_errors(&self) -> Option<ErrorGuaranteed> { if self.inner.borrow().has_errors() { Some(ErrorGuaranteed(())) } else { None } } + pub fn has_errors_or_lint_errors(&self) -> Option<ErrorGuaranteed> { if self.inner.borrow().has_errors_or_lint_errors() { Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()) @@ -1132,6 +1141,20 @@ impl Handler { self.create_warning(warning).emit() } + pub fn create_almost_fatal<'a>( + &'a self, + fatal: impl IntoDiagnostic<'a, FatalError>, + ) -> DiagnosticBuilder<'a, FatalError> { + fatal.into_diagnostic(self) + } + + pub fn emit_almost_fatal<'a>( + &'a self, + fatal: impl IntoDiagnostic<'a, FatalError>, + ) -> FatalError { + self.create_almost_fatal(fatal).emit() + } + pub fn create_fatal<'a>( &'a self, fatal: impl IntoDiagnostic<'a, !>, |
