Skip to content
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

Track where diagnostics were created. #103217

Merged
merged 7 commits into from
Nov 1, 2022
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
1 change: 1 addition & 0 deletions compiler/rustc_driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1211,6 +1211,7 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
false,
None,
false,
false,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is getting to be a lot of arguments, maybe add a Config struct? Doesn't need to block this PR though

));
let handler = rustc_errors::Handler::with_emitter(true, None, emitter);

Expand Down
29 changes: 29 additions & 0 deletions compiler/rustc_errors/src/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use rustc_span::{Span, DUMMY_SP};
use std::borrow::Cow;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::panic::Location;

/// Error type for `Diagnostic`'s `suggestions` field, indicating that
/// `.disable_suggestions()` was called on the `Diagnostic`.
Expand Down Expand Up @@ -107,6 +108,31 @@ pub struct Diagnostic {
/// If diagnostic is from Lint, custom hash function ignores notes
/// otherwise hash is based on the all the fields
pub is_lint: bool,

/// With `-Ztrack_diagnostics` enabled,
/// we print where in rustc this error was emitted.
pub emitted_at: DiagnosticLocation,
}

#[derive(Clone, Debug, Encodable, Decodable)]
pub struct DiagnosticLocation {
file: Cow<'static, str>,
mejrs marked this conversation as resolved.
Show resolved Hide resolved
line: u32,
col: u32,
}

impl DiagnosticLocation {
#[track_caller]
fn caller() -> Self {
let loc = Location::caller();
DiagnosticLocation { file: loc.file().into(), line: loc.line(), col: loc.column() }
}
}

impl fmt::Display for DiagnosticLocation {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}:{}:{}", self.file, self.line, self.col)
}
}

#[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)]
Expand Down Expand Up @@ -173,10 +199,12 @@ impl StringPart {
}

impl Diagnostic {
#[track_caller]
pub fn new<M: Into<DiagnosticMessage>>(level: Level, message: M) -> Self {
Diagnostic::new_with_code(level, None, message)
}

#[track_caller]
pub fn new_with_code<M: Into<DiagnosticMessage>>(
level: Level,
code: Option<DiagnosticId>,
Expand All @@ -192,6 +220,7 @@ impl Diagnostic {
args: Default::default(),
sort_span: DUMMY_SP,
is_lint: false,
emitted_at: DiagnosticLocation::caller(),
}
}

Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_errors/src/diagnostic_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ 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`].
#[track_caller]
pub(crate) fn new_guaranteeing_error<M: Into<DiagnosticMessage>, const L: Level>(
handler: &'a Handler,
message: M,
Expand Down Expand Up @@ -196,6 +197,7 @@ impl EmissionGuarantee for ErrorGuaranteed {
}
}

#[track_caller]
fn make_diagnostic_builder(
handler: &Handler,
msg: impl Into<DiagnosticMessage>,
Expand All @@ -209,6 +211,7 @@ impl EmissionGuarantee for ErrorGuaranteed {
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<M: Into<DiagnosticMessage>>(
handler: &'a Handler,
level: Level,
Expand All @@ -220,6 +223,7 @@ impl<'a> DiagnosticBuilder<'a, ()> {

/// 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 {
Expand Down Expand Up @@ -308,6 +312,7 @@ impl EmissionGuarantee for Noted {
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<DiagnosticMessage>) -> Self {
let diagnostic = Diagnostic::new_with_code(Level::Fatal, None, message);
Self::new_diagnostic_fatal(handler, diagnostic)
Expand Down
36 changes: 31 additions & 5 deletions compiler/rustc_errors/src/emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ use crate::snippet::{Annotation, AnnotationType, Line, MultilineAnnotation, Styl
use crate::styled_buffer::StyledBuffer;
use crate::translation::{to_fluent_args, Translate};
use crate::{
CodeSuggestion, Diagnostic, DiagnosticId, DiagnosticMessage, FluentBundle, Handler,
LazyFallbackBundle, Level, MultiSpan, SubDiagnostic, SubstitutionHighlight, SuggestionStyle,
diagnostic::DiagnosticLocation, CodeSuggestion, Diagnostic, DiagnosticId, DiagnosticMessage,
FluentBundle, Handler, LazyFallbackBundle, Level, MultiSpan, SubDiagnostic,
SubstitutionHighlight, SuggestionStyle,
};

use rustc_lint_defs::pluralize;

use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
Expand Down Expand Up @@ -64,6 +64,7 @@ impl HumanReadableErrorType {
teach: bool,
diagnostic_width: Option<usize>,
macro_backtrace: bool,
track_diagnostics: bool,
) -> EmitterWriter {
let (short, color_config) = self.unzip();
let color = color_config.suggests_using_colors();
Expand All @@ -77,6 +78,7 @@ impl HumanReadableErrorType {
color,
diagnostic_width,
macro_backtrace,
track_diagnostics,
)
}
}
Expand Down Expand Up @@ -557,6 +559,7 @@ impl Emitter for EmitterWriter {
&primary_span,
&children,
&suggestions,
self.track_diagnostics.then_some(&diag.emitted_at),
);
}

Expand Down Expand Up @@ -650,6 +653,7 @@ pub struct EmitterWriter {
diagnostic_width: Option<usize>,

macro_backtrace: bool,
track_diagnostics: bool,
}

#[derive(Debug)]
Expand All @@ -669,6 +673,7 @@ impl EmitterWriter {
teach: bool,
diagnostic_width: Option<usize>,
macro_backtrace: bool,
track_diagnostics: bool,
) -> EmitterWriter {
let dst = Destination::from_stderr(color_config);
EmitterWriter {
Expand All @@ -681,6 +686,7 @@ impl EmitterWriter {
ui_testing: false,
diagnostic_width,
macro_backtrace,
track_diagnostics,
}
}

Expand All @@ -694,6 +700,7 @@ impl EmitterWriter {
colored: bool,
diagnostic_width: Option<usize>,
macro_backtrace: bool,
track_diagnostics: bool,
) -> EmitterWriter {
EmitterWriter {
dst: Raw(dst, colored),
Expand All @@ -705,6 +712,7 @@ impl EmitterWriter {
ui_testing: false,
diagnostic_width,
macro_backtrace,
track_diagnostics,
}
}

Expand Down Expand Up @@ -1327,6 +1335,7 @@ impl EmitterWriter {
level: &Level,
max_line_num_len: usize,
is_secondary: bool,
emitted_at: Option<&DiagnosticLocation>,
) -> io::Result<()> {
let mut buffer = StyledBuffer::new();

Expand Down Expand Up @@ -1377,7 +1386,6 @@ impl EmitterWriter {
}
}
}

let mut annotated_files = FileWithAnnotatedLines::collect_annotations(self, args, msp);

// Make sure our primary file comes first
Expand Down Expand Up @@ -1653,6 +1661,12 @@ impl EmitterWriter {
}
}

if let Some(tracked) = emitted_at {
let track = format!("-Ztrack-diagnostics: created at {tracked}");
let len = buffer.num_lines();
buffer.append(len, &track, Style::NoStyle);
}

// final step: take our styled buffer, render it, then output it
emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?;

Expand Down Expand Up @@ -1977,6 +1991,7 @@ impl EmitterWriter {
span: &MultiSpan,
children: &[SubDiagnostic],
suggestions: &[CodeSuggestion],
emitted_at: Option<&DiagnosticLocation>,
) {
let max_line_num_len = if self.ui_testing {
ANONYMIZED_LINE_NUM.len()
Expand All @@ -1985,7 +2000,16 @@ impl EmitterWriter {
num_decimal_digits(n)
};

match self.emit_message_default(span, message, args, code, level, max_line_num_len, false) {
match self.emit_message_default(
span,
message,
args,
code,
level,
max_line_num_len,
false,
emitted_at,
) {
Ok(()) => {
if !children.is_empty()
|| suggestions.iter().any(|s| s.style != SuggestionStyle::CompletelyHidden)
Expand Down Expand Up @@ -2014,6 +2038,7 @@ impl EmitterWriter {
&child.level,
max_line_num_len,
true,
None,
) {
panic!("failed to emit error: {}", err);
}
Expand All @@ -2030,6 +2055,7 @@ impl EmitterWriter {
&Level::Help,
max_line_num_len,
true,
None,
) {
panic!("failed to emit error: {}", e);
}
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_errors/src/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ pub struct JsonEmitter {
json_rendered: HumanReadableErrorType,
diagnostic_width: Option<usize>,
macro_backtrace: bool,
track_diagnostics: bool,
}

impl JsonEmitter {
Expand All @@ -57,6 +58,7 @@ impl JsonEmitter {
json_rendered: HumanReadableErrorType,
diagnostic_width: Option<usize>,
macro_backtrace: bool,
track_diagnostics: bool,
) -> JsonEmitter {
JsonEmitter {
dst: Box::new(io::BufWriter::new(io::stderr())),
Expand All @@ -69,6 +71,7 @@ impl JsonEmitter {
json_rendered,
diagnostic_width,
macro_backtrace,
track_diagnostics,
}
}

Expand All @@ -79,6 +82,7 @@ impl JsonEmitter {
fallback_bundle: LazyFallbackBundle,
diagnostic_width: Option<usize>,
macro_backtrace: bool,
track_diagnostics: bool,
) -> JsonEmitter {
let file_path_mapping = FilePathMapping::empty();
JsonEmitter::stderr(
Expand All @@ -90,6 +94,7 @@ impl JsonEmitter {
json_rendered,
diagnostic_width,
macro_backtrace,
track_diagnostics,
)
}

Expand All @@ -103,6 +108,7 @@ impl JsonEmitter {
json_rendered: HumanReadableErrorType,
diagnostic_width: Option<usize>,
macro_backtrace: bool,
track_diagnostics: bool,
) -> JsonEmitter {
JsonEmitter {
dst,
Expand All @@ -115,6 +121,7 @@ impl JsonEmitter {
json_rendered,
diagnostic_width,
macro_backtrace,
track_diagnostics,
}
}

Expand Down Expand Up @@ -350,6 +357,7 @@ impl Diagnostic {
false,
je.diagnostic_width,
je.macro_backtrace,
je.track_diagnostics,
)
.ui_testing(je.ui_testing)
.emit_diagnostic(diag);
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_errors/src/json/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) {
HumanReadableErrorType::Short(ColorConfig::Never),
None,
false,
false,
);

let span = Span::with_root_ctxt(BytePos(span.0), BytePos(span.1));
Expand Down
Loading