Skip to content

Commit 7f03681

Browse files
committed
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`
1 parent 4c09a33 commit 7f03681

File tree

3 files changed

+53
-6
lines changed

3 files changed

+53
-6
lines changed

compiler/rustc_errors/src/lib.rs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,13 @@ struct HandlerInner {
426426

427427
future_breakage_diagnostics: Vec<Diagnostic>,
428428

429+
/// The [`unstable_expect_diagnostics`] should be empty when this struct is
430+
/// dropped. However, it can have values if the compilation is stopped early
431+
/// or is only partially executed. To avoid ICEs, like in rust#94953 we only
432+
/// check if [`unstable_expect_diagnostics`] is empty, if the expectation ids
433+
/// have been converted.
434+
check_unstable_expect_diagnostics: bool,
435+
429436
/// Expected [`Diagnostic`]s store a [`LintExpectationId`] as part of
430437
/// the lint level. [`LintExpectationId`]s created early during the compilation
431438
/// (before `HirId`s have been defined) are not stable and can therefore not be
@@ -497,10 +504,12 @@ impl Drop for HandlerInner {
497504
);
498505
}
499506

500-
assert!(
501-
self.unstable_expect_diagnostics.is_empty(),
502-
"all diagnostics with unstable expectations should have been converted",
503-
);
507+
if self.check_unstable_expect_diagnostics {
508+
assert!(
509+
self.unstable_expect_diagnostics.is_empty(),
510+
"all diagnostics with unstable expectations should have been converted",
511+
);
512+
}
504513
}
505514
}
506515

@@ -574,6 +583,7 @@ impl Handler {
574583
emitted_diagnostics: Default::default(),
575584
stashed_diagnostics: Default::default(),
576585
future_breakage_diagnostics: Vec::new(),
586+
check_unstable_expect_diagnostics: false,
577587
unstable_expect_diagnostics: Vec::new(),
578588
fulfilled_expectations: Default::default(),
579589
}),
@@ -988,12 +998,13 @@ impl Handler {
988998
&self,
989999
unstable_to_stable: &FxHashMap<LintExpectationId, LintExpectationId>,
9901000
) {
991-
let diags = std::mem::take(&mut self.inner.borrow_mut().unstable_expect_diagnostics);
1001+
let mut inner = self.inner.borrow_mut();
1002+
let diags = std::mem::take(&mut inner.unstable_expect_diagnostics);
1003+
inner.check_unstable_expect_diagnostics = true;
9921004
if diags.is_empty() {
9931005
return;
9941006
}
9951007

996-
let mut inner = self.inner.borrow_mut();
9971008
for mut diag in diags.into_iter() {
9981009
diag.update_unstable_expectation_id(unstable_to_stable);
9991010

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// This ensures that ICEs like rust#94953 don't happen
2+
// check-pass
3+
// compile-flags: -Z unpretty=expanded
4+
5+
#![feature(lint_reasons)]
6+
7+
// This `expect` will create an expectation with an unstable expectation id
8+
#[expect(while_true)]
9+
fn create_early_lint_pass_expectation() {
10+
// `while_true` is an early lint
11+
while true {}
12+
}
13+
14+
fn main() {
15+
create_early_lint_pass_expectation();
16+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#![feature(prelude_import)]
2+
#![no_std]
3+
// This ensures that ICEs like rust#94953 don't happen
4+
// check-pass
5+
// compile-flags: -Z unpretty=expanded
6+
7+
#![feature(lint_reasons)]
8+
#[prelude_import]
9+
use ::std::prelude::rust_2015::*;
10+
#[macro_use]
11+
extern crate std;
12+
13+
// This `expect` will create an expectation with an unstable expectation id
14+
#[expect(while_true)]
15+
fn create_early_lint_pass_expectation() {
16+
// `while_true` is an early lint
17+
while true {}
18+
}
19+
20+
fn main() { create_early_lint_pass_expectation(); }

0 commit comments

Comments
 (0)