Only assert for unstable expectation ids after conversion (RFC 2383)

This ICE was reported by `@matthiaskrgr`. A big THANK YOU to him. See `rust#94953`
This commit is contained in:
xFrednet 2022-03-29 00:42:41 +02:00
parent 4c09a3345a
commit 7f03681cd9
No known key found for this signature in database
GPG Key ID: FCDCBF29AF64D601
3 changed files with 53 additions and 6 deletions

View File

@ -426,6 +426,13 @@ struct HandlerInner {
future_breakage_diagnostics: Vec<Diagnostic>,
/// The [`unstable_expect_diagnostics`] should be empty when this struct is
/// dropped. However, it can have values if the compilation is stopped early
/// or is only partially executed. To avoid ICEs, like in rust#94953 we only
/// check if [`unstable_expect_diagnostics`] is empty, if the expectation ids
/// have been converted.
check_unstable_expect_diagnostics: bool,
/// Expected [`Diagnostic`]s store a [`LintExpectationId`] as part of
/// the lint level. [`LintExpectationId`]s created early during the compilation
/// (before `HirId`s have been defined) are not stable and can therefore not be
@ -497,10 +504,12 @@ impl Drop for HandlerInner {
);
}
assert!(
self.unstable_expect_diagnostics.is_empty(),
"all diagnostics with unstable expectations should have been converted",
);
if self.check_unstable_expect_diagnostics {
assert!(
self.unstable_expect_diagnostics.is_empty(),
"all diagnostics with unstable expectations should have been converted",
);
}
}
}
@ -574,6 +583,7 @@ impl Handler {
emitted_diagnostics: Default::default(),
stashed_diagnostics: Default::default(),
future_breakage_diagnostics: Vec::new(),
check_unstable_expect_diagnostics: false,
unstable_expect_diagnostics: Vec::new(),
fulfilled_expectations: Default::default(),
}),
@ -988,12 +998,13 @@ impl Handler {
&self,
unstable_to_stable: &FxHashMap<LintExpectationId, LintExpectationId>,
) {
let diags = std::mem::take(&mut self.inner.borrow_mut().unstable_expect_diagnostics);
let mut inner = self.inner.borrow_mut();
let diags = std::mem::take(&mut inner.unstable_expect_diagnostics);
inner.check_unstable_expect_diagnostics = true;
if diags.is_empty() {
return;
}
let mut inner = self.inner.borrow_mut();
for mut diag in diags.into_iter() {
diag.update_unstable_expectation_id(unstable_to_stable);

View File

@ -0,0 +1,16 @@
// This ensures that ICEs like rust#94953 don't happen
// check-pass
// compile-flags: -Z unpretty=expanded
#![feature(lint_reasons)]
// This `expect` will create an expectation with an unstable expectation id
#[expect(while_true)]
fn create_early_lint_pass_expectation() {
// `while_true` is an early lint
while true {}
}
fn main() {
create_early_lint_pass_expectation();
}

View File

@ -0,0 +1,20 @@
#![feature(prelude_import)]
#![no_std]
// This ensures that ICEs like rust#94953 don't happen
// check-pass
// compile-flags: -Z unpretty=expanded
#![feature(lint_reasons)]
#[prelude_import]
use ::std::prelude::rust_2015::*;
#[macro_use]
extern crate std;
// This `expect` will create an expectation with an unstable expectation id
#[expect(while_true)]
fn create_early_lint_pass_expectation() {
// `while_true` is an early lint
while true {}
}
fn main() { create_early_lint_pass_expectation(); }