Skip to content

Implement diagnostic translation for rustc-errors #113281

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions compiler/rustc_errors/messages.ftl
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
errors_delayed_at_with_newline =
delayed at {$emitted_at}
{$note}

errors_delayed_at_without_newline =
delayed at {$emitted_at} - {$note}

errors_expected_lifetime_parameter =
expected lifetime {$count ->
[1] parameter
*[other] parameters
}

errors_indicate_anonymous_lifetime =
indicate the anonymous {$count ->
[1] lifetime
*[other] lifetimes
}

errors_invalid_flushed_delayed_diagnostic_level =
`flushed_delayed` got diagnostic with level {$level}, instead of the expected `DelayedBug`

errors_target_inconsistent_architecture =
inconsistent target specification: "data-layout" claims architecture is {$dl}-endian, while "target-endian" is `{$target}`

Expand Down
61 changes: 61 additions & 0 deletions compiler/rustc_errors/src/diagnostic_impls.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::diagnostic::DiagnosticLocation;
use crate::{fluent_generated as fluent, AddToDiagnostic};
use crate::{DiagnosticArgValue, DiagnosticBuilder, Handler, IntoDiagnostic, IntoDiagnosticArg};
use rustc_ast as ast;
Expand All @@ -10,6 +11,7 @@ use rustc_span::Span;
use rustc_target::abi::TargetDataLayoutErrors;
use rustc_target::spec::{PanicStrategy, SplitDebuginfo, StackProtector, TargetTriple};
use rustc_type_ir as type_ir;
use std::backtrace::Backtrace;
use std::borrow::Cow;
use std::fmt;
use std::num::ParseIntError;
Expand Down Expand Up @@ -311,3 +313,62 @@ pub enum LabelKind {
Label,
Help,
}

#[derive(Subdiagnostic)]
#[label(errors_expected_lifetime_parameter)]
pub struct ExpectedLifetimeParameter {
#[primary_span]
pub span: Span,
pub count: usize,
}

#[derive(Subdiagnostic)]
#[note(errors_delayed_at_with_newline)]
pub struct DelayedAtWithNewline {
#[primary_span]
pub span: Span,
pub emitted_at: DiagnosticLocation,
pub note: Backtrace,
}
#[derive(Subdiagnostic)]
#[note(errors_delayed_at_without_newline)]
pub struct DelayedAtWithoutNewline {
#[primary_span]
pub span: Span,
pub emitted_at: DiagnosticLocation,
pub note: Backtrace,
}

impl IntoDiagnosticArg for DiagnosticLocation {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
DiagnosticArgValue::Str(Cow::from(self.to_string()))
}
}

impl IntoDiagnosticArg for Backtrace {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
DiagnosticArgValue::Str(Cow::from(self.to_string()))
}
}

#[derive(Subdiagnostic)]
#[note(errors_invalid_flushed_delayed_diagnostic_level)]
pub struct InvalidFlushedDelayedDiagnosticLevel {
#[primary_span]
pub span: Span,
pub level: rustc_errors::Level,
}
impl IntoDiagnosticArg for rustc_errors::Level {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
DiagnosticArgValue::Str(Cow::from(self.to_string()))
}
}

#[derive(Subdiagnostic)]
#[suggestion(errors_indicate_anonymous_lifetime, code = "{suggestion}", style = "verbose")]
pub struct IndicateAnonymousLifetime {
#[primary_span]
pub span: Span,
pub count: usize,
pub suggestion: String,
}
42 changes: 28 additions & 14 deletions compiler/rustc_errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ extern crate rustc_macros;
#[macro_use]
extern crate tracing;

extern crate self as rustc_errors;

pub use emitter::ColorConfig;

use rustc_lint_defs::LintExpectationId;
Expand Down Expand Up @@ -375,13 +377,16 @@ pub struct ExplicitBug;
/// rather than a failed assertion, etc.
pub struct DelayedBugPanic;

use crate::diagnostic_impls::{DelayedAtWithNewline, DelayedAtWithoutNewline};
pub use diagnostic::{
AddToDiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgValue, DiagnosticId,
DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic,
};
pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee, Noted};
pub use diagnostic_impls::{
DiagnosticArgFromDisplay, DiagnosticSymbolList, LabelKind, SingleLabelManySpans,
DiagnosticArgFromDisplay, DiagnosticSymbolList, ExpectedLifetimeParameter,
IndicateAnonymousLifetime, InvalidFlushedDelayedDiagnosticLevel, LabelKind,
SingleLabelManySpans,
};
use std::backtrace::{Backtrace, BacktraceStatus};

Expand Down Expand Up @@ -1670,11 +1675,10 @@ impl HandlerInner {
if bug.level != Level::DelayedBug {
// NOTE(eddyb) not panicking here because we're already producing
// an ICE, and the more information the merrier.
bug.note(format!(
"`flushed_delayed` got diagnostic with level {:?}, \
instead of the expected `DelayedBug`",
bug.level,
));
bug.subdiagnostic(InvalidFlushedDelayedDiagnosticLevel {
span: bug.span.primary_span().unwrap(),
level: bug.level,
});
}
bug.level = Level::Bug;

Expand Down Expand Up @@ -1741,12 +1745,22 @@ impl DelayedDiagnostic {
fn decorate(mut self) -> Diagnostic {
match self.note.status() {
BacktraceStatus::Captured => {
self.inner.note(format!("delayed at {}\n{}", self.inner.emitted_at, self.note));
let inner = &self.inner;
self.inner.subdiagnostic(DelayedAtWithNewline {
span: inner.span.primary_span().unwrap(),
emitted_at: inner.emitted_at.clone(),
note: self.note,
});
}
// Avoid the needless newline when no backtrace has been captured,
// the display impl should just be a single line.
_ => {
self.inner.note(format!("delayed at {} - {}", self.inner.emitted_at, self.note));
let inner = &self.inner;
self.inner.subdiagnostic(DelayedAtWithoutNewline {
span: inner.span.primary_span().unwrap(),
emitted_at: inner.emitted_at.clone(),
note: self.note,
});
}
}

Expand Down Expand Up @@ -1838,20 +1852,20 @@ pub fn add_elided_lifetime_in_path_suggestion(
incl_angl_brckt: bool,
insertion_span: Span,
) {
diag.span_label(path_span, format!("expected lifetime parameter{}", pluralize!(n)));
diag.subdiagnostic(ExpectedLifetimeParameter { span: path_span, count: n });
if !source_map.is_span_accessible(insertion_span) {
// Do not try to suggest anything if generated by a proc-macro.
return;
}
let anon_lts = vec!["'_"; n].join(", ");
let suggestion =
if incl_angl_brckt { format!("<{}>", anon_lts) } else { format!("{}, ", anon_lts) };
diag.span_suggestion_verbose(
insertion_span.shrink_to_hi(),
format!("indicate the anonymous lifetime{}", pluralize!(n)),

diag.subdiagnostic(IndicateAnonymousLifetime {
span: insertion_span.shrink_to_hi(),
count: n,
suggestion,
Applicability::MachineApplicable,
);
});
}

#[derive(Clone, Copy, PartialEq, Hash, Debug)]
Expand Down