From f1ac54123f4cdb288a9bf136783f23a3f6f1774d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 12 Jan 2024 07:38:42 +1100 Subject: [PATCH] Don't consider delayed bugs for `-Ztreat-err-as-bug`. `-Ztreat-err-as-bug` treats normal errors and delayed bugs equally, which can lead to some really surprising results. This commit changes `-Ztreat-err-as-bug` so it ignores delayed bugs, unless they get promoted to proper bugs and are printed. This feels to me much simpler and more logical. And it simplifies the implementation: - The `-Ztreat-err-as-bug` check is removed from in `DiagCtxt::{delayed_bug,span_delayed_bug}`. - `treat_err_as_bug` doesn't need to count delayed bugs. - The `-Ztreat-err-as-bug` panic message is simpler, because it doesn't have to mention delayed bugs. Output of delayed bugs is now more consistent. They're always printed the same way. Previously when they triggered `-Ztreat-err-as-bug` they would be printed slightly differently, via `span_bug` in `span_delayed_bug` or `delayed_bug`. A minor behaviour change: the "no errors encountered even though `span_delayed_bug` issued" printed before delayed bugs is now a note rather than a bug. This is done so it doesn't get counted as an error that might trigger `-Ztreat-err-as-bug`, which would be silly. This means that if you use `-Ztreat-err-as-bug=1` and there are no normal errors but there are delayed bugs, the first delayed bug will be shown (and the panic will happen after it's printed). Also, I have added a second note saying "those delayed bugs will now be shown as internal compiler errors". I think this makes it clearer what is happening, because the whole concept of delayed bugs is non-obvious. There are some test changes. - equality-in-canonical-query.rs: Minor output changes, and the error count reduces by one because the "no errors encountered even though `span_delayed_bug` issued" message is no longer counted as an error. - rpit_tait_equality_in_canonical_query.rs: Ditto. - storage-live.rs: The query stack disappears because these delayed bugs are now printed at the end, rather than when they are created. - storage-return.rs, span_delayed_bug.rs: now need `-Zeagerly-emit-delayed-bugs` because they need the delayed bugs emitted immediately to preserve behaviour. --- compiler/rustc_errors/src/lib.rs | 64 +++++++------------ .../equality-in-canonical-query.clone.stderr | 16 ++--- .../impl-trait/equality-in-canonical-query.rs | 6 +- tests/ui/mir/lint/storage-live.stderr | 8 ++- tests/ui/mir/lint/storage-return.rs | 2 +- tests/ui/treat-err-as-bug/span_delayed_bug.rs | 2 +- ...equality_in_canonical_query.current.stderr | 16 ++--- .../rpit_tait_equality_in_canonical_query.rs | 5 +- 8 files changed, 51 insertions(+), 68 deletions(-) diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 8c2752af65974..63391a0faa6b3 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -865,10 +865,6 @@ impl DiagCtxt { /// directly). #[track_caller] pub fn delayed_bug(&self, msg: impl Into) -> ErrorGuaranteed { - let treat_next_err_as_bug = self.inner.borrow().treat_next_err_as_bug(); - if treat_next_err_as_bug { - self.bug(msg); - } DiagnosticBuilder::::new(self, DelayedBug(DelayedBugKind::Normal), msg) .emit() } @@ -883,10 +879,6 @@ impl DiagCtxt { sp: impl Into, msg: impl Into, ) -> ErrorGuaranteed { - let treat_next_err_as_bug = self.inner.borrow().treat_next_err_as_bug(); - if treat_next_err_as_bug { - self.span_bug(sp, msg); - } DiagnosticBuilder::::new(self, DelayedBug(DelayedBugKind::Normal), msg) .with_span(sp) .emit() @@ -1259,10 +1251,6 @@ impl DiagCtxtInner { } fn emit_diagnostic(&mut self, mut diagnostic: Diagnostic) -> Option { - if matches!(diagnostic.level, Error | Fatal) && self.treat_next_err_as_bug() { - diagnostic.level = Bug; - } - // The `LintExpectationId` can be stable or unstable depending on when it was created. // Diagnostics created before the definition of `HirId`s are unstable and can not yet // be stored. Instead, they are buffered until the `LintExpectationId` is replaced by @@ -1298,6 +1286,12 @@ impl DiagCtxtInner { _ => {} } + // This must come after the possible promotion of `DelayedBug` to + // `Error` above. + if matches!(diagnostic.level, Error | Fatal) && self.treat_next_err_as_bug() { + diagnostic.level = Bug; + } + if diagnostic.has_future_breakage() { // Future breakages aren't emitted if they're Level::Allow, // but they still need to be constructed and stashed below, @@ -1387,20 +1381,14 @@ impl DiagCtxtInner { } fn treat_err_as_bug(&self) -> bool { - self.flags.treat_err_as_bug.is_some_and(|c| { - self.err_count + self.lint_err_count + self.delayed_bug_count() >= c.get() - }) + self.flags.treat_err_as_bug.is_some_and(|c| self.err_count + self.lint_err_count >= c.get()) } // Use this one before incrementing `err_count`. fn treat_next_err_as_bug(&self) -> bool { - self.flags.treat_err_as_bug.is_some_and(|c| { - self.err_count + self.lint_err_count + self.delayed_bug_count() + 1 >= c.get() - }) - } - - fn delayed_bug_count(&self) -> usize { - self.span_delayed_bugs.len() + self.good_path_delayed_bugs.len() + self.flags + .treat_err_as_bug + .is_some_and(|c| self.err_count + self.lint_err_count + 1 >= c.get()) } fn has_errors(&self) -> bool { @@ -1412,7 +1400,7 @@ impl DiagCtxtInner { } fn flush_delayed(&mut self, kind: DelayedBugKind) { - let (bugs, explanation) = match kind { + let (bugs, note1) = match kind { DelayedBugKind::Normal => ( std::mem::take(&mut self.span_delayed_bugs), "no errors encountered even though `span_delayed_bug` issued", @@ -1422,6 +1410,7 @@ impl DiagCtxtInner { "no warnings or errors encountered even though `good_path_delayed_bugs` issued", ), }; + let note2 = "those delayed bugs will now be shown as internal compiler errors"; if bugs.is_empty() { return; @@ -1447,8 +1436,11 @@ impl DiagCtxtInner { if i == 0 { // Put the overall explanation before the `DelayedBug`s, to - // frame them better (e.g. separate warnings from them). - self.emit_diagnostic(Diagnostic::new(Bug, explanation)); + // frame them better (e.g. separate warnings from them). Also, + // make it a note so it doesn't count as an error, because that + // could trigger `-Ztreat-err-as-bug`, which we don't want. + self.emit_diagnostic(Diagnostic::new(Note, note1)); + self.emit_diagnostic(Diagnostic::new(Note, note2)); } let mut bug = @@ -1474,22 +1466,12 @@ impl DiagCtxtInner { fn panic_if_treat_err_as_bug(&self) { if self.treat_err_as_bug() { - match ( - self.err_count + self.lint_err_count, - self.delayed_bug_count(), - self.flags.treat_err_as_bug.map(|c| c.get()).unwrap(), - ) { - (1, 0, 1) => panic!("aborting due to `-Z treat-err-as-bug=1`"), - (0, 1, 1) => panic!("aborting due delayed bug with `-Z treat-err-as-bug=1`"), - (count, delayed_count, val) => { - if delayed_count > 0 { - panic!( - "aborting after {count} errors and {delayed_count} delayed bugs due to `-Z treat-err-as-bug={val}`", - ) - } else { - panic!("aborting after {count} errors due to `-Z treat-err-as-bug={val}`") - } - } + let n = self.flags.treat_err_as_bug.map(|c| c.get()).unwrap(); + assert_eq!(n, self.err_count + self.lint_err_count); + if n == 1 { + panic!("aborting due to `-Z treat-err-as-bug=1`"); + } else { + panic!("aborting after {n} errors due to `-Z treat-err-as-bug={n}`"); } } } diff --git a/tests/ui/impl-trait/equality-in-canonical-query.clone.stderr b/tests/ui/impl-trait/equality-in-canonical-query.clone.stderr index 046d35e4e4acf..1011fc4163bca 100644 --- a/tests/ui/impl-trait/equality-in-canonical-query.clone.stderr +++ b/tests/ui/impl-trait/equality-in-canonical-query.clone.stderr @@ -1,4 +1,6 @@ -error: internal compiler error: no errors encountered even though `span_delayed_bug` issued +note: no errors encountered even though `span_delayed_bug` issued + +note: those delayed bugs will now be shown as internal compiler errors error: internal compiler error: {OpaqueTypeKey { def_id: DefId(rpit::{opaque#0}), args: [] }: OpaqueTypeDecl { hidden_type: OpaqueHiddenType { span: no-location (#0), ty: Alias(Opaque, AliasTy { args: [], def_id: DefId(foo::{opaque#0}) }) } }} | @@ -6,24 +8,18 @@ error: internal compiler error: {OpaqueTypeKey { def_id: DefId(rpit::{opaque#0}) error: internal compiler error: error performing ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing }, value: ProvePredicate { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [FnDef(DefId(rpit), []), ()], def_id: DefId(ops::function::FnOnce::Output) }, Term::Ty(Alias(Opaque, AliasTy { args: [], def_id: DefId(foo::{opaque#0}) }))), bound_vars: [] } } } - --> $DIR/equality-in-canonical-query.rs:19:5 + --> $DIR/equality-in-canonical-query.rs:21:5 | LL | same_output(foo, rpit); | ^^^^^^^^^^^^^^^^^^^^^^ | - --> $DIR/equality-in-canonical-query.rs:19:5 + --> $DIR/equality-in-canonical-query.rs:21:5 | LL | same_output(foo, rpit); | ^^^^^^^^^^^^^^^^^^^^^^ - - - - - - query stack during panic: end of query stack -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors diff --git a/tests/ui/impl-trait/equality-in-canonical-query.rs b/tests/ui/impl-trait/equality-in-canonical-query.rs index 672b1eeeab69f..31ab94f624e5e 100644 --- a/tests/ui/impl-trait/equality-in-canonical-query.rs +++ b/tests/ui/impl-trait/equality-in-canonical-query.rs @@ -1,11 +1,13 @@ // issue: #116877 // revisions: sized clone //[sized] check-pass - //[clone] known-bug: #108498 //[clone] failure-status: 101 //[clone] normalize-stderr-test: "DefId\(.*?\]::" -> "DefId(" -//[clone] normalize-stderr-test: "(?m)note: .*$" -> "" +//[clone] normalize-stderr-test: "(?m)note: we would appreciate a bug report.*\n\n" -> "" +//[clone] normalize-stderr-test: "(?m)note: rustc.*running on.*\n\n" -> "" +//[clone] normalize-stderr-test: "(?m)note: compiler flags.*\n\n" -> "" +//[clone] normalize-stderr-test: "(?m)note: delayed at.*$" -> "" //[clone] normalize-stderr-test: "(?m)^ *\d+: .*\n" -> "" //[clone] normalize-stderr-test: "(?m)^ *at .*\n" -> "" diff --git a/tests/ui/mir/lint/storage-live.stderr b/tests/ui/mir/lint/storage-live.stderr index 02156dd858db2..2eb8d8e700010 100644 --- a/tests/ui/mir/lint/storage-live.stderr +++ b/tests/ui/mir/lint/storage-live.stderr @@ -2,6 +2,12 @@ error: internal compiler error: broken MIR in Item(DefId(0:8 ~ storage_live[HASH StorageLive(_1) which already has storage here --> $DIR/storage-live.rs:22:13 | +LL | StorageLive(a); + | ^^^^^^^^^^^^^^ + | +note: delayed at compiler/rustc_mir_transform/src/lint.rs:97:26 - disabled backtrace + --> $DIR/storage-live.rs:22:13 + | LL | StorageLive(a); | ^^^^^^^^^^^^^^ @@ -9,6 +15,4 @@ aborting due to `-Z treat-err-as-bug=1` error: the compiler unexpectedly panicked. this is a bug. query stack during panic: -#0 [mir_const] preparing `multiple_storage` for borrow checking -#1 [mir_promoted] promoting constants in MIR for `multiple_storage` end of query stack diff --git a/tests/ui/mir/lint/storage-return.rs b/tests/ui/mir/lint/storage-return.rs index a2f63b449b4d5..7f5700fc897a8 100644 --- a/tests/ui/mir/lint/storage-return.rs +++ b/tests/ui/mir/lint/storage-return.rs @@ -1,4 +1,4 @@ -// compile-flags: -Zlint-mir -Ztreat-err-as-bug +// compile-flags: -Zlint-mir -Ztreat-err-as-bug -Zeagerly-emit-delayed-bugs // failure-status: 101 // dont-check-compiler-stderr // error-pattern: has storage when returning diff --git a/tests/ui/treat-err-as-bug/span_delayed_bug.rs b/tests/ui/treat-err-as-bug/span_delayed_bug.rs index dda35b9b92a6d..8b9526bf3f966 100644 --- a/tests/ui/treat-err-as-bug/span_delayed_bug.rs +++ b/tests/ui/treat-err-as-bug/span_delayed_bug.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztreat-err-as-bug +// compile-flags: -Ztreat-err-as-bug -Zeagerly-emit-delayed-bugs // failure-status: 101 // error-pattern: aborting due to `-Z treat-err-as-bug=1` // error-pattern: [trigger_span_delayed_bug] triggering a span delayed bug for testing incremental diff --git a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr index d4e2f95353381..d92bafce142c2 100644 --- a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr +++ b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr @@ -1,4 +1,6 @@ -error: internal compiler error: no errors encountered even though `span_delayed_bug` issued +note: no errors encountered even though `span_delayed_bug` issued + +note: those delayed bugs will now be shown as internal compiler errors error: internal compiler error: {OpaqueTypeKey { def_id: DefId(get_rpit::{opaque#0}), args: [] }: OpaqueTypeDecl { hidden_type: OpaqueHiddenType { span: no-location (#0), ty: Alias(Opaque, AliasTy { args: [], def_id: DefId(Opaque::{opaque#0}) }) } }} | @@ -6,24 +8,18 @@ error: internal compiler error: {OpaqueTypeKey { def_id: DefId(get_rpit::{opaque error: internal compiler error: error performing ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing }, value: ProvePredicate { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [FnDef(DefId(get_rpit), []), ()], def_id: DefId(ops::function::FnOnce::Output) }, Term::Ty(Alias(Opaque, AliasTy { args: [], def_id: DefId(Opaque::{opaque#0}) }))), bound_vars: [] } } } - --> $DIR/rpit_tait_equality_in_canonical_query.rs:28:5 + --> $DIR/rpit_tait_equality_in_canonical_query.rs:31:5 | LL | query(get_rpit); | ^^^^^^^^^^^^^^^ | - --> $DIR/rpit_tait_equality_in_canonical_query.rs:28:5 + --> $DIR/rpit_tait_equality_in_canonical_query.rs:31:5 | LL | query(get_rpit); | ^^^^^^^^^^^^^^^ - - - - - - query stack during panic: end of query stack -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors diff --git a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs index 222841f346715..1b02fce2ad9be 100644 --- a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs +++ b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs @@ -12,7 +12,10 @@ //[current] known-bug: #108498 //[current] failure-status: 101 //[current] normalize-stderr-test: "DefId\(.*?\]::" -> "DefId(" -//[current] normalize-stderr-test: "(?m)note: .*$" -> "" +//[current] normalize-stderr-test: "(?m)note: we would appreciate a bug report.*\n\n" -> "" +//[current] normalize-stderr-test: "(?m)note: rustc.*running on.*\n\n" -> "" +//[current] normalize-stderr-test: "(?m)note: compiler flags.*\n\n" -> "" +//[current] normalize-stderr-test: "(?m)note: delayed at.*$" -> "" //[current] normalize-stderr-test: "(?m)^ *\d+: .*\n" -> "" //[current] normalize-stderr-test: "(?m)^ *at .*\n" -> ""