From ad526d831e295facc198610a27350076aa5aa438 Mon Sep 17 00:00:00 2001
From: yukang <moorekang@gmail.com>
Date: Tue, 30 Jan 2024 12:42:29 +0800
Subject: [PATCH] add missing potential_query_instability for keys and values
 in hashmap

---
 .../src/coverageinfo/mapgen.rs                |  1 +
 .../src/assert_module_sources.rs              |  1 +
 compiler/rustc_codegen_ssa/src/back/link.rs   |  1 +
 compiler/rustc_hir_typeck/src/expr.rs         |  1 +
 compiler/rustc_lint/src/context.rs            | 14 +++++-----
 .../rustc_lint/src/context/diagnostics.rs     |  1 +
 .../src/traits/auto_trait.rs                  |  1 +
 library/std/src/collections/hash/map.rs       |  3 +++
 .../internal-lints/query_stability.rs         | 13 ++++++++++
 .../internal-lints/query_stability.stderr     | 26 ++++++++++++++++++-
 10 files changed, 55 insertions(+), 7 deletions(-)

diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
index 6116a6fd222b3..b1ceb1d4dd56d 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
@@ -403,6 +403,7 @@ fn codegenned_and_inlined_items(tcx: TyCtxt<'_>) -> DefIdSet {
     let mut result = items.clone();
 
     for cgu in cgus {
+        #[allow(rustc::potential_query_instability)]
         for item in cgu.items().keys() {
             if let mir::mono::MonoItem::Fn(ref instance) = item {
                 let did = instance.def_id();
diff --git a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs
index a1daadce958eb..61fe6b261c6a9 100644
--- a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs
+++ b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs
@@ -267,6 +267,7 @@ impl CguReuseTracker {
 
     fn check_expected_reuse(&self, sess: &Session) {
         if let Some(ref data) = self.data {
+            #[allow(rustc::potential_query_instability)]
             let mut keys = data.expected_reuse.keys().collect::<Vec<_>>();
             keys.sort_unstable();
             for cgu_name in keys {
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index f098fc9cb5970..b29f71bfb9553 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -682,6 +682,7 @@ fn link_dwarf_object<'a>(
         }
 
         // Input rlibs contain .o/.dwo files from dependencies.
+        #[allow(rustc::potential_query_instability)]
         let input_rlibs = cg_results
             .crate_info
             .used_crate_source
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index d00ae4db300be..7f13814b082bc 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -1950,6 +1950,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ) {
         let len = remaining_fields.len();
 
+        #[allow(rustc::potential_query_instability)]
         let mut displayable_field_names: Vec<&str> =
             remaining_fields.keys().map(|ident| ident.as_str()).collect();
         // sorting &str primitives here, sort_unstable is ok
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index 04201a38c35ea..1c480ec8f53b1 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -326,11 +326,9 @@ impl LintStore {
 
     /// True if this symbol represents a lint group name.
     pub fn is_lint_group(&self, lint_name: Symbol) -> bool {
-        debug!(
-            "is_lint_group(lint_name={:?}, lint_groups={:?})",
-            lint_name,
-            self.lint_groups.keys().collect::<Vec<_>>()
-        );
+        #[allow(rustc::potential_query_instability)]
+        let lint_groups = self.lint_groups.keys().collect::<Vec<_>>();
+        debug!("is_lint_group(lint_name={:?}, lint_groups={:?})", lint_name, lint_groups);
         let lint_name_str = lint_name.as_str();
         self.lint_groups.contains_key(lint_name_str) || {
             let warnings_name_str = crate::WARNINGS.name_lower();
@@ -374,8 +372,12 @@ impl LintStore {
                     None => {
                         // 1. The tool is currently running, so this lint really doesn't exist.
                         // FIXME: should this handle tools that never register a lint, like rustfmt?
-                        debug!("lints={:?}", self.by_name.keys().collect::<Vec<_>>());
+                        #[allow(rustc::potential_query_instability)]
+                        let lints = self.by_name.keys().collect::<Vec<_>>();
+                        debug!("lints={:?}", lints);
                         let tool_prefix = format!("{tool_name}::");
+
+                        #[allow(rustc::potential_query_instability)]
                         return if self.by_name.keys().any(|lint| lint.starts_with(&tool_prefix)) {
                             self.no_lint_suggestion(&complete_name, tool_name.as_str())
                         } else {
diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs
index 312874db3f54e..eb42730f69a4d 100644
--- a/compiler/rustc_lint/src/context/diagnostics.rs
+++ b/compiler/rustc_lint/src/context/diagnostics.rs
@@ -185,6 +185,7 @@ pub(super) fn builtin(
             db.note("see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information");
         }
         BuiltinLintDiagnostics::UnexpectedCfgName((name, name_span), value) => {
+            #[allow(rustc::potential_query_instability)]
             let possibilities: Vec<Symbol> =
                 sess.parse_sess.check_config.expecteds.keys().copied().collect();
             let is_from_cargo = std::env::var_os("CARGO").is_some();
diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
index c43447585746a..0b9fb7b6fbc1d 100644
--- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs
+++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
@@ -513,6 +513,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
         }
 
         while !vid_map.is_empty() {
+            #[allow(rustc::potential_query_instability)]
             let target = *vid_map.keys().next().expect("Keys somehow empty");
             let deps = vid_map.remove(&target).expect("Entry somehow missing");
 
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index fc27b6a67bfcb..0d4c1fa05cc87 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -356,6 +356,7 @@ impl<K, V, S> HashMap<K, V, S> {
     ///
     /// In the current implementation, iterating over keys takes O(capacity) time
     /// instead of O(len) because it internally visits empty buckets too.
+    #[rustc_lint_query_instability]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn keys(&self) -> Keys<'_, K, V> {
         Keys { inner: self.iter() }
@@ -417,6 +418,7 @@ impl<K, V, S> HashMap<K, V, S> {
     ///
     /// In the current implementation, iterating over values takes O(capacity) time
     /// instead of O(len) because it internally visits empty buckets too.
+    #[rustc_lint_query_instability]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn values(&self) -> Values<'_, K, V> {
         Values { inner: self.iter() }
@@ -449,6 +451,7 @@ impl<K, V, S> HashMap<K, V, S> {
     ///
     /// In the current implementation, iterating over values takes O(capacity) time
     /// instead of O(len) because it internally visits empty buckets too.
+    #[rustc_lint_query_instability]
     #[stable(feature = "map_values_mut", since = "1.10.0")]
     pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
         ValuesMut { inner: self.iter_mut() }
diff --git a/tests/ui-fulldeps/internal-lints/query_stability.rs b/tests/ui-fulldeps/internal-lints/query_stability.rs
index 560675b448608..627ffa5cbd0f3 100644
--- a/tests/ui-fulldeps/internal-lints/query_stability.rs
+++ b/tests/ui-fulldeps/internal-lints/query_stability.rs
@@ -21,4 +21,17 @@ fn main() {
 
     for _ in x {}
     //~^ ERROR using `into_iter`
+
+    let x = FxHashMap::<u32, i32>::default();
+    let _ = x.keys();
+    //~^ ERROR using `keys` can result in unstable query results
+
+    let _ = x.values();
+    //~^ ERROR using `values` can result in unstable query results
+
+    let mut x = FxHashMap::<u32, i32>::default();
+    for val in x.values_mut() {
+        //~^ ERROR using `values_mut` can result in unstable query results
+        *val = *val + 10;
+    }
 }
diff --git a/tests/ui-fulldeps/internal-lints/query_stability.stderr b/tests/ui-fulldeps/internal-lints/query_stability.stderr
index ee4ef9982371e..43b156dc20a3c 100644
--- a/tests/ui-fulldeps/internal-lints/query_stability.stderr
+++ b/tests/ui-fulldeps/internal-lints/query_stability.stderr
@@ -35,5 +35,29 @@ LL |     for _ in x {}
    |
    = note: if you believe this case to be fine, allow this lint and add a comment explaining your rationale
 
-error: aborting due to 4 previous errors
+error: using `keys` can result in unstable query results
+  --> $DIR/query_stability.rs:26:15
+   |
+LL |     let _ = x.keys();
+   |               ^^^^
+   |
+   = note: if you believe this case to be fine, allow this lint and add a comment explaining your rationale
+
+error: using `values` can result in unstable query results
+  --> $DIR/query_stability.rs:29:15
+   |
+LL |     let _ = x.values();
+   |               ^^^^^^
+   |
+   = note: if you believe this case to be fine, allow this lint and add a comment explaining your rationale
+
+error: using `values_mut` can result in unstable query results
+  --> $DIR/query_stability.rs:33:18
+   |
+LL |     for val in x.values_mut() {
+   |                  ^^^^^^^^^^
+   |
+   = note: if you believe this case to be fine, allow this lint and add a comment explaining your rationale
+
+error: aborting due to 7 previous errors