From 406e1dc8ebdeb509515c0c8be7cfe015c5eced30 Mon Sep 17 00:00:00 2001 From: mejrs <> Date: Wed, 19 Oct 2022 00:08:20 +0200 Subject: [PATCH] Implement -Ztrack-diagnostics --- compiler/rustc_driver/src/lib.rs | 1 + compiler/rustc_errors/src/diagnostic.rs | 29 +++++++++++++++ .../rustc_errors/src/diagnostic_builder.rs | 5 +++ compiler/rustc_errors/src/emitter.rs | 36 ++++++++++++++++--- compiler/rustc_errors/src/json.rs | 8 +++++ compiler/rustc_errors/src/json/tests.rs | 1 + compiler/rustc_errors/src/lib.rs | 30 ++++++++++++++++ compiler/rustc_expand/src/tests.rs | 1 + compiler/rustc_session/src/config.rs | 1 + compiler/rustc_session/src/options.rs | 2 ++ compiler/rustc_session/src/session.rs | 30 ++++++++++++++-- src/librustdoc/core.rs | 2 ++ src/librustdoc/doctest.rs | 3 ++ src/test/ui/track-diagnostics/track.rs | 6 ++++ src/test/ui/track-diagnostics/track.stderr | 26 ++++++++++++++ src/tools/clippy/clippy_lints/src/doc.rs | 1 + src/tools/clippy/src/driver.rs | 1 + src/tools/rustfmt/src/parse/session.rs | 1 + 18 files changed, 176 insertions(+), 8 deletions(-) create mode 100644 src/test/ui/track-diagnostics/track.rs create mode 100644 src/test/ui/track-diagnostics/track.stderr diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index f268d50e96e8..b92a3289fa2e 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -1211,6 +1211,7 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { false, None, false, + false, )); let handler = rustc_errors::Handler::with_emitter(true, None, emitter); diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 518c59dba536..1ea6d82891fd 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -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`. @@ -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>, + 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)] @@ -173,10 +199,12 @@ impl StringPart { } impl Diagnostic { + #[track_caller] pub fn new>(level: Level, message: M) -> Self { Diagnostic::new_with_code(level, None, message) } + #[track_caller] pub fn new_with_code>( level: Level, code: Option, @@ -192,6 +220,7 @@ impl Diagnostic { args: Default::default(), sort_span: DUMMY_SP, is_lint: false, + emitted_at: DiagnosticLocation::caller(), } } diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 9b41234dcfb6..ecf8570e81f7 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -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, const L: Level>( handler: &'a Handler, message: M, @@ -196,6 +197,7 @@ impl EmissionGuarantee for ErrorGuaranteed { } } + #[track_caller] fn make_diagnostic_builder( handler: &Handler, msg: impl Into, @@ -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>( handler: &'a Handler, level: Level, @@ -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 { @@ -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) -> Self { let diagnostic = Diagnostic::new_with_code(Level::Fatal, None, message); Self::new_diagnostic_fatal(handler, diagnostic) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index cd6413bc3ec6..b9b9a59e354b 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -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}; @@ -64,6 +64,7 @@ impl HumanReadableErrorType { teach: bool, diagnostic_width: Option, macro_backtrace: bool, + track_diagnostics: bool, ) -> EmitterWriter { let (short, color_config) = self.unzip(); let color = color_config.suggests_using_colors(); @@ -77,6 +78,7 @@ impl HumanReadableErrorType { color, diagnostic_width, macro_backtrace, + track_diagnostics, ) } } @@ -557,6 +559,7 @@ impl Emitter for EmitterWriter { &primary_span, &children, &suggestions, + Some(&diag.emitted_at), ); } @@ -650,6 +653,7 @@ pub struct EmitterWriter { diagnostic_width: Option, macro_backtrace: bool, + track_diagnostics: bool, } #[derive(Debug)] @@ -669,6 +673,7 @@ impl EmitterWriter { teach: bool, diagnostic_width: Option, macro_backtrace: bool, + track_diagnostics: bool, ) -> EmitterWriter { let dst = Destination::from_stderr(color_config); EmitterWriter { @@ -681,6 +686,7 @@ impl EmitterWriter { ui_testing: false, diagnostic_width, macro_backtrace, + track_diagnostics, } } @@ -694,6 +700,7 @@ impl EmitterWriter { colored: bool, diagnostic_width: Option, macro_backtrace: bool, + track_diagnostics: bool, ) -> EmitterWriter { EmitterWriter { dst: Raw(dst, colored), @@ -705,6 +712,7 @@ impl EmitterWriter { ui_testing: false, diagnostic_width, macro_backtrace, + track_diagnostics, } } @@ -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(); @@ -1377,7 +1386,6 @@ impl EmitterWriter { } } } - let mut annotated_files = FileWithAnnotatedLines::collect_annotations(self, args, msp); // Make sure our primary file comes first @@ -1653,6 +1661,12 @@ impl EmitterWriter { } } + if self.track_diagnostics && 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)?; @@ -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() @@ -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) @@ -2014,6 +2038,7 @@ impl EmitterWriter { &child.level, max_line_num_len, true, + None, ) { panic!("failed to emit error: {}", err); } @@ -2030,6 +2055,7 @@ impl EmitterWriter { &Level::Help, max_line_num_len, true, + None, ) { panic!("failed to emit error: {}", e); } diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 4cc7be47fc2c..c4498eafa4ea 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -45,6 +45,7 @@ pub struct JsonEmitter { json_rendered: HumanReadableErrorType, diagnostic_width: Option, macro_backtrace: bool, + track_diagnostics: bool, } impl JsonEmitter { @@ -57,6 +58,7 @@ impl JsonEmitter { json_rendered: HumanReadableErrorType, diagnostic_width: Option, macro_backtrace: bool, + track_diagnostics: bool, ) -> JsonEmitter { JsonEmitter { dst: Box::new(io::BufWriter::new(io::stderr())), @@ -69,6 +71,7 @@ impl JsonEmitter { json_rendered, diagnostic_width, macro_backtrace, + track_diagnostics, } } @@ -79,6 +82,7 @@ impl JsonEmitter { fallback_bundle: LazyFallbackBundle, diagnostic_width: Option, macro_backtrace: bool, + track_diagnostics: bool, ) -> JsonEmitter { let file_path_mapping = FilePathMapping::empty(); JsonEmitter::stderr( @@ -90,6 +94,7 @@ impl JsonEmitter { json_rendered, diagnostic_width, macro_backtrace, + track_diagnostics, ) } @@ -103,6 +108,7 @@ impl JsonEmitter { json_rendered: HumanReadableErrorType, diagnostic_width: Option, macro_backtrace: bool, + track_diagnostics: bool, ) -> JsonEmitter { JsonEmitter { dst, @@ -115,6 +121,7 @@ impl JsonEmitter { json_rendered, diagnostic_width, macro_backtrace, + track_diagnostics, } } @@ -350,6 +357,7 @@ impl Diagnostic { false, je.diagnostic_width, je.macro_backtrace, + je.track_diagnostics, ) .ui_testing(je.ui_testing) .emit_diagnostic(diag); diff --git a/compiler/rustc_errors/src/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs index d940d14e1db9..f131468971b5 100644 --- a/compiler/rustc_errors/src/json/tests.rs +++ b/compiler/rustc_errors/src/json/tests.rs @@ -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)); diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 9fafbe4bd407..e3bb50c3d22e 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -489,6 +489,8 @@ pub struct HandlerFlags { pub macro_backtrace: bool, /// If true, identical diagnostics are reported only once. pub deduplicate_diagnostics: bool, + /// Track where errors are created. Enabled with `-Ztrack-diagnostics`. + pub track_diagnostics: bool, } impl Drop for HandlerInner { @@ -556,6 +558,7 @@ impl Handler { false, None, flags.macro_backtrace, + flags.track_diagnostics, )); Self::with_emitter_and_flags(emitter, flags) } @@ -661,6 +664,7 @@ impl Handler { /// Construct a builder with the `msg` at the level appropriate for the specific `EmissionGuarantee`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_diagnostic( &self, msg: impl Into, @@ -674,6 +678,7 @@ impl Handler { /// * `can_emit_warnings` is `true` /// * `is_force_warn` was set in `DiagnosticId::Lint` #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_warn( &self, span: impl Into, @@ -690,6 +695,7 @@ impl Handler { /// Attempting to `.emit()` the builder will only emit if either: /// * `can_emit_warnings` is `true` /// * `is_force_warn` was set in `DiagnosticId::Lint` + #[track_caller] pub fn struct_span_warn_with_expectation( &self, span: impl Into, @@ -703,6 +709,7 @@ impl Handler { /// Construct a builder at the `Allow` level at the given `span` and with the `msg`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_allow( &self, span: impl Into, @@ -716,6 +723,7 @@ impl Handler { /// Construct a builder at the `Warning` level at the given `span` and with the `msg`. /// Also include a code. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_warn_with_code( &self, span: impl Into, @@ -733,6 +741,7 @@ impl Handler { /// * `can_emit_warnings` is `true` /// * `is_force_warn` was set in `DiagnosticId::Lint` #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_warn(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { DiagnosticBuilder::new(self, Level::Warning(None), msg) } @@ -743,6 +752,7 @@ impl Handler { /// Attempting to `.emit()` the builder will only emit if either: /// * `can_emit_warnings` is `true` /// * `is_force_warn` was set in `DiagnosticId::Lint` + #[track_caller] pub fn struct_warn_with_expectation( &self, msg: impl Into, @@ -759,6 +769,7 @@ impl Handler { /// Construct a builder at the `Expect` level with the `msg`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_expect( &self, msg: impl Into, @@ -769,6 +780,7 @@ impl Handler { /// Construct a builder at the `Error` level at the given `span` and with the `msg`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_err( &self, span: impl Into, @@ -781,6 +793,7 @@ impl Handler { /// Construct a builder at the `Error` level at the given `span`, with the `msg`, and `code`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_err_with_code( &self, span: impl Into, @@ -795,6 +808,7 @@ impl Handler { /// Construct a builder at the `Error` level with the `msg`. // FIXME: This method should be removed (every error should have an associated error code). #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_err( &self, msg: impl Into, @@ -804,12 +818,14 @@ impl Handler { /// This should only be used by `rustc_middle::lint::struct_lint_level`. Do not use it for hard errors. #[doc(hidden)] + #[track_caller] pub fn struct_err_lint(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { DiagnosticBuilder::new(self, Level::Error { lint: true }, msg) } /// Construct a builder at the `Error` level with the `msg` and the `code`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_err_with_code( &self, msg: impl Into, @@ -822,6 +838,7 @@ impl Handler { /// Construct a builder at the `Warn` level with the `msg` and the `code`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_warn_with_code( &self, msg: impl Into, @@ -834,6 +851,7 @@ impl Handler { /// Construct a builder at the `Fatal` level at the given `span` and with the `msg`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_fatal( &self, span: impl Into, @@ -871,6 +889,7 @@ impl Handler { /// Construct a builder at the `Note` level with the `msg`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_note_without_error( &self, msg: impl Into, @@ -885,6 +904,7 @@ impl Handler { } #[rustc_lint_diagnostics] + #[track_caller] pub fn span_fatal_with_code( &self, span: impl Into, @@ -896,6 +916,7 @@ impl Handler { } #[rustc_lint_diagnostics] + #[track_caller] pub fn span_err( &self, span: impl Into, @@ -905,6 +926,7 @@ impl Handler { } #[rustc_lint_diagnostics] + #[track_caller] pub fn span_err_with_code( &self, span: impl Into, @@ -918,11 +940,13 @@ impl Handler { } #[rustc_lint_diagnostics] + #[track_caller] pub fn span_warn(&self, span: impl Into, msg: impl Into) { self.emit_diag_at_span(Diagnostic::new(Warning(None), msg), span); } #[rustc_lint_diagnostics] + #[track_caller] pub fn span_warn_with_code( &self, span: impl Into, @@ -932,6 +956,7 @@ impl Handler { self.emit_diag_at_span(Diagnostic::new_with_code(Warning(None), Some(code), msg), span); } + #[track_caller] pub fn span_bug(&self, span: impl Into, msg: impl Into) -> ! { self.inner.borrow_mut().span_bug(span, msg) } @@ -947,14 +972,17 @@ impl Handler { // FIXME(eddyb) note the comment inside `impl Drop for HandlerInner`, that's // where the explanation of what "good path" is (also, it should be renamed). + #[track_caller] pub fn delay_good_path_bug(&self, msg: impl Into) { self.inner.borrow_mut().delay_good_path_bug(msg) } + #[track_caller] pub fn span_bug_no_panic(&self, span: impl Into, msg: impl Into) { self.emit_diag_at_span(Diagnostic::new(Bug, msg), span); } + #[track_caller] pub fn span_note_without_error( &self, span: impl Into, @@ -963,6 +991,7 @@ impl Handler { self.emit_diag_at_span(Diagnostic::new(Note, msg), span); } + #[track_caller] pub fn span_note_diag( &self, span: Span, @@ -1449,6 +1478,7 @@ impl HandlerInner { } } + #[track_caller] fn span_bug(&mut self, sp: impl Into, msg: impl Into) -> ! { self.emit_diag_at_span(Diagnostic::new(Bug, msg), sp); panic::panic_any(ExplicitBug); diff --git a/compiler/rustc_expand/src/tests.rs b/compiler/rustc_expand/src/tests.rs index e44f06081963..d82a7a54030c 100644 --- a/compiler/rustc_expand/src/tests.rs +++ b/compiler/rustc_expand/src/tests.rs @@ -151,6 +151,7 @@ fn test_harness(file_text: &str, span_labels: Vec, expected_output: & false, None, false, + false, ); let handler = Handler::with_emitter(true, None, Box::new(emitter)); handler.span_err(msp, "foo"); diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index f2ee52262ade..856ff3d41508 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -794,6 +794,7 @@ impl UnstableOptions { report_delayed_bugs: self.report_delayed_bugs, macro_backtrace: self.macro_backtrace, deduplicate_diagnostics: self.deduplicate_diagnostics, + track_diagnostics: self.track_diagnostics, } } } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index a8be318dea8a..af290931850f 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1585,6 +1585,8 @@ options! { "choose the TLS model to use (`rustc --print tls-models` for details)"), trace_macros: bool = (false, parse_bool, [UNTRACKED], "for every macro invocation, print its name and arguments (default: no)"), + track_diagnostics: bool = (false, parse_bool, [TRACKED], + "Tracks where in rustc a diagnostic was emitted"), // Diagnostics are considered side-effects of a query (see `QuerySideEffects`) and are saved // alongside query results and changes to translation options can affect diagnostics - so // translation options should be tracked. diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index b5e25f45fa75..0c04a2f24499 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -287,6 +287,7 @@ impl Session { } #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_warn>( &self, sp: S, @@ -295,6 +296,7 @@ impl Session { self.diagnostic().struct_span_warn(sp, msg) } #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_warn_with_expectation>( &self, sp: S, @@ -304,6 +306,7 @@ impl Session { self.diagnostic().struct_span_warn_with_expectation(sp, msg, id) } #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_warn_with_code>( &self, sp: S, @@ -313,10 +316,12 @@ impl Session { self.diagnostic().struct_span_warn_with_code(sp, msg, code) } #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_warn(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { self.diagnostic().struct_warn(msg) } #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_warn_with_expectation( &self, msg: impl Into, @@ -345,6 +350,7 @@ impl Session { self.diagnostic().struct_expect(msg, id) } #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_err>( &self, sp: S, @@ -353,6 +359,7 @@ impl Session { self.diagnostic().struct_span_err(sp, msg) } #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_err_with_code>( &self, sp: S, @@ -363,12 +370,14 @@ impl Session { } // FIXME: This method should be removed (every error should have an associated error code). #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_err( &self, msg: impl Into, ) -> DiagnosticBuilder<'_, ErrorGuaranteed> { self.parse_sess.struct_err(msg) } + #[track_caller] #[rustc_lint_diagnostics] pub fn struct_err_with_code( &self, @@ -378,6 +387,7 @@ impl Session { self.diagnostic().struct_err_with_code(msg, code) } #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_warn_with_code( &self, msg: impl Into, @@ -425,6 +435,7 @@ impl Session { self.diagnostic().fatal(msg).raise() } #[rustc_lint_diagnostics] + #[track_caller] pub fn span_err_or_warn>( &self, is_warning: bool, @@ -438,6 +449,7 @@ impl Session { } } #[rustc_lint_diagnostics] + #[track_caller] pub fn span_err>( &self, sp: S, @@ -458,12 +470,14 @@ impl Session { pub fn err(&self, msg: impl Into) -> ErrorGuaranteed { self.diagnostic().err(msg) } + #[track_caller] pub fn create_err<'a>( &'a self, err: impl IntoDiagnostic<'a>, ) -> DiagnosticBuilder<'a, ErrorGuaranteed> { self.parse_sess.create_err(err) } + #[track_caller] pub fn create_feature_err<'a>( &'a self, err: impl IntoDiagnostic<'a>, @@ -1214,6 +1228,7 @@ fn default_emitter( fallback_bundle: LazyFallbackBundle, ) -> Box { let macro_backtrace = sopts.unstable_opts.macro_backtrace; + let track_diagnostics = sopts.unstable_opts.track_diagnostics; match sopts.error_format { config::ErrorOutputType::HumanReadable(kind) => { let (short, color_config) = kind.unzip(); @@ -1237,6 +1252,7 @@ fn default_emitter( sopts.unstable_opts.teach, sopts.diagnostic_width, macro_backtrace, + track_diagnostics, ); Box::new(emitter.ui_testing(sopts.unstable_opts.ui_testing)) } @@ -1251,6 +1267,7 @@ fn default_emitter( json_rendered, sopts.diagnostic_width, macro_backtrace, + track_diagnostics, ) .ui_testing(sopts.unstable_opts.ui_testing), ), @@ -1553,11 +1570,18 @@ fn early_error_handler(output: config::ErrorOutputType) -> rustc_errors::Handler false, None, false, + false, )) } - config::ErrorOutputType::Json { pretty, json_rendered } => { - Box::new(JsonEmitter::basic(pretty, json_rendered, None, fallback_bundle, None, false)) - } + config::ErrorOutputType::Json { pretty, json_rendered } => Box::new(JsonEmitter::basic( + pretty, + json_rendered, + None, + fallback_bundle, + None, + false, + false, + )), }; rustc_errors::Handler::with_emitter(true, None, emitter) } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 858e939bd96e..2a61c2451b63 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -172,6 +172,7 @@ pub(crate) fn new_handler( unstable_opts.teach, diagnostic_width, false, + false, ) .ui_testing(unstable_opts.ui_testing), ) @@ -190,6 +191,7 @@ pub(crate) fn new_handler( json_rendered, diagnostic_width, false, + false, ) .ui_testing(unstable_opts.ui_testing), ) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index ac8b5211878f..7bd7fc5ea752 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -551,6 +551,7 @@ pub(crate) fn make_test( false, Some(80), false, + false, ) .supports_color(); @@ -564,6 +565,7 @@ pub(crate) fn make_test( false, None, false, + false, ); // FIXME(misdreavus): pass `-Z treat-err-as-bug` to the doctest parser @@ -748,6 +750,7 @@ fn check_if_attr_is_complete(source: &str, edition: Edition) -> bool { false, None, false, + false, ); let handler = Handler::with_emitter(false, None, Box::new(emitter)); diff --git a/src/test/ui/track-diagnostics/track.rs b/src/test/ui/track-diagnostics/track.rs new file mode 100644 index 000000000000..3427c593e856 --- /dev/null +++ b/src/test/ui/track-diagnostics/track.rs @@ -0,0 +1,6 @@ +// compile-flags: -Z track-diagnostics +// error-pattern: created at + +fn main() { + break rust +} diff --git a/src/test/ui/track-diagnostics/track.stderr b/src/test/ui/track-diagnostics/track.stderr new file mode 100644 index 000000000000..83ff935dbabd --- /dev/null +++ b/src/test/ui/track-diagnostics/track.stderr @@ -0,0 +1,26 @@ +error[E0425]: cannot find value `rust` in this scope + --> $DIR/track.rs:5:11 + | +LL | break rust + | ^^^^ not found in this scope +-Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:289:28 + +error[E0268]: `break` outside of a loop + --> $DIR/track.rs:5:5 + | +LL | break rust + | ^^^^^^^^^^ cannot `break` outside of a loop +-Ztrack-diagnostics: created at compiler/rustc_passes/src/errors.rs:957:10 + +error: internal compiler error: It looks like you're trying to break rust; would you like some ICE? + +note: the compiler expectedly panicked. this is a feature. + +note: we would appreciate a joke overview: https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675 + +note: rustc 1.66.0-dev running on x86_64-pc-windows-msvc + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0268, E0425. +For more information about an error, try `rustc --explain E0268`. diff --git a/src/tools/clippy/clippy_lints/src/doc.rs b/src/tools/clippy/clippy_lints/src/doc.rs index 36dc7e3396b8..9e2facf0f63b 100644 --- a/src/tools/clippy/clippy_lints/src/doc.rs +++ b/src/tools/clippy/clippy_lints/src/doc.rs @@ -691,6 +691,7 @@ fn check_code(cx: &LateContext<'_>, text: &str, edition: Edition, span: Span) { false, None, false, + false, ); let handler = Handler::with_emitter(false, None, Box::new(emitter)); let sess = ParseSess::with_span_handler(handler, sm); diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs index b12208ac62a8..ae54b2078a65 100644 --- a/src/tools/clippy/src/driver.rs +++ b/src/tools/clippy/src/driver.rs @@ -179,6 +179,7 @@ fn report_clippy_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { false, None, false, + false, )); let handler = rustc_errors::Handler::with_emitter(true, None, emitter); diff --git a/src/tools/rustfmt/src/parse/session.rs b/src/tools/rustfmt/src/parse/session.rs index 6efeee98fea6..6bfec79cd703 100644 --- a/src/tools/rustfmt/src/parse/session.rs +++ b/src/tools/rustfmt/src/parse/session.rs @@ -134,6 +134,7 @@ fn default_handler( false, None, false, + false, )) }; Handler::with_emitter(