From 04532e930c9accf08955a3a906fcb49a11130a68 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 12 Jan 2024 00:30:04 +0000 Subject: [PATCH] Give me a way to emit all the delayed bugs --- compiler/rustc_errors/src/lib.rs | 26 ++++++++++++------- compiler/rustc_session/src/config.rs | 1 + compiler/rustc_session/src/options.rs | 3 +++ tests/ui/treat-err-as-bug/eagerly-emit.rs | 11 ++++++++ tests/ui/treat-err-as-bug/eagerly-emit.stderr | 26 +++++++++++++++++++ 5 files changed, 58 insertions(+), 9 deletions(-) create mode 100644 tests/ui/treat-err-as-bug/eagerly-emit.rs create mode 100644 tests/ui/treat-err-as-bug/eagerly-emit.stderr diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 8fb539fc3582f..21e9629d3e77e 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -527,6 +527,9 @@ pub struct DiagCtxtFlags { /// If Some, the Nth error-level diagnostic is upgraded to bug-level. /// (rustc: see `-Z treat-err-as-bug`) pub treat_err_as_bug: Option, + /// Eagerly emit delayed bugs as errors, so that the compiler debugger may + /// see all of the errors being emitted at once. + pub eagerly_emit_delayed_bugs: bool, /// Show macro backtraces. /// (rustc: see `-Z macro-backtrace`) pub macro_backtrace: bool, @@ -1269,16 +1272,21 @@ impl DiagCtxtInner { } 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)); + if self.flags.eagerly_emit_delayed_bugs { + // Emit error as bug, rather than stashing it. + diagnostic.level = Error; + } else { + // 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)); - #[allow(deprecated)] - return Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()); + #[allow(deprecated)] + return Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()); + } } if diagnostic.has_future_breakage() { diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 61796d7a6cafc..8918dce7d3a41 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1146,6 +1146,7 @@ impl UnstableOptions { DiagCtxtFlags { can_emit_warnings, treat_err_as_bug: self.treat_err_as_bug, + eagerly_emit_delayed_bugs: self.eagerly_emit_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 c97b18ebd66ad..2d91a3fbd9116 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1583,6 +1583,9 @@ options! { "version of DWARF debug information to emit (default: 2 or 4, depending on platform)"), dylib_lto: bool = (false, parse_bool, [UNTRACKED], "enables LTO for dylib crate type"), + eagerly_emit_delayed_bugs: bool = (false, parse_bool, [UNTRACKED], + "emit delayed bugs eagerly as errors instead of stashing them and emitting \ + them only if an error has not been emitted"), ehcont_guard: bool = (false, parse_bool, [TRACKED], "generate Windows EHCont Guard tables"), emit_stack_sizes: bool = (false, parse_bool, [UNTRACKED], diff --git a/tests/ui/treat-err-as-bug/eagerly-emit.rs b/tests/ui/treat-err-as-bug/eagerly-emit.rs new file mode 100644 index 0000000000000..5f32f5a1d94b7 --- /dev/null +++ b/tests/ui/treat-err-as-bug/eagerly-emit.rs @@ -0,0 +1,11 @@ +// compile-flags: -Zeagerly-emit-delayed-bugs + +trait Foo {} + +fn main() {} + +fn f() -> impl Foo { + //~^ ERROR the trait bound `i32: Foo` is not satisfied + //~| ERROR `report_selection_error` did not emit an error + 1i32 +} diff --git a/tests/ui/treat-err-as-bug/eagerly-emit.stderr b/tests/ui/treat-err-as-bug/eagerly-emit.stderr new file mode 100644 index 0000000000000..c2a625fbec82d --- /dev/null +++ b/tests/ui/treat-err-as-bug/eagerly-emit.stderr @@ -0,0 +1,26 @@ +error: `report_selection_error` did not emit an error + --> $DIR/eagerly-emit.rs:7:11 + | +LL | fn f() -> impl Foo { + | ^^^^^^^^ + +error[E0277]: the trait bound `i32: Foo` is not satisfied + --> $DIR/eagerly-emit.rs:7:11 + | +LL | fn f() -> impl Foo { + | ^^^^^^^^ the trait `Foo` is not implemented for `i32` +... +LL | 1i32 + | ---- return type was inferred to be `i32` here + | +help: this trait has no implementations, consider adding one + --> $DIR/eagerly-emit.rs:3:1 + | +LL | trait Foo {} + | ^^^^^^^^^ + +error: expected fulfillment errors + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`.