Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Good path bugs are just a flavor of delayed bug
  • Loading branch information
compiler-errors committed Jan 12, 2024
commit eb79bc0470e0eefbc7608cffb99879969d68faea
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ fn source_string(file: Lrc<SourceFile>, line: &Line) -> String {
/// Maps `Diagnostic::Level` to `snippet::AnnotationType`
fn annotation_type_for_level(level: Level) -> AnnotationType {
match level {
Level::Bug | Level::DelayedBug | Level::Fatal | Level::Error => AnnotationType::Error,
Level::Bug | Level::DelayedBug(_) | Level::Fatal | Level::Error => AnnotationType::Error,
Level::ForceWarning(_) | Level::Warning => AnnotationType::Warning,
Level::Note | Level::OnceNote => AnnotationType::Note,
Level::Help | Level::OnceHelp => AnnotationType::Help,
Expand Down
15 changes: 9 additions & 6 deletions compiler/rustc_errors/src/diagnostic.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::snippet::Style;
use crate::{
CodeSuggestion, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee, Level, MultiSpan,
SubdiagnosticMessage, Substitution, SubstitutionPart, SuggestionStyle,
CodeSuggestion, DelayedBugKind, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee, Level,
MultiSpan, SubdiagnosticMessage, Substitution, SubstitutionPart, SuggestionStyle,
};
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
use rustc_error_messages::fluent_value_from_str_list_sep_by_and;
Expand Down Expand Up @@ -243,12 +243,15 @@ impl Diagnostic {

pub fn is_error(&self) -> bool {
match self.level {
Level::Bug | Level::DelayedBug | Level::Fatal | Level::Error | Level::FailureNote => {
true
}
Level::Bug
| Level::DelayedBug(DelayedBugKind::Normal)
| Level::Fatal
| Level::Error
| Level::FailureNote => true,

Level::ForceWarning(_)
| Level::Warning
| Level::DelayedBug(DelayedBugKind::GoodPath)
| Level::Note
| Level::OnceNote
| Level::Help
Expand Down Expand Up @@ -318,7 +321,7 @@ impl Diagnostic {
"downgrade_to_delayed_bug: cannot downgrade {:?} to DelayedBug: not an error",
self.level
);
self.level = Level::DelayedBug;
self.level = Level::DelayedBug(DelayedBugKind::Normal);
}

/// Appends a labeled span to the diagnostic.
Expand Down
56 changes: 34 additions & 22 deletions compiler/rustc_errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,8 @@ fn default_track_diagnostic(diag: Diagnostic, f: &mut dyn FnMut(Diagnostic)) {
pub static TRACK_DIAGNOSTIC: AtomicRef<fn(Diagnostic, &mut dyn FnMut(Diagnostic))> =
AtomicRef::new(&(default_track_diagnostic as _));

enum DelayedBugKind {
#[derive(Copy, PartialEq, Eq, Clone, Hash, Debug, Encodable, Decodable)]
pub enum DelayedBugKind {
Normal,
GoodPath,
}
Expand Down Expand Up @@ -865,7 +866,8 @@ impl DiagCtxt {
if treat_next_err_as_bug {
self.bug(msg);
}
DiagnosticBuilder::<ErrorGuaranteed>::new(self, DelayedBug, msg).emit()
DiagnosticBuilder::<ErrorGuaranteed>::new(self, DelayedBug(DelayedBugKind::Normal), msg)
.emit()
}

/// Like `delayed_bug`, but takes an additional span.
Expand All @@ -882,16 +884,15 @@ impl DiagCtxt {
if treat_next_err_as_bug {
self.span_bug(sp, msg);
}
DiagnosticBuilder::<ErrorGuaranteed>::new(self, DelayedBug, msg).with_span(sp).emit()
DiagnosticBuilder::<ErrorGuaranteed>::new(self, DelayedBug(DelayedBugKind::Normal), msg)
.with_span(sp)
.emit()
}

// FIXME(eddyb) note the comment inside `impl Drop for DiagCtxtInner`, that's
// where the explanation of what "good path" is (also, it should be renamed).
pub fn good_path_delayed_bug(&self, msg: impl Into<DiagnosticMessage>) {
let mut inner = self.inner.borrow_mut();
let diagnostic = Diagnostic::new(DelayedBug, msg);
let backtrace = std::backtrace::Backtrace::capture();
inner.good_path_delayed_bugs.push(DelayedDiagnostic::with_backtrace(diagnostic, backtrace));
DiagnosticBuilder::<()>::new(self, DelayedBug(DelayedBugKind::GoodPath), msg).emit()
}

#[track_caller]
Expand Down Expand Up @@ -1268,17 +1269,27 @@ impl DiagCtxtInner {
return None;
}

if diagnostic.level == DelayedBug {
// FIXME(eddyb) this should check for `has_errors` and stop pushing
// once *any* errors were emitted (and truncate `span_delayed_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.
let backtrace = std::backtrace::Backtrace::capture();
self.span_delayed_bugs
.push(DelayedDiagnostic::with_backtrace(diagnostic.clone(), backtrace));
// FIXME(eddyb) this should check for `has_errors` and stop pushing
// once *any* errors were emitted (and truncate `span_delayed_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.
match diagnostic.level {
DelayedBug(DelayedBugKind::Normal) => {
let backtrace = std::backtrace::Backtrace::capture();
self.span_delayed_bugs
.push(DelayedDiagnostic::with_backtrace(diagnostic.clone(), backtrace));

#[allow(deprecated)]
return Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
#[allow(deprecated)]
return Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
}
DelayedBug(DelayedBugKind::GoodPath) => {
let backtrace = std::backtrace::Backtrace::capture();
self.good_path_delayed_bugs
.push(DelayedDiagnostic::with_backtrace(diagnostic.clone(), backtrace));

return None;
}
_ => {}
}

if diagnostic.has_future_breakage() {
Expand Down Expand Up @@ -1438,7 +1449,7 @@ impl DiagCtxtInner {
if backtrace || self.ice_file.is_none() { bug.decorate() } else { bug.inner };

// "Undelay" the `DelayedBug`s (into plain `Bug`s).
if bug.level != DelayedBug {
if !matches!(bug.level, DelayedBug(_)) {
// NOTE(eddyb) not panicking here because we're already producing
// an ICE, and the more information the merrier.
bug.subdiagnostic(InvalidFlushedDelayedDiagnosticLevel {
Expand Down Expand Up @@ -1526,8 +1537,9 @@ pub enum Level {
/// silently dropped. I.e. "expect other errors are emitted" semantics. Useful on code paths
/// that should only be reached when compiling erroneous code.
///
/// Its `EmissionGuarantee` is `ErrorGuaranteed`.
DelayedBug,
/// Its `EmissionGuarantee` is `ErrorGuaranteed` for `Normal` delayed bugs, and `()` for
/// `GoodPath` delayed bugs.
DelayedBug(DelayedBugKind),

/// An error that causes an immediate abort. Used for things like configuration errors,
/// internal overflows, some file operation errors.
Expand Down Expand Up @@ -1602,7 +1614,7 @@ impl Level {
fn color(self) -> ColorSpec {
let mut spec = ColorSpec::new();
match self {
Bug | DelayedBug | Fatal | Error => {
Bug | DelayedBug(_) | Fatal | Error => {
spec.set_fg(Some(Color::Red)).set_intense(true);
}
ForceWarning(_) | Warning => {
Expand All @@ -1622,7 +1634,7 @@ impl Level {

pub fn to_str(self) -> &'static str {
match self {
Bug | DelayedBug => "error: internal compiler error",
Bug | DelayedBug(_) => "error: internal compiler error",
Fatal | Error => "error",
ForceWarning(_) | Warning => "warning",
Note | OnceNote => "note",
Expand Down