about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCamille GILLOT <gillot.camille@gmail.com>2023-05-18 08:50:56 +0000
committerCamille GILLOT <gillot.camille@gmail.com>2023-05-18 08:52:54 +0000
commitf52db3ecaa47167137cdbe48bd7d56bb5f9c9d3c (patch)
tree48d887b12b3b771850f5536fa4ec00055655387f
parent6c64870fa67f0227f40f6adc25a6944e95c2959f (diff)
downloadrust-f52db3ecaa47167137cdbe48bd7d56bb5f9c9d3c.tar.gz
rust-f52db3ecaa47167137cdbe48bd7d56bb5f9c9d3c.zip
Stop confusing specification levels when computing expectations.
-rw-r--r--compiler/rustc_lint/src/levels.rs10
-rw-r--r--tests/ui/lint/rfc-2383-lint-reason/root-attribute-confusion.rs7
2 files changed, 14 insertions, 3 deletions
diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs
index b92ed11f38a..8376835f52c 100644
--- a/compiler/rustc_lint/src/levels.rs
+++ b/compiler/rustc_lint/src/levels.rs
@@ -242,7 +242,9 @@ impl LintLevelsProvider for LintLevelQueryMap<'_> {
 
 struct QueryMapExpectationsWrapper<'tcx> {
     tcx: TyCtxt<'tcx>,
+    /// HirId of the currently investigated element.
     cur: HirId,
+    /// Level map for `cur`.
     specs: ShallowLintLevelMap,
     expectations: Vec<(LintExpectationId, LintExpectation)>,
     unstable_to_stable_ids: FxHashMap<LintExpectationId, LintExpectationId>,
@@ -255,11 +257,11 @@ impl LintLevelsProvider for QueryMapExpectationsWrapper<'_> {
         self.specs.specs.get(&self.cur.local_id).unwrap_or(&self.empty)
     }
     fn insert(&mut self, id: LintId, lvl: LevelAndSource) {
-        let specs = self.specs.specs.get_mut_or_insert_default(self.cur.local_id);
-        specs.clear();
-        specs.insert(id, lvl);
+        self.specs.specs.get_mut_or_insert_default(self.cur.local_id).insert(id, lvl);
     }
     fn get_lint_level(&self, lint: &'static Lint, _: &Session) -> LevelAndSource {
+        // We cannot use `tcx.lint_level_at_node` because we want to know in which order the
+        // attributes have been inserted, in particular whether an `expect` follows a `forbid`.
         self.specs.lint_level_id_at_node(self.tcx, LintId::of(lint), self.cur)
     }
     fn push_expectation(&mut self, id: LintExpectationId, expectation: LintExpectation) {
@@ -355,7 +357,9 @@ impl<'tcx> Visitor<'tcx> for LintLevelsBuilder<'_, LintLevelQueryMap<'tcx>> {
 
 impl<'tcx> LintLevelsBuilder<'_, QueryMapExpectationsWrapper<'tcx>> {
     fn add_id(&mut self, hir_id: HirId) {
+        // Change both the `HirId` and the associated specs.
         self.provider.cur = hir_id;
+        self.provider.specs.specs.clear();
         self.add(self.provider.tcx.hir().attrs(hir_id), hir_id == hir::CRATE_HIR_ID, Some(hir_id));
     }
 }
diff --git a/tests/ui/lint/rfc-2383-lint-reason/root-attribute-confusion.rs b/tests/ui/lint/rfc-2383-lint-reason/root-attribute-confusion.rs
new file mode 100644
index 00000000000..0cade7fef02
--- /dev/null
+++ b/tests/ui/lint/rfc-2383-lint-reason/root-attribute-confusion.rs
@@ -0,0 +1,7 @@
+// check-pass
+// compile-flags: -Dunused_attributes
+
+#![deny(unused_crate_dependencies)]
+#![feature(lint_reasons)]
+
+fn main() {}