From f8c422f332158011c07a5457aab4c73719b8facc Mon Sep 17 00:00:00 2001
From: Ben Kimock <kimockb@gmail.com>
Date: Tue, 7 Jun 2022 17:05:25 -0400
Subject: [PATCH] Iterate in reverse when comparing Stacks

---
 src/stacked_borrows.rs | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/src/stacked_borrows.rs b/src/stacked_borrows.rs
index 0d671ec653..0a94308171 100644
--- a/src/stacked_borrows.rs
+++ b/src/stacked_borrows.rs
@@ -79,7 +79,7 @@ impl fmt::Debug for Item {
 }
 
 /// Extra per-location state.
-#[derive(Clone, Debug, PartialEq, Eq)]
+#[derive(Clone, Debug, Eq)]
 pub struct Stack {
     /// Used *mostly* as a stack; never empty.
     /// Invariants:
@@ -88,6 +88,18 @@ pub struct Stack {
     borrows: Vec<Item>,
 }
 
+/// This implementation is primarily used when attempting to merge borrow stacks for adjacent
+/// bytes. For adjacent stacks, when the stacks differ at all, they tend to differ either in
+/// length or at the end of the borrows array. Iterating in reverse returns faster for `Stack`s
+/// that are not equal.
+impl PartialEq for Stack {
+    fn eq(&self, other: &Self) -> bool {
+        let Stack { borrows: lhs } = self;
+        let Stack { borrows: rhs } = other;
+        lhs.len() == rhs.len() && lhs.iter().rev().zip(rhs.iter().rev()).all(|(l, r)| l == r)
+    }
+}
+
 /// Extra per-allocation state.
 #[derive(Clone, Debug)]
 pub struct Stacks {