diff options
| author | Camille GILLOT <gillot.camille@gmail.com> | 2024-08-31 14:32:15 +0000 |
|---|---|---|
| committer | Camille GILLOT <gillot.camille@gmail.com> | 2024-09-06 20:51:06 +0000 |
| commit | 94f8347bae7404d894f4e6dc57fb64e63e8efb73 (patch) | |
| tree | 4357988438f872a6ffa67a654d7a8ad56ca87c73 /compiler/rustc_errors/src | |
| parent | 17b322fa69eed7216dccc9f097eb68237cf62234 (diff) | |
| download | rust-94f8347bae7404d894f4e6dc57fb64e63e8efb73.tar.gz rust-94f8347bae7404d894f4e6dc57fb64e63e8efb73.zip | |
Check AttrId for expectations.
Diffstat (limited to 'compiler/rustc_errors/src')
| -rw-r--r-- | compiler/rustc_errors/src/diagnostic.rs | 24 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/lib.rs | 101 |
2 files changed, 17 insertions, 108 deletions
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 1c39840207c..412a2c17081 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -8,11 +8,11 @@ use std::thread::panicking; use rustc_data_structures::fx::FxIndexMap; use rustc_error_messages::{fluent_value_from_str_list_sep_by_and, FluentValue}; -use rustc_lint_defs::{Applicability, LintExpectationId}; +use rustc_lint_defs::Applicability; use rustc_macros::{Decodable, Encodable}; use rustc_span::source_map::Spanned; use rustc_span::symbol::Symbol; -use rustc_span::{AttrId, Span, DUMMY_SP}; +use rustc_span::{Span, DUMMY_SP}; use tracing::debug; use crate::snippet::Style; @@ -354,26 +354,6 @@ impl DiagInner { } } - pub(crate) fn update_unstable_expectation_id( - &mut self, - unstable_to_stable: &FxIndexMap<AttrId, LintExpectationId>, - ) { - if let Level::Expect(expectation_id) | Level::ForceWarning(Some(expectation_id)) = - &mut self.level - && let LintExpectationId::Unstable { attr_id, lint_index } = *expectation_id - { - // The unstable to stable map only maps the unstable `AttrId` to a stable `HirId` with an attribute index. - // The lint index inside the attribute is manually transferred here. - let Some(stable_id) = unstable_to_stable.get(&attr_id) else { - panic!("{expectation_id:?} must have a matching stable id") - }; - - let mut stable_id = *stable_id; - stable_id.set_lint_index(lint_index); - *expectation_id = stable_id; - } - } - /// Indicates whether this diagnostic should show up in cargo's future breakage report. pub(crate) fn has_future_breakage(&self) -> bool { matches!(self.is_lint, Some(IsLint { has_future_breakage: true, .. })) diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 02ead41fc68..26e3a63c9d6 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -69,7 +69,7 @@ use rustc_macros::{Decodable, Encodable}; pub use rustc_span::fatal_error::{FatalError, FatalErrorMarker}; use rustc_span::source_map::SourceMap; pub use rustc_span::ErrorGuaranteed; -use rustc_span::{AttrId, Loc, Span, DUMMY_SP}; +use rustc_span::{Loc, Span, DUMMY_SP}; pub use snippet::Style; // Used by external projects such as `rust-gpu`. // See https://github.com/rust-lang/rust/pull/115393. @@ -497,28 +497,18 @@ struct DiagCtxtInner { future_breakage_diagnostics: Vec<DiagInner>, - /// The [`Self::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 [`Self::unstable_expect_diagnostics`] is empty, if the expectation ids - /// have been converted. - check_unstable_expect_diagnostics: bool, - - /// Expected [`DiagInner`][struct@diagnostic::DiagInner]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 - /// stored on disk. This buffer stores these diagnostics until the ID has been - /// replaced by a stable [`LintExpectationId`]. The [`DiagInner`][struct@diagnostic::DiagInner]s - /// are submitted for storage and added to the list of fulfilled expectations. - unstable_expect_diagnostics: Vec<DiagInner>, - /// expected diagnostic will have the level `Expect` which additionally /// carries the [`LintExpectationId`] of the expectation that can be /// marked as fulfilled. This is a collection of all [`LintExpectationId`]s /// that have been marked as fulfilled this way. /// /// [RFC-2383]: https://rust-lang.github.io/rfcs/2383-lint-reasons.html - fulfilled_expectations: FxHashSet<LintExpectationId>, + fulfilled_expectations: FxIndexSet<LintExpectationId>, + + /// Whether `fulfilled_expectations` has been stolen. This is used to ICE in case we emit + /// an expectation diagnostic after stealing it, which means that expectation would not be + /// correctly handled. + stolen_fulfilled_expectations: bool, /// The file where the ICE information is stored. This allows delayed_span_bug backtraces to be /// stored along side the main panic backtrace. @@ -605,13 +595,6 @@ impl Drop for DiagCtxtInner { ); } } - - if self.check_unstable_expect_diagnostics { - assert!( - self.unstable_expect_diagnostics.is_empty(), - "all diagnostics with unstable expectations should have been converted", - ); - } } } @@ -740,9 +723,8 @@ impl DiagCtxt { emitted_diagnostics, stashed_diagnostics, future_breakage_diagnostics, - check_unstable_expect_diagnostics, - unstable_expect_diagnostics, fulfilled_expectations, + stolen_fulfilled_expectations: _, ice_file: _, } = inner.deref_mut(); @@ -761,8 +743,6 @@ impl DiagCtxt { *emitted_diagnostics = Default::default(); *stashed_diagnostics = Default::default(); *future_breakage_diagnostics = Default::default(); - *check_unstable_expect_diagnostics = false; - *unstable_expect_diagnostics = Default::default(); *fulfilled_expectations = Default::default(); } @@ -1094,44 +1074,11 @@ impl<'a> DiagCtxtHandle<'a> { inner.emitter.emit_unused_externs(lint_level, unused_externs) } - pub fn update_unstable_expectation_id( - &self, - unstable_to_stable: FxIndexMap<AttrId, LintExpectationId>, - ) { - 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() { - inner.suppressed_expected_diag = true; - for mut diag in diags.into_iter() { - diag.update_unstable_expectation_id(&unstable_to_stable); - - // Here the diagnostic is given back to `emit_diagnostic` where it was first - // intercepted. Now it should be processed as usual, since the unstable expectation - // id is now stable. - inner.emit_diagnostic(diag, self.tainted_with_errors); - } - } - - inner - .stashed_diagnostics - .values_mut() - .for_each(|(diag, _guar)| diag.update_unstable_expectation_id(&unstable_to_stable)); - inner - .future_breakage_diagnostics - .iter_mut() - .for_each(|diag| diag.update_unstable_expectation_id(&unstable_to_stable)); - } - /// This methods steals all [`LintExpectationId`]s that are stored inside /// [`DiagCtxtInner`] and indicate that the linked expectation has been fulfilled. #[must_use] - pub fn steal_fulfilled_expectation_ids(&self) -> FxHashSet<LintExpectationId> { - assert!( - self.inner.borrow().unstable_expect_diagnostics.is_empty(), - "`DiagCtxtInner::unstable_expect_diagnostics` should be empty at this point", - ); + pub fn steal_fulfilled_expectation_ids(&self) -> FxIndexSet<LintExpectationId> { + self.inner.borrow_mut().stolen_fulfilled_expectations = true; std::mem::take(&mut self.inner.borrow_mut().fulfilled_expectations) } @@ -1440,9 +1387,8 @@ impl DiagCtxtInner { 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(), + stolen_fulfilled_expectations: false, ice_file: None, } } @@ -1471,24 +1417,6 @@ impl DiagCtxtInner { mut diagnostic: DiagInner, taint: Option<&Cell<Option<ErrorGuaranteed>>>, ) -> Option<ErrorGuaranteed> { - match diagnostic.level { - Expect(expect_id) | ForceWarning(Some(expect_id)) => { - // 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 a stable one by the `LintLevelsBuilder`. - if let LintExpectationId::Unstable { .. } = expect_id { - // We don't call TRACK_DIAGNOSTIC because we wait for the - // unstable ID to be updated, whereupon the diagnostic will be - // passed into this method again. - self.unstable_expect_diagnostics.push(diagnostic); - return None; - } - // Continue through to the `Expect`/`ForceWarning` case below. - } - _ => {} - } - if diagnostic.has_future_breakage() { // Future breakages aren't emitted if they're `Level::Allow` or // `Level::Expect`, but they still need to be constructed and @@ -1564,9 +1492,10 @@ impl DiagCtxtInner { return None; } Expect(expect_id) | ForceWarning(Some(expect_id)) => { - if let LintExpectationId::Unstable { .. } = expect_id { - unreachable!(); // this case was handled at the top of this function - } + assert!( + !self.stolen_fulfilled_expectations, + "Attempting to emit an expected diagnostic after `check_expectations`.", + ); self.fulfilled_expectations.insert(expect_id); if let Expect(_) = diagnostic.level { // Nothing emitted here for expected lints. |
