summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_errors/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_errors/src/lib.rs')
-rw-r--r--compiler/rustc_errors/src/lib.rs71
1 files changed, 64 insertions, 7 deletions
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 0963ea71f..eb0506c45 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -5,6 +5,7 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(drain_filter)]
#![feature(if_let_guard)]
+#![feature(is_terminal)]
#![feature(adt_const_params)]
#![feature(let_chains)]
#![feature(never_type)]
@@ -376,7 +377,7 @@ pub use diagnostic::{
DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic,
};
pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee, Noted};
-pub use diagnostic_impls::DiagnosticArgFromDisplay;
+pub use diagnostic_impls::{DiagnosticArgFromDisplay, DiagnosticSymbolList};
use std::backtrace::Backtrace;
/// A handler deals with errors and other compiler output.
@@ -466,6 +467,10 @@ pub enum StashKey {
/// When an invalid lifetime e.g. `'2` should be reinterpreted
/// as a char literal in the parser
LifetimeIsChar,
+ /// Maybe there was a typo where a comma was forgotten before
+ /// FRU syntax
+ MaybeFruTypo,
+ CallAssocMethod,
}
fn default_track_diagnostic(_: &Diagnostic) {}
@@ -492,6 +497,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 {
@@ -559,6 +566,7 @@ impl Handler {
false,
None,
flags.macro_backtrace,
+ flags.track_diagnostics,
));
Self::with_emitter_and_flags(emitter, flags)
}
@@ -641,13 +649,14 @@ impl Handler {
inner.stashed_diagnostics = Default::default();
}
- /// Stash a given diagnostic with the given `Span` and `StashKey` as the key for later stealing.
+ /// Stash a given diagnostic with the given `Span` and [`StashKey`] as the key.
+ /// Retrieve a stashed diagnostic with `steal_diagnostic`.
pub fn stash_diagnostic(&self, span: Span, key: StashKey, diag: Diagnostic) {
let mut inner = self.inner.borrow_mut();
inner.stash((span, key), diag);
}
- /// Steal a previously stashed diagnostic with the given `Span` and `StashKey` as the key.
+ /// Steal a previously stashed diagnostic with the given `Span` and [`StashKey`] as the key.
pub fn steal_diagnostic(&self, span: Span, key: StashKey) -> Option<DiagnosticBuilder<'_, ()>> {
let mut inner = self.inner.borrow_mut();
inner.steal((span, key)).map(|diag| DiagnosticBuilder::new_diagnostic(self, diag))
@@ -664,6 +673,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<G: EmissionGuarantee>(
&self,
msg: impl Into<DiagnosticMessage>,
@@ -677,6 +687,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<MultiSpan>,
@@ -693,6 +704,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<MultiSpan>,
@@ -706,6 +718,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<MultiSpan>,
@@ -719,6 +732,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<MultiSpan>,
@@ -736,6 +750,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<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> {
DiagnosticBuilder::new(self, Level::Warning(None), msg)
}
@@ -746,6 +761,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<DiagnosticMessage>,
@@ -756,12 +772,14 @@ impl Handler {
/// Construct a builder at the `Allow` level with the `msg`.
#[rustc_lint_diagnostics]
+ #[track_caller]
pub fn struct_allow(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> {
DiagnosticBuilder::new(self, Level::Allow, msg)
}
/// Construct a builder at the `Expect` level with the `msg`.
#[rustc_lint_diagnostics]
+ #[track_caller]
pub fn struct_expect(
&self,
msg: impl Into<DiagnosticMessage>,
@@ -772,6 +790,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<MultiSpan>,
@@ -784,6 +803,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<MultiSpan>,
@@ -798,6 +818,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<DiagnosticMessage>,
@@ -807,12 +828,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<DiagnosticMessage>) -> 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<DiagnosticMessage>,
@@ -825,6 +848,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<DiagnosticMessage>,
@@ -837,6 +861,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<MultiSpan>,
@@ -849,6 +874,7 @@ impl Handler {
/// Construct a builder at the `Fatal` level at the given `span`, with the `msg`, and `code`.
#[rustc_lint_diagnostics]
+ #[track_caller]
pub fn struct_span_fatal_with_code(
&self,
span: impl Into<MultiSpan>,
@@ -862,6 +888,7 @@ impl Handler {
/// Construct a builder at the `Error` level with the `msg`.
#[rustc_lint_diagnostics]
+ #[track_caller]
pub fn struct_fatal(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, !> {
DiagnosticBuilder::new_fatal(self, msg)
}
@@ -874,6 +901,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<DiagnosticMessage>,
@@ -882,12 +910,14 @@ impl Handler {
}
#[rustc_lint_diagnostics]
+ #[track_caller]
pub fn span_fatal(&self, span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) -> ! {
self.emit_diag_at_span(Diagnostic::new(Fatal, msg), span);
FatalError.raise()
}
#[rustc_lint_diagnostics]
+ #[track_caller]
pub fn span_fatal_with_code(
&self,
span: impl Into<MultiSpan>,
@@ -899,6 +929,7 @@ impl Handler {
}
#[rustc_lint_diagnostics]
+ #[track_caller]
pub fn span_err(
&self,
span: impl Into<MultiSpan>,
@@ -908,6 +939,7 @@ impl Handler {
}
#[rustc_lint_diagnostics]
+ #[track_caller]
pub fn span_err_with_code(
&self,
span: impl Into<MultiSpan>,
@@ -921,11 +953,13 @@ impl Handler {
}
#[rustc_lint_diagnostics]
+ #[track_caller]
pub fn span_warn(&self, span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) {
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<MultiSpan>,
@@ -954,10 +988,12 @@ impl Handler {
self.inner.borrow_mut().delay_good_path_bug(msg)
}
+ #[track_caller]
pub fn span_bug_no_panic(&self, span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) {
self.emit_diag_at_span(Diagnostic::new(Bug, msg), span);
}
+ #[track_caller]
pub fn span_note_without_error(
&self,
span: impl Into<MultiSpan>,
@@ -966,6 +1002,7 @@ impl Handler {
self.emit_diag_at_span(Diagnostic::new(Note, msg), span);
}
+ #[track_caller]
pub fn span_note_diag(
&self,
span: Span,
@@ -1008,13 +1045,24 @@ impl Handler {
}
pub fn has_errors_or_lint_errors(&self) -> Option<ErrorGuaranteed> {
if self.inner.borrow().has_errors_or_lint_errors() {
- Some(ErrorGuaranteed(()))
+ Some(ErrorGuaranteed::unchecked_claim_error_was_emitted())
} else {
None
}
}
- pub fn has_errors_or_delayed_span_bugs(&self) -> bool {
- self.inner.borrow().has_errors_or_delayed_span_bugs()
+ pub fn has_errors_or_delayed_span_bugs(&self) -> Option<ErrorGuaranteed> {
+ if self.inner.borrow().has_errors_or_delayed_span_bugs() {
+ Some(ErrorGuaranteed::unchecked_claim_error_was_emitted())
+ } else {
+ None
+ }
+ }
+ pub fn is_compilation_going_to_fail(&self) -> Option<ErrorGuaranteed> {
+ if self.inner.borrow().is_compilation_going_to_fail() {
+ Some(ErrorGuaranteed::unchecked_claim_error_was_emitted())
+ } else {
+ None
+ }
}
pub fn print_error_count(&self, registry: &Registry) {
@@ -1223,6 +1271,10 @@ impl HandlerInner {
}
if diagnostic.has_future_breakage() {
+ // Future breakages aren't emitted if they're Level::Allowed,
+ // but they still need to be constructed and stashed below,
+ // so they'll trigger the good-path bug check.
+ self.suppressed_expected_diag = true;
self.future_breakage_diagnostics.push(diagnostic.clone());
}
@@ -1277,7 +1329,7 @@ impl HandlerInner {
diagnostic.children.drain_filter(already_emitted_sub).for_each(|_| {});
- self.emitter.emit_diagnostic(&diagnostic);
+ self.emitter.emit_diagnostic(diagnostic);
if diagnostic.is_error() {
self.deduplicated_err_count += 1;
} else if let Warning(_) = diagnostic.level {
@@ -1444,6 +1496,10 @@ impl HandlerInner {
self.err_count() > 0 || self.lint_err_count > 0 || self.warn_count > 0
}
+ fn is_compilation_going_to_fail(&self) -> bool {
+ self.has_errors() || self.lint_err_count > 0 || !self.delayed_span_bugs.is_empty()
+ }
+
fn abort_if_errors(&mut self) {
self.emit_stashed_diagnostics();
@@ -1452,6 +1508,7 @@ impl HandlerInner {
}
}
+ #[track_caller]
fn span_bug(&mut self, sp: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) -> ! {
self.emit_diag_at_span(Diagnostic::new(Bug, msg), sp);
panic::panic_any(ExplicitBug);