1
Fork 0

errors: implement fallback diagnostic translation

This commit updates the signatures of all diagnostic functions to accept
types that can be converted into a `DiagnosticMessage`. This enables
existing diagnostic calls to continue to work as before and Fluent
identifiers to be provided. The `SessionDiagnostic` derive just
generates normal diagnostic calls, so these APIs had to be modified to
accept Fluent identifiers.

In addition, loading of the "fallback" Fluent bundle, which contains the
built-in English messages, has been implemented.

Each diagnostic now has "arguments" which correspond to variables in the
Fluent messages (necessary to render a Fluent message) but no API for
adding arguments has been added yet. Therefore, diagnostics (that do not
require interpolation) can be converted to use Fluent identifiers and
will be output as before.
This commit is contained in:
David Wood 2022-03-26 07:27:43 +00:00
parent c45f29595d
commit 7f91697b50
46 changed files with 919 additions and 293 deletions

View file

@ -1,4 +1,4 @@
use crate::{Diagnostic, DiagnosticId, DiagnosticStyledString, ErrorGuaranteed};
use crate::{Diagnostic, DiagnosticId, DiagnosticMessage, DiagnosticStyledString, ErrorGuaranteed};
use crate::{Handler, Level, MultiSpan, StashKey};
use rustc_lint_defs::Applicability;
@ -99,7 +99,10 @@ mod sealed_level_is_error {
impl<'a> DiagnosticBuilder<'a, ErrorGuaranteed> {
/// Convenience function for internal use, clients should use one of the
/// `struct_*` methods on [`Handler`].
crate fn new_guaranteeing_error<const L: Level>(handler: &'a Handler, message: &str) -> Self
crate fn new_guaranteeing_error<M: Into<DiagnosticMessage>, const L: Level>(
handler: &'a Handler,
message: M,
) -> Self
where
(): sealed_level_is_error::IsError<L>,
{
@ -163,7 +166,11 @@ impl EmissionGuarantee for ErrorGuaranteed {
impl<'a> DiagnosticBuilder<'a, ()> {
/// Convenience function for internal use, clients should use one of the
/// `struct_*` methods on [`Handler`].
crate fn new(handler: &'a Handler, level: Level, message: &str) -> Self {
crate fn new<M: Into<DiagnosticMessage>>(
handler: &'a Handler,
level: Level,
message: M,
) -> Self {
let diagnostic = Diagnostic::new_with_code(level, None, message);
Self::new_diagnostic(handler, diagnostic)
}
@ -201,7 +208,7 @@ impl EmissionGuarantee for () {
impl<'a> DiagnosticBuilder<'a, !> {
/// Convenience function for internal use, clients should use one of the
/// `struct_*` methods on [`Handler`].
crate fn new_fatal(handler: &'a Handler, message: &str) -> Self {
crate fn new_fatal(handler: &'a Handler, message: impl Into<DiagnosticMessage>) -> Self {
let diagnostic = Diagnostic::new_with_code(Level::Fatal, None, message);
Self::new_diagnostic_fatal(handler, diagnostic)
}
@ -346,7 +353,7 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
}
// Take the `Diagnostic` by replacing it with a dummy.
let dummy = Diagnostic::new(Level::Allow, "");
let dummy = Diagnostic::new(Level::Allow, DiagnosticMessage::Str("".to_string()));
let diagnostic = std::mem::replace(&mut *self.inner.diagnostic, dummy);
// Disable the ICE on `Drop`.
@ -434,25 +441,25 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
found: DiagnosticStyledString,
) -> &mut Self);
forward!(pub fn note(&mut self, msg: &str) -> &mut Self);
forward!(pub fn note_once(&mut self, msg: &str) -> &mut Self);
forward!(pub fn note(&mut self, msg: impl Into<DiagnosticMessage>) -> &mut Self);
forward!(pub fn note_once(&mut self, msg: impl Into<DiagnosticMessage>) -> &mut Self);
forward!(pub fn span_note(
&mut self,
sp: impl Into<MultiSpan>,
msg: &str,
msg: impl Into<DiagnosticMessage>,
) -> &mut Self);
forward!(pub fn span_note_once(
&mut self,
sp: impl Into<MultiSpan>,
msg: &str,
msg: impl Into<DiagnosticMessage>,
) -> &mut Self);
forward!(pub fn warn(&mut self, msg: &str) -> &mut Self);
forward!(pub fn warn(&mut self, msg: impl Into<DiagnosticMessage>) -> &mut Self);
forward!(pub fn span_warn(&mut self, sp: impl Into<MultiSpan>, msg: &str) -> &mut Self);
forward!(pub fn help(&mut self, msg: &str) -> &mut Self);
forward!(pub fn help(&mut self, msg: impl Into<DiagnosticMessage>) -> &mut Self);
forward!(pub fn span_help(
&mut self,
sp: impl Into<MultiSpan>,
msg: &str,
msg: impl Into<DiagnosticMessage>,
) -> &mut Self);
forward!(pub fn help_use_latest_edition(&mut self,) -> &mut Self);
forward!(pub fn set_is_lint(&mut self,) -> &mut Self);
@ -461,67 +468,67 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
forward!(pub fn multipart_suggestion(
&mut self,
msg: &str,
msg: impl Into<DiagnosticMessage>,
suggestion: Vec<(Span, String)>,
applicability: Applicability,
) -> &mut Self);
forward!(pub fn multipart_suggestion_verbose(
&mut self,
msg: &str,
msg: impl Into<DiagnosticMessage>,
suggestion: Vec<(Span, String)>,
applicability: Applicability,
) -> &mut Self);
forward!(pub fn tool_only_multipart_suggestion(
&mut self,
msg: &str,
msg: impl Into<DiagnosticMessage>,
suggestion: Vec<(Span, String)>,
applicability: Applicability,
) -> &mut Self);
forward!(pub fn span_suggestion(
&mut self,
sp: Span,
msg: &str,
msg: impl Into<DiagnosticMessage>,
suggestion: String,
applicability: Applicability,
) -> &mut Self);
forward!(pub fn span_suggestions(
&mut self,
sp: Span,
msg: &str,
msg: impl Into<DiagnosticMessage>,
suggestions: impl Iterator<Item = String>,
applicability: Applicability,
) -> &mut Self);
forward!(pub fn multipart_suggestions(
&mut self,
msg: &str,
msg: impl Into<DiagnosticMessage>,
suggestions: impl Iterator<Item = Vec<(Span, String)>>,
applicability: Applicability,
) -> &mut Self);
forward!(pub fn span_suggestion_short(
&mut self,
sp: Span,
msg: &str,
msg: impl Into<DiagnosticMessage>,
suggestion: String,
applicability: Applicability,
) -> &mut Self);
forward!(pub fn span_suggestion_verbose(
&mut self,
sp: Span,
msg: &str,
msg: impl Into<DiagnosticMessage>,
suggestion: String,
applicability: Applicability,
) -> &mut Self);
forward!(pub fn span_suggestion_hidden(
&mut self,
sp: Span,
msg: &str,
msg: impl Into<DiagnosticMessage>,
suggestion: String,
applicability: Applicability,
) -> &mut Self);
forward!(pub fn tool_only_span_suggestion(
&mut self,
sp: Span,
msg: &str,
msg: impl Into<DiagnosticMessage>,
suggestion: String,
applicability: Applicability,
) -> &mut Self);
@ -547,7 +554,9 @@ impl Drop for DiagnosticBuilderInner<'_> {
if !panicking() {
handler.emit_diagnostic(&mut Diagnostic::new(
Level::Bug,
"the following error was constructed but not emitted",
DiagnosticMessage::Str(
"the following error was constructed but not emitted".to_string(),
),
));
handler.emit_diagnostic(&mut self.diagnostic);
panic!();