diff options
| author | xFrednet <xFrednet@gmail.com> | 2021-11-20 20:45:27 +0100 |
|---|---|---|
| committer | xFrednet <xFrednet@gmail.com> | 2022-03-02 17:46:08 +0100 |
| commit | 33a5945069e2c7bd3ba8a0dd65b74ebdd234ad7c (patch) | |
| tree | 148bd4bf7d42747ed3a2542ca446c429938c4a6c /compiler/rustc_lint | |
| parent | 44cb8fa482abaa567119ceab125498cfeef1171b (diff) | |
| download | rust-33a5945069e2c7bd3ba8a0dd65b74ebdd234ad7c.tar.gz rust-33a5945069e2c7bd3ba8a0dd65b74ebdd234ad7c.zip | |
Make `LintExpectationId` stable between compilation sessions (RFC-2383)
Diffstat (limited to 'compiler/rustc_lint')
| -rw-r--r-- | compiler/rustc_lint/src/early.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/expect.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/levels.rs | 50 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/lib.rs | 2 |
4 files changed, 48 insertions, 9 deletions
diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index 1b2c88867d4..e9b7620bf1d 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -59,7 +59,8 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> { F: FnOnce(&mut Self), { let is_crate_node = id == ast::CRATE_NODE_ID; - let push = self.context.builder.push(attrs, is_crate_node); + let push = self.context.builder.push(attrs, is_crate_node, None); + self.check_id(id); self.enter_attrs(attrs); f(self); diff --git a/compiler/rustc_lint/src/expect.rs b/compiler/rustc_lint/src/expect.rs index a0c8b3501cd..49664322a98 100644 --- a/compiler/rustc_lint/src/expect.rs +++ b/compiler/rustc_lint/src/expect.rs @@ -25,7 +25,7 @@ pub fn check_expectations(tcx: TyCtxt<'_>) { } fn emit_unfulfilled_expectation_lint(tcx: TyCtxt<'_>, expectation: &LintExpectation) { - // FIXME The current implementation doesn't cover cases where the + // FIXME: The current implementation doesn't cover cases where the // `unfulfilled_lint_expectations` is actually expected by another lint // expectation. This can be added here as we have the lint level of this // expectation, and we can also mark the lint expectation it would fulfill diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index a876e35c0a8..417022bd2bf 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -32,17 +32,23 @@ fn lint_levels(tcx: TyCtxt<'_>, (): ()) -> LintLevelMap { builder.levels.id_to_set.reserve(krate.owners.len() + 1); - let push = builder.levels.push(tcx.hir().attrs(hir::CRATE_HIR_ID), true); + let push = + builder.levels.push(tcx.hir().attrs(hir::CRATE_HIR_ID), true, Some(hir::CRATE_HIR_ID)); + builder.levels.register_id(hir::CRATE_HIR_ID); tcx.hir().walk_toplevel_module(&mut builder); builder.levels.pop(push); + builder.levels.update_unstable_expectation_ids(); builder.levels.build_map() } pub struct LintLevelsBuilder<'s> { sess: &'s Session, lint_expectations: FxHashMap<LintExpectationId, LintExpectation>, + /// Each expectation has a stable and an unstable identifier. This map + /// is used to map from unstable to stable [`LintExpectationId`]s. + expectation_id_map: FxHashMap<LintExpectationId, LintExpectationId>, sets: LintLevelSets, id_to_set: FxHashMap<HirId, LintStackIndex>, cur: LintStackIndex, @@ -66,6 +72,7 @@ impl<'s> LintLevelsBuilder<'s> { let mut builder = LintLevelsBuilder { sess, lint_expectations: Default::default(), + expectation_id_map: Default::default(), sets: LintLevelSets::new(), cur: COMMAND_LINE, id_to_set: Default::default(), @@ -226,13 +233,26 @@ impl<'s> LintLevelsBuilder<'s> { /// `#[allow]` /// /// Don't forget to call `pop`! - pub(crate) fn push(&mut self, attrs: &[ast::Attribute], is_crate_node: bool) -> BuilderPush { + pub(crate) fn push( + &mut self, + attrs: &[ast::Attribute], + is_crate_node: bool, + source_hir_id: Option<HirId>, + ) -> BuilderPush { let mut specs = FxHashMap::default(); let sess = self.sess; let bad_attr = |span| struct_span_err!(sess, span, E0452, "malformed lint attribute input"); - for attr in attrs { - let Some(level) = Level::from_symbol(attr.name_or_empty(), attr.id.as_u32()) else { - continue + for (attr_index, attr) in attrs.iter().enumerate() { + let level = match Level::from_symbol(attr.name_or_empty(), || { + LintExpectationId::Unstable(attr.id) + }) { + None => continue, + Some(Level::Expect(unstable_id)) if source_hir_id.is_some() => { + let stable_id = + self.create_stable_id(unstable_id, source_hir_id.unwrap(), attr_index); + Level::Expect(stable_id) + } + Some(lvl) => lvl, }; let Some(mut metas) = attr.meta_item_list() else { @@ -539,6 +559,19 @@ impl<'s> LintLevelsBuilder<'s> { BuilderPush { prev, changed: prev != self.cur } } + fn create_stable_id( + &mut self, + unstable_id: LintExpectationId, + hir_id: HirId, + attr_index: usize, + ) -> LintExpectationId { + let stable_id = LintExpectationId::Stable { hir_id, attr_index }; + + self.expectation_id_map.insert(unstable_id, stable_id); + + stable_id + } + /// Checks if the lint is gated on a feature that is not enabled. fn check_gated_lint(&self, lint_id: LintId, span: Span) { if let Some(feature) = lint_id.lint.feature_gate { @@ -582,6 +615,10 @@ impl<'s> LintLevelsBuilder<'s> { self.id_to_set.insert(id, self.cur); } + fn update_unstable_expectation_ids(&self) { + self.sess.diagnostic().update_unstable_expectation_id(&self.expectation_id_map); + } + pub fn build_map(self) -> LintLevelMap { LintLevelMap { sets: self.sets, @@ -603,7 +640,8 @@ impl LintLevelMapBuilder<'_> { { let is_crate_hir = id == hir::CRATE_HIR_ID; let attrs = self.tcx.hir().attrs(id); - let push = self.levels.push(attrs, is_crate_hir); + let push = self.levels.push(attrs, is_crate_hir, Some(id)); + if push.changed { self.levels.register_id(id); } diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 2dc6e980722..18f229564c2 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -51,8 +51,8 @@ pub mod builtin; mod context; mod early; mod enum_intrinsics_non_enums; -pub mod hidden_unicode_codepoints; mod expect; +pub mod hidden_unicode_codepoints; mod internal; mod late; mod levels; |
