From 5b3bd95c3cb633eac46c8c75d9b4db145a1e39a3 Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Fri, 17 Oct 2025 12:10:51 +0000 Subject: [PATCH] btree: cleanup difference, intersection, is_subset --- library/alloc/src/collections/btree/set.rs | 183 ++++++++---------- library/alloctests/Cargo.toml | 2 +- tests/run-make/alloc-no-oom-handling/rmake.rs | 2 +- tests/run-make/alloc-no-rc/rmake.rs | 2 +- tests/run-make/alloc-no-sync/rmake.rs | 2 +- .../rmake.rs | 6 +- tests/run-make/panic-abort-eh_frame/rmake.rs | 2 +- 7 files changed, 92 insertions(+), 107 deletions(-) diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index 6e6996bcbd69b..46268f94ce6aa 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -427,39 +427,35 @@ impl BTreeSet { where T: Ord, { - let (self_min, self_max) = - if let (Some(self_min), Some(self_max)) = (self.first(), self.last()) { - (self_min, self_max) - } else { - return Difference { inner: DifferenceInner::Iterate(self.iter()) }; - }; - let (other_min, other_max) = - if let (Some(other_min), Some(other_max)) = (other.first(), other.last()) { - (other_min, other_max) - } else { - return Difference { inner: DifferenceInner::Iterate(self.iter()) }; - }; - Difference { - inner: match (self_min.cmp(other_max), self_max.cmp(other_min)) { - (Greater, _) | (_, Less) => DifferenceInner::Iterate(self.iter()), - (Equal, _) => { - let mut self_iter = self.iter(); - self_iter.next(); - DifferenceInner::Iterate(self_iter) - } - (_, Equal) => { - let mut self_iter = self.iter(); - self_iter.next_back(); - DifferenceInner::Iterate(self_iter) - } - _ if self.len() <= other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF => { - DifferenceInner::Search { self_iter: self.iter(), other_set: other } - } - _ => DifferenceInner::Stitch { - self_iter: self.iter(), - other_iter: other.iter().peekable(), + if let Some(self_min) = self.first() + && let Some(self_max) = self.last() + && let Some(other_min) = other.first() + && let Some(other_max) = other.last() + { + Difference { + inner: match (self_min.cmp(other_max), self_max.cmp(other_min)) { + (Greater, _) | (_, Less) => DifferenceInner::Iterate(self.iter()), + (Equal, _) => { + let mut self_iter = self.iter(); + self_iter.next(); + DifferenceInner::Iterate(self_iter) + } + (_, Equal) => { + let mut self_iter = self.iter(); + self_iter.next_back(); + DifferenceInner::Iterate(self_iter) + } + _ if self.len() <= other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF => { + DifferenceInner::Search { self_iter: self.iter(), other_set: other } + } + _ => DifferenceInner::Stitch { + self_iter: self.iter(), + other_iter: other.iter().peekable(), + }, }, - }, + } + } else { + Difference { inner: DifferenceInner::Iterate(self.iter()) } } } @@ -519,31 +515,27 @@ impl BTreeSet { where T: Ord, { - let (self_min, self_max) = - if let (Some(self_min), Some(self_max)) = (self.first(), self.last()) { - (self_min, self_max) - } else { - return Intersection { inner: IntersectionInner::Answer(None) }; - }; - let (other_min, other_max) = - if let (Some(other_min), Some(other_max)) = (other.first(), other.last()) { - (other_min, other_max) - } else { - return Intersection { inner: IntersectionInner::Answer(None) }; - }; - Intersection { - inner: match (self_min.cmp(other_max), self_max.cmp(other_min)) { - (Greater, _) | (_, Less) => IntersectionInner::Answer(None), - (Equal, _) => IntersectionInner::Answer(Some(self_min)), - (_, Equal) => IntersectionInner::Answer(Some(self_max)), - _ if self.len() <= other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF => { - IntersectionInner::Search { small_iter: self.iter(), large_set: other } - } - _ if other.len() <= self.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF => { - IntersectionInner::Search { small_iter: other.iter(), large_set: self } - } - _ => IntersectionInner::Stitch { a: self.iter(), b: other.iter() }, - }, + if let Some(self_min) = self.first() + && let Some(self_max) = self.last() + && let Some(other_min) = other.first() + && let Some(other_max) = other.last() + { + Intersection { + inner: match (self_min.cmp(other_max), self_max.cmp(other_min)) { + (Greater, _) | (_, Less) => IntersectionInner::Answer(None), + (Equal, _) => IntersectionInner::Answer(Some(self_min)), + (_, Equal) => IntersectionInner::Answer(Some(self_max)), + _ if self.len() <= other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF => { + IntersectionInner::Search { small_iter: self.iter(), large_set: other } + } + _ if other.len() <= self.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF => { + IntersectionInner::Search { small_iter: other.iter(), large_set: self } + } + _ => IntersectionInner::Stitch { a: self.iter(), b: other.iter() }, + }, + } + } else { + Intersection { inner: IntersectionInner::Answer(None) } } } @@ -696,53 +688,46 @@ impl BTreeSet { if self.len() > other.len() { return false; } - let (self_min, self_max) = - if let (Some(self_min), Some(self_max)) = (self.first(), self.last()) { - (self_min, self_max) - } else { - return true; // self is empty + if let Some(self_min) = self.first() + && let Some(self_max) = self.last() + && let Some(other_min) = other.first() + && let Some(other_max) = other.last() + { + let mut self_iter = self.iter(); + match self_min.cmp(other_min) { + Less => return false, + Equal => self_iter.next(), + Greater => None, }; - let (other_min, other_max) = - if let (Some(other_min), Some(other_max)) = (other.first(), other.last()) { - (other_min, other_max) - } else { - return false; // other is empty + match self_max.cmp(other_max) { + Greater => return false, + Equal => self_iter.next_back(), + Less => None, }; - let mut self_iter = self.iter(); - match self_min.cmp(other_min) { - Less => return false, - Equal => { - self_iter.next(); - } - Greater => (), - } - match self_max.cmp(other_max) { - Greater => return false, - Equal => { - self_iter.next_back(); - } - Less => (), - } - if self_iter.len() <= other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF { - for next in self_iter { - if !other.contains(next) { - return false; - } + if self_iter.len() <= other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF { + self_iter.all(|e| other.contains(e)) + } else { + let mut other_iter = other.iter(); + other_iter.next(); + other_iter.next_back(); + self_iter.all(|self1| { + while let Some(other1) = other_iter.next() { + match other1.cmp(self1) { + // skip over elements that are smaller + // happens up to `ITER_PERFORMANCE_TIPPING_SIZE_DIFF * self.len() - 1` times + Less => continue, + // happens `self.len()` times + Equal => return true, + // happens only once + Greater => return false, + } + } + false + }) } } else { - let mut other_iter = other.iter(); - other_iter.next(); - other_iter.next_back(); - let mut self_next = self_iter.next(); - while let Some(self1) = self_next { - match other_iter.next().map_or(Less, |other1| self1.cmp(other1)) { - Less => return false, - Equal => self_next = self_iter.next(), - Greater => (), - } - } + self.is_empty() } - true } /// Returns `true` if the set is a superset of another, diff --git a/library/alloctests/Cargo.toml b/library/alloctests/Cargo.toml index 07c45d1b82484..3b522bf80a217 100644 --- a/library/alloctests/Cargo.toml +++ b/library/alloctests/Cargo.toml @@ -6,7 +6,7 @@ repository = "https://github.com/rust-lang/rust.git" description = "Tests for the Rust Allocation Library" autotests = false autobenches = false -edition = "2021" +edition = "2024" [lib] path = "lib.rs" diff --git a/tests/run-make/alloc-no-oom-handling/rmake.rs b/tests/run-make/alloc-no-oom-handling/rmake.rs index 89a6636d9a0cc..94002eca5736f 100644 --- a/tests/run-make/alloc-no-oom-handling/rmake.rs +++ b/tests/run-make/alloc-no-oom-handling/rmake.rs @@ -6,7 +6,7 @@ use run_make_support::{rustc, source_root}; fn main() { rustc() - .edition("2021") + .edition("2024") .arg("-Dwarnings") .crate_type("rlib") .input(source_root().join("library/alloc/src/lib.rs")) diff --git a/tests/run-make/alloc-no-rc/rmake.rs b/tests/run-make/alloc-no-rc/rmake.rs index 12171c2148f1d..8d8cd4990bc65 100644 --- a/tests/run-make/alloc-no-rc/rmake.rs +++ b/tests/run-make/alloc-no-rc/rmake.rs @@ -6,7 +6,7 @@ use run_make_support::{rustc, source_root}; fn main() { rustc() - .edition("2021") + .edition("2024") .arg("-Dwarnings") .crate_type("rlib") .input(source_root().join("library/alloc/src/lib.rs")) diff --git a/tests/run-make/alloc-no-sync/rmake.rs b/tests/run-make/alloc-no-sync/rmake.rs index 29f204f30673e..a096d3941d466 100644 --- a/tests/run-make/alloc-no-sync/rmake.rs +++ b/tests/run-make/alloc-no-sync/rmake.rs @@ -6,7 +6,7 @@ use run_make_support::{rustc, source_root}; fn main() { rustc() - .edition("2021") + .edition("2024") .arg("-Dwarnings") .crate_type("rlib") .input(source_root().join("library/alloc/src/lib.rs")) diff --git a/tests/run-make/llvm-location-discriminator-limit-dummy-span/rmake.rs b/tests/run-make/llvm-location-discriminator-limit-dummy-span/rmake.rs index d28c8463016cb..00ae400f71d20 100644 --- a/tests/run-make/llvm-location-discriminator-limit-dummy-span/rmake.rs +++ b/tests/run-make/llvm-location-discriminator-limit-dummy-span/rmake.rs @@ -49,21 +49,21 @@ fn main() { rustc() .input("proc.rs") .crate_type("proc-macro") - .edition("2021") + .edition("2024") .arg("-Cdebuginfo=line-tables-only") .run(); rustc() .extern_("proc", dynamic_lib_name("proc")) .input("other.rs") .crate_type("rlib") - .edition("2021") + .edition("2024") .opt_level("3") .arg("-Cdebuginfo=line-tables-only") .run(); rustc() .extern_("other", rust_lib_name("other")) .input("main.rs") - .edition("2021") + .edition("2024") .opt_level("3") .arg("-Cdebuginfo=line-tables-only") .arg("-Clto=fat") diff --git a/tests/run-make/panic-abort-eh_frame/rmake.rs b/tests/run-make/panic-abort-eh_frame/rmake.rs index 2eccde627955c..5c859a7482674 100644 --- a/tests/run-make/panic-abort-eh_frame/rmake.rs +++ b/tests/run-make/panic-abort-eh_frame/rmake.rs @@ -19,7 +19,7 @@ fn main() { .crate_type("lib") .emit("obj=foo.o") .panic("abort") - .edition("2021") + .edition("2024") .arg("-Zvalidate-mir") .arg("-Cforce-unwind-tables=no") .run();