diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:13 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:13 +0000 |
commit | 218caa410aa38c29984be31a5229b9fa717560ee (patch) | |
tree | c54bd55eeb6e4c508940a30e94c0032fbd45d677 /compiler/rustc_errors/src/lib.rs | |
parent | Releasing progress-linux version 1.67.1+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-218caa410aa38c29984be31a5229b9fa717560ee.tar.xz rustc-218caa410aa38c29984be31a5229b9fa717560ee.zip |
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_errors/src/lib.rs')
-rw-r--r-- | compiler/rustc_errors/src/lib.rs | 177 |
1 files changed, 106 insertions, 71 deletions
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index eb0506c45..535812fb0 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -11,6 +11,10 @@ #![feature(never_type)] #![feature(result_option_inspect)] #![feature(rustc_attrs)] +#![feature(yeet_expr)] +#![feature(try_blocks)] +#![feature(box_patterns)] +#![feature(error_reporter)] #![allow(incomplete_features)] #[macro_use] @@ -41,11 +45,12 @@ use rustc_span::HashStableContext; use rustc_span::{Loc, Span}; use std::borrow::Cow; +use std::error::Report; +use std::fmt; use std::hash::Hash; use std::num::NonZeroUsize; use std::panic; use std::path::Path; -use std::{error, fmt}; use termcolor::{Color, ColorSpec}; @@ -54,11 +59,14 @@ mod diagnostic; mod diagnostic_builder; mod diagnostic_impls; pub mod emitter; +pub mod error; pub mod json; mod lock; pub mod registry; mod snippet; mod styled_buffer; +#[cfg(test)] +mod tests; pub mod translation; pub use diagnostic_builder::IntoDiagnostic; @@ -324,7 +332,7 @@ impl CodeSuggestion { // Account for the difference between the width of the current code and the // snippet being suggested, so that the *later* suggestions are correctly // aligned on the screen. - acc += len as isize - (cur_hi.col.0 - cur_lo.col.0) as isize; + acc += len - (cur_hi.col.0 - cur_lo.col.0) as isize; } prev_hi = cur_hi; prev_line = sf.get_line(prev_hi.line - 1); @@ -361,16 +369,11 @@ pub use rustc_span::fatal_error::{FatalError, FatalErrorMarker}; /// Signifies that the compiler died with an explicit call to `.bug` /// or `.span_bug` rather than a failed assertion, etc. -#[derive(Copy, Clone, Debug)] pub struct ExplicitBug; -impl fmt::Display for ExplicitBug { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "parser internal bug") - } -} - -impl error::Error for ExplicitBug {} +/// Signifies that the compiler died with an explicit call to `.delay_*_bug` +/// rather than a failed assertion, etc. +pub struct DelayedBugPanic; pub use diagnostic::{ AddToDiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgValue, DiagnosticId, @@ -403,7 +406,7 @@ struct HandlerInner { warn_count: usize, deduplicated_err_count: usize, emitter: Box<dyn Emitter + sync::Send>, - delayed_span_bugs: Vec<Diagnostic>, + delayed_span_bugs: Vec<DelayedDiagnostic>, delayed_good_path_bugs: Vec<DelayedDiagnostic>, /// This flag indicates that an expected diagnostic was emitted and suppressed. /// This is used for the `delayed_good_path_bugs` check. @@ -473,10 +476,12 @@ pub enum StashKey { CallAssocMethod, } -fn default_track_diagnostic(_: &Diagnostic) {} +fn default_track_diagnostic(d: &mut Diagnostic, f: &mut dyn FnMut(&mut Diagnostic)) { + (*f)(d) +} -pub static TRACK_DIAGNOSTICS: AtomicRef<fn(&Diagnostic)> = - AtomicRef::new(&(default_track_diagnostic as fn(&_))); +pub static TRACK_DIAGNOSTICS: AtomicRef<fn(&mut Diagnostic, &mut dyn FnMut(&mut Diagnostic))> = + AtomicRef::new(&(default_track_diagnostic as _)); #[derive(Copy, Clone, Default)] pub struct HandlerFlags { @@ -518,7 +523,7 @@ impl Drop for HandlerInner { if !self.has_any_message() && !self.suppressed_expected_diag { let bugs = std::mem::replace(&mut self.delayed_good_path_bugs, Vec::new()); self.flush_delayed( - bugs.into_iter().map(DelayedDiagnostic::decorate), + bugs, "no warnings or errors encountered even though `delayed_good_path_bugs` issued", ); } @@ -619,7 +624,14 @@ impl Handler { ) -> SubdiagnosticMessage { let inner = self.inner.borrow(); let args = crate::translation::to_fluent_args(args); - SubdiagnosticMessage::Eager(inner.emitter.translate_message(&message, &args).to_string()) + SubdiagnosticMessage::Eager( + inner + .emitter + .translate_message(&message, &args) + .map_err(Report::new) + .unwrap() + .to_string(), + ) } // This is here to not allow mutation of flags; @@ -653,17 +665,19 @@ impl Handler { /// 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); + inner.stash((span.with_parent(None), key), diag); } /// 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)) + inner + .steal((span.with_parent(None), key)) + .map(|diag| DiagnosticBuilder::new_diagnostic(self, diag)) } pub fn has_stashed_diagnostic(&self, span: Span, key: StashKey) -> bool { - self.inner.borrow().stashed_diagnostics.get(&(span, key)).is_some() + self.inner.borrow().stashed_diagnostics.get(&(span.with_parent(None), key)).is_some() } /// Emit all stashed diagnostics. @@ -973,6 +987,7 @@ impl Handler { self.inner.borrow_mut().span_bug(span, msg) } + /// For documentation on this, see `Session::delay_span_bug`. #[track_caller] pub fn delay_span_bug( &self, @@ -1127,6 +1142,20 @@ impl Handler { self.create_fatal(fatal).emit() } + pub fn create_bug<'a>( + &'a self, + bug: impl IntoDiagnostic<'a, diagnostic_builder::Bug>, + ) -> DiagnosticBuilder<'a, diagnostic_builder::Bug> { + bug.into_diagnostic(self) + } + + pub fn emit_bug<'a>( + &'a self, + bug: impl IntoDiagnostic<'a, diagnostic_builder::Bug>, + ) -> diagnostic_builder::Bug { + self.create_bug(bug).emit() + } + fn emit_diag_at_span( &self, mut diag: Diagnostic, @@ -1212,8 +1241,8 @@ impl HandlerInner { self.taught_diagnostics.insert(code.clone()) } - fn force_print_diagnostic(&mut self, mut db: Diagnostic) { - self.emitter.emit_diagnostic(&mut db); + fn force_print_diagnostic(&mut self, db: Diagnostic) { + self.emitter.emit_diagnostic(&db); } /// Emit all stashed diagnostics. @@ -1263,7 +1292,9 @@ impl HandlerInner { // once *any* errors were emitted (and truncate `delayed_span_bugs` // when an error is first emitted, also), but maybe there's a case // in which that's not sound? otherwise this is really inefficient. - self.delayed_span_bugs.push(diagnostic.clone()); + let backtrace = std::backtrace::Backtrace::force_capture(); + self.delayed_span_bugs + .push(DelayedDiagnostic::with_backtrace(diagnostic.clone(), backtrace)); if !self.flags.report_delayed_bugs { return Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()); @@ -1288,67 +1319,69 @@ impl HandlerInner { && !diagnostic.is_force_warn() { if diagnostic.has_future_breakage() { - (*TRACK_DIAGNOSTICS)(diagnostic); + (*TRACK_DIAGNOSTICS)(diagnostic, &mut |_| {}); } return None; } - (*TRACK_DIAGNOSTICS)(diagnostic); - if matches!(diagnostic.level, Level::Expect(_) | Level::Allow) { + (*TRACK_DIAGNOSTICS)(diagnostic, &mut |_| {}); return None; } - if let Some(ref code) = diagnostic.code { - self.emitted_diagnostic_codes.insert(code.clone()); - } - - let already_emitted = |this: &mut Self| { - let mut hasher = StableHasher::new(); - diagnostic.hash(&mut hasher); - let diagnostic_hash = hasher.finish(); - !this.emitted_diagnostics.insert(diagnostic_hash) - }; + let mut guaranteed = None; + (*TRACK_DIAGNOSTICS)(diagnostic, &mut |diagnostic| { + if let Some(ref code) = diagnostic.code { + self.emitted_diagnostic_codes.insert(code.clone()); + } - // Only emit the diagnostic if we've been asked to deduplicate or - // haven't already emitted an equivalent diagnostic. - if !(self.flags.deduplicate_diagnostics && already_emitted(self)) { - debug!(?diagnostic); - debug!(?self.emitted_diagnostics); - let already_emitted_sub = |sub: &mut SubDiagnostic| { - debug!(?sub); - if sub.level != Level::OnceNote { - return false; - } + let already_emitted = |this: &mut Self| { let mut hasher = StableHasher::new(); - sub.hash(&mut hasher); + diagnostic.hash(&mut hasher); let diagnostic_hash = hasher.finish(); - debug!(?diagnostic_hash); - !self.emitted_diagnostics.insert(diagnostic_hash) + !this.emitted_diagnostics.insert(diagnostic_hash) }; - diagnostic.children.drain_filter(already_emitted_sub).for_each(|_| {}); - - self.emitter.emit_diagnostic(diagnostic); - if diagnostic.is_error() { - self.deduplicated_err_count += 1; - } else if let Warning(_) = diagnostic.level { - self.deduplicated_warn_count += 1; + // Only emit the diagnostic if we've been asked to deduplicate or + // haven't already emitted an equivalent diagnostic. + if !(self.flags.deduplicate_diagnostics && already_emitted(self)) { + debug!(?diagnostic); + debug!(?self.emitted_diagnostics); + let already_emitted_sub = |sub: &mut SubDiagnostic| { + debug!(?sub); + if sub.level != Level::OnceNote { + return false; + } + let mut hasher = StableHasher::new(); + sub.hash(&mut hasher); + let diagnostic_hash = hasher.finish(); + debug!(?diagnostic_hash); + !self.emitted_diagnostics.insert(diagnostic_hash) + }; + + diagnostic.children.drain_filter(already_emitted_sub).for_each(|_| {}); + + self.emitter.emit_diagnostic(diagnostic); + if diagnostic.is_error() { + self.deduplicated_err_count += 1; + } else if let Warning(_) = diagnostic.level { + self.deduplicated_warn_count += 1; + } } - } - if diagnostic.is_error() { - if matches!(diagnostic.level, Level::Error { lint: true }) { - self.bump_lint_err_count(); + if diagnostic.is_error() { + if matches!(diagnostic.level, Level::Error { lint: true }) { + self.bump_lint_err_count(); + } else { + self.bump_err_count(); + } + + guaranteed = Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()); } else { - self.bump_err_count(); + self.bump_warn_count(); } + }); - Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()) - } else { - self.bump_warn_count(); - - None - } + guaranteed } fn emit_artifact_notification(&mut self, path: &Path, artifact_type: &str) { @@ -1518,6 +1551,7 @@ impl HandlerInner { self.emit_diagnostic(diag.set_span(sp)); } + /// For documentation on this, see `Session::delay_span_bug`. #[track_caller] fn delay_span_bug( &mut self, @@ -1535,7 +1569,6 @@ impl HandlerInner { } let mut diagnostic = Diagnostic::new(Level::DelayedBug, msg); diagnostic.set_span(sp.into()); - diagnostic.note(&format!("delayed at {}", std::panic::Location::caller())); self.emit_diagnostic(&mut diagnostic).unwrap() } @@ -1578,11 +1611,13 @@ impl HandlerInner { fn flush_delayed( &mut self, - bugs: impl IntoIterator<Item = Diagnostic>, + bugs: impl IntoIterator<Item = DelayedDiagnostic>, explanation: impl Into<DiagnosticMessage> + Copy, ) { let mut no_bugs = true; - for mut bug in bugs { + for bug in bugs { + let mut bug = bug.decorate(); + if no_bugs { // Put the overall explanation before the `DelayedBug`s, to // frame them better (e.g. separate warnings from them). @@ -1605,9 +1640,9 @@ impl HandlerInner { self.emit_diagnostic(&mut bug); } - // Panic with `ExplicitBug` to avoid "unexpected panic" messages. + // Panic with `DelayedBugPanic` to avoid "unexpected panic" messages. if !no_bugs { - panic::panic_any(ExplicitBug); + panic::panic_any(DelayedBugPanic); } } |