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.
This commit is contained in:
parent
2319be8e26
commit
f1ac54123f
@ -865,10 +865,6 @@ impl DiagCtxt {
|
|||||||
/// directly).
|
/// directly).
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn delayed_bug(&self, msg: impl Into<DiagnosticMessage>) -> ErrorGuaranteed {
|
pub fn delayed_bug(&self, msg: impl Into<DiagnosticMessage>) -> 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::<ErrorGuaranteed>::new(self, DelayedBug(DelayedBugKind::Normal), msg)
|
DiagnosticBuilder::<ErrorGuaranteed>::new(self, DelayedBug(DelayedBugKind::Normal), msg)
|
||||||
.emit()
|
.emit()
|
||||||
}
|
}
|
||||||
@ -883,10 +879,6 @@ impl DiagCtxt {
|
|||||||
sp: impl Into<MultiSpan>,
|
sp: impl Into<MultiSpan>,
|
||||||
msg: impl Into<DiagnosticMessage>,
|
msg: impl Into<DiagnosticMessage>,
|
||||||
) -> ErrorGuaranteed {
|
) -> 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::<ErrorGuaranteed>::new(self, DelayedBug(DelayedBugKind::Normal), msg)
|
DiagnosticBuilder::<ErrorGuaranteed>::new(self, DelayedBug(DelayedBugKind::Normal), msg)
|
||||||
.with_span(sp)
|
.with_span(sp)
|
||||||
.emit()
|
.emit()
|
||||||
@ -1259,10 +1251,6 @@ impl DiagCtxtInner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn emit_diagnostic(&mut self, mut diagnostic: Diagnostic) -> Option<ErrorGuaranteed> {
|
fn emit_diagnostic(&mut self, mut diagnostic: Diagnostic) -> Option<ErrorGuaranteed> {
|
||||||
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.
|
// 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
|
// 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
|
// 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() {
|
if diagnostic.has_future_breakage() {
|
||||||
// Future breakages aren't emitted if they're Level::Allow,
|
// Future breakages aren't emitted if they're Level::Allow,
|
||||||
// but they still need to be constructed and stashed below,
|
// but they still need to be constructed and stashed below,
|
||||||
@ -1387,20 +1381,14 @@ impl DiagCtxtInner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn treat_err_as_bug(&self) -> bool {
|
fn treat_err_as_bug(&self) -> bool {
|
||||||
self.flags.treat_err_as_bug.is_some_and(|c| {
|
self.flags.treat_err_as_bug.is_some_and(|c| self.err_count + self.lint_err_count >= c.get())
|
||||||
self.err_count + self.lint_err_count + self.delayed_bug_count() >= c.get()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use this one before incrementing `err_count`.
|
// Use this one before incrementing `err_count`.
|
||||||
fn treat_next_err_as_bug(&self) -> bool {
|
fn treat_next_err_as_bug(&self) -> bool {
|
||||||
self.flags.treat_err_as_bug.is_some_and(|c| {
|
self.flags
|
||||||
self.err_count + self.lint_err_count + self.delayed_bug_count() + 1 >= c.get()
|
.treat_err_as_bug
|
||||||
})
|
.is_some_and(|c| self.err_count + self.lint_err_count + 1 >= c.get())
|
||||||
}
|
|
||||||
|
|
||||||
fn delayed_bug_count(&self) -> usize {
|
|
||||||
self.span_delayed_bugs.len() + self.good_path_delayed_bugs.len()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_errors(&self) -> bool {
|
fn has_errors(&self) -> bool {
|
||||||
@ -1412,7 +1400,7 @@ impl DiagCtxtInner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn flush_delayed(&mut self, kind: DelayedBugKind) {
|
fn flush_delayed(&mut self, kind: DelayedBugKind) {
|
||||||
let (bugs, explanation) = match kind {
|
let (bugs, note1) = match kind {
|
||||||
DelayedBugKind::Normal => (
|
DelayedBugKind::Normal => (
|
||||||
std::mem::take(&mut self.span_delayed_bugs),
|
std::mem::take(&mut self.span_delayed_bugs),
|
||||||
"no errors encountered even though `span_delayed_bug` issued",
|
"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",
|
"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() {
|
if bugs.is_empty() {
|
||||||
return;
|
return;
|
||||||
@ -1447,8 +1436,11 @@ impl DiagCtxtInner {
|
|||||||
|
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
// Put the overall explanation before the `DelayedBug`s, to
|
// Put the overall explanation before the `DelayedBug`s, to
|
||||||
// frame them better (e.g. separate warnings from them).
|
// frame them better (e.g. separate warnings from them). Also,
|
||||||
self.emit_diagnostic(Diagnostic::new(Bug, explanation));
|
// 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 =
|
let mut bug =
|
||||||
@ -1474,22 +1466,12 @@ impl DiagCtxtInner {
|
|||||||
|
|
||||||
fn panic_if_treat_err_as_bug(&self) {
|
fn panic_if_treat_err_as_bug(&self) {
|
||||||
if self.treat_err_as_bug() {
|
if self.treat_err_as_bug() {
|
||||||
match (
|
let n = self.flags.treat_err_as_bug.map(|c| c.get()).unwrap();
|
||||||
self.err_count + self.lint_err_count,
|
assert_eq!(n, self.err_count + self.lint_err_count);
|
||||||
self.delayed_bug_count(),
|
if n == 1 {
|
||||||
self.flags.treat_err_as_bug.map(|c| c.get()).unwrap(),
|
panic!("aborting due to `-Z treat-err-as-bug=1`");
|
||||||
) {
|
} else {
|
||||||
(1, 0, 1) => panic!("aborting due to `-Z treat-err-as-bug=1`"),
|
panic!("aborting after {n} errors due to `-Z treat-err-as-bug={n}`");
|
||||||
(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}`")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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}) }) } }}
|
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: [] } } }
|
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);
|
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);
|
LL | same_output(foo, rpit);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
query stack during panic:
|
query stack during panic:
|
||||||
end of query stack
|
end of query stack
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
// issue: #116877
|
// issue: #116877
|
||||||
// revisions: sized clone
|
// revisions: sized clone
|
||||||
//[sized] check-pass
|
//[sized] check-pass
|
||||||
|
|
||||||
//[clone] known-bug: #108498
|
//[clone] known-bug: #108498
|
||||||
//[clone] failure-status: 101
|
//[clone] failure-status: 101
|
||||||
//[clone] normalize-stderr-test: "DefId\(.*?\]::" -> "DefId("
|
//[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)^ *\d+: .*\n" -> ""
|
||||||
//[clone] normalize-stderr-test: "(?m)^ *at .*\n" -> ""
|
//[clone] normalize-stderr-test: "(?m)^ *at .*\n" -> ""
|
||||||
|
|
||||||
|
@ -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
|
StorageLive(_1) which already has storage here
|
||||||
--> $DIR/storage-live.rs:22:13
|
--> $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);
|
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.
|
error: the compiler unexpectedly panicked. this is a bug.
|
||||||
|
|
||||||
query stack during panic:
|
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
|
end of query stack
|
||||||
|
@ -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
|
// failure-status: 101
|
||||||
// dont-check-compiler-stderr
|
// dont-check-compiler-stderr
|
||||||
// error-pattern: has storage when returning
|
// error-pattern: has storage when returning
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// compile-flags: -Ztreat-err-as-bug
|
// compile-flags: -Ztreat-err-as-bug -Zeagerly-emit-delayed-bugs
|
||||||
// failure-status: 101
|
// failure-status: 101
|
||||||
// error-pattern: aborting due to `-Z treat-err-as-bug=1`
|
// 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
|
// error-pattern: [trigger_span_delayed_bug] triggering a span delayed bug for testing incremental
|
||||||
|
@ -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}) }) } }}
|
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: [] } } }
|
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);
|
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);
|
LL | query(get_rpit);
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
query stack during panic:
|
query stack during panic:
|
||||||
end of query stack
|
end of query stack
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
@ -12,7 +12,10 @@
|
|||||||
//[current] known-bug: #108498
|
//[current] known-bug: #108498
|
||||||
//[current] failure-status: 101
|
//[current] failure-status: 101
|
||||||
//[current] normalize-stderr-test: "DefId\(.*?\]::" -> "DefId("
|
//[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)^ *\d+: .*\n" -> ""
|
||||||
//[current] normalize-stderr-test: "(?m)^ *at .*\n" -> ""
|
//[current] normalize-stderr-test: "(?m)^ *at .*\n" -> ""
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user