about summary refs log tree commit diff
path: root/compiler/rustc_data_structures/src
diff options
context:
space:
mode:
authorNicholas Nethercote <n.nethercote@gmail.com>2022-06-02 17:51:39 +1000
committerNicholas Nethercote <n.nethercote@gmail.com>2022-06-06 08:47:49 +1000
commit32741d5d1645a41acd16addc9612b1253e101458 (patch)
tree9ed55442a347a9563f26c9b716d67736ccc6d661 /compiler/rustc_data_structures/src
parent281229a6d392c192d44d9de0d98675303b3fa271 (diff)
downloadrust-32741d5d1645a41acd16addc9612b1253e101458.tar.gz
rust-32741d5d1645a41acd16addc9612b1253e101458.zip
Split `process_obligation` in two.
Because it really has two halves:
- A read-only part that checks if further work is needed.
- The further work part, which is much less hot.

This makes things a bit clearer and nicer.
Diffstat (limited to 'compiler/rustc_data_structures/src')
-rw-r--r--compiler/rustc_data_structures/src/obligation_forest/mod.rs15
-rw-r--r--compiler/rustc_data_structures/src/obligation_forest/tests.rs4
2 files changed, 14 insertions, 5 deletions
diff --git a/compiler/rustc_data_structures/src/obligation_forest/mod.rs b/compiler/rustc_data_structures/src/obligation_forest/mod.rs
index 60f8f37b226..07a96dd7dbb 100644
--- a/compiler/rustc_data_structures/src/obligation_forest/mod.rs
+++ b/compiler/rustc_data_structures/src/obligation_forest/mod.rs
@@ -96,6 +96,8 @@ pub trait ObligationProcessor {
     type Obligation: ForestObligation;
     type Error: Debug;
 
+    fn needs_process_obligation(&self, obligation: &Self::Obligation) -> bool;
+
     fn process_obligation(
         &mut self,
         obligation: &mut Self::Obligation,
@@ -143,7 +145,7 @@ pub struct ObligationForest<O: ForestObligation> {
 
     /// A cache of the nodes in `nodes`, indexed by predicate. Unfortunately,
     /// its contents are not guaranteed to match those of `nodes`. See the
-    /// comments in [`Self::process_obligation` for details.
+    /// comments in `Self::process_obligation` for details.
     active_cache: FxHashMap<O::CacheKey, usize>,
 
     /// A vector reused in [Self::compress()] and [Self::find_cycles_from_node()],
@@ -417,15 +419,18 @@ impl<O: ForestObligation> ObligationForest<O> {
             // nodes. Therefore we use a `while` loop.
             let mut index = 0;
             while let Some(node) = self.nodes.get_mut(index) {
+                if node.state.get() != NodeState::Pending
+                    || !processor.needs_process_obligation(&node.obligation)
+                {
+                    index += 1;
+                    continue;
+                }
+
                 // `processor.process_obligation` can modify the predicate within
                 // `node.obligation`, and that predicate is the key used for
                 // `self.active_cache`. This means that `self.active_cache` can get
                 // out of sync with `nodes`. It's not very common, but it does
                 // happen, and code in `compress` has to allow for it.
-                if node.state.get() != NodeState::Pending {
-                    index += 1;
-                    continue;
-                }
 
                 match processor.process_obligation(&mut node.obligation) {
                     ProcessResult::Unchanged => {
diff --git a/compiler/rustc_data_structures/src/obligation_forest/tests.rs b/compiler/rustc_data_structures/src/obligation_forest/tests.rs
index 5ecc75736a3..e2991aae174 100644
--- a/compiler/rustc_data_structures/src/obligation_forest/tests.rs
+++ b/compiler/rustc_data_structures/src/obligation_forest/tests.rs
@@ -65,6 +65,10 @@ where
     type Obligation = O;
     type Error = E;
 
+    fn needs_process_obligation(&self, _obligation: &Self::Obligation) -> bool {
+        true
+    }
+
     fn process_obligation(
         &mut self,
         obligation: &mut Self::Obligation,