diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fddf5f1..fb3a5c8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,7 +39,7 @@ jobs: bench: test build benchmarks steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} @@ -72,7 +72,7 @@ jobs: target: thumbv6m-none-eabi steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} @@ -85,7 +85,7 @@ jobs: clippy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 - uses: dtolnay/rust-toolchain@beta with: components: clippy @@ -94,7 +94,7 @@ jobs: miri: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 - uses: dtolnay/rust-toolchain@nightly with: components: miri, rust-src @@ -110,7 +110,7 @@ jobs: name: Check MSRV and minimal-versions runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 - uses: dtolnay/rust-toolchain@nightly - uses: dtolnay/rust-toolchain@1.85.0 # MSRV - uses: taiki-e/install-action@v2 diff --git a/Cargo.toml b/Cargo.toml index c3e0edf..087c5d6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "ordermap" edition = "2024" -version = "1.2.0" +version = "1.2.1" documentation = "https://docs.rs/ordermap/" repository = "https://github.com/indexmap-rs/ordermap" license = "Apache-2.0 OR MIT" @@ -14,7 +14,7 @@ rust-version = "1.85" bench = false [dependencies] -indexmap = { version = "2.14.0", default-features = false } +indexmap = { version = "2.14.1", default-features = false } arbitrary = { version = "1.0", optional = true, default-features = false } quickcheck = { version = "1.0", optional = true, default-features = false } @@ -64,13 +64,13 @@ rustdoc-args = ["--cfg", "docsrs"] members = ["test-nostd", "test-serde", "test-sval"] [lints.rust] -private-bounds = "deny" -private-interfaces = "deny" -unnameable-types = "deny" -unreachable-pub = "deny" -unsafe-code = "deny" +private_bounds = "deny" +private_interfaces = "deny" +unnameable_types = "deny" +unreachable_pub = "deny" +unsafe_code = "deny" -rust-2018-idioms = "warn" +rust_2018_idioms = { level = "warn", priority = -1 } [lints.clippy] style = "allow" diff --git a/RELEASES.md b/RELEASES.md index 26accaf..6a11048 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,5 +1,9 @@ # Releases +## 1.2.1 (2026-08-28) + +- Sync changes from `indexmap v2.14.1` + ## 1.2.0 (2026-02-09) - **MSRV**: Rust 1.85.0 or later is now required. diff --git a/benches/bench.rs b/benches/bench.rs index 5d867df..7cfdba8 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -289,6 +289,7 @@ fn lookup_hashmap_10_000_exist(b: &mut Bencher) { } b.iter(|| { let mut found = 0; + #[expect(clippy::unnecessary_get_then_check)] for key in 5000..c { found += map.get(&key).is_some() as i32; } @@ -306,6 +307,7 @@ fn lookup_hashmap_10_000_noexist(b: &mut Bencher) { } b.iter(|| { let mut found = 0; + #[expect(clippy::unnecessary_get_then_check)] for key in c..15000 { found += map.get(&key).is_some() as i32; } diff --git a/benches/faststring.rs b/benches/faststring.rs index c1d9760..b03f882 100644 --- a/benches/faststring.rs +++ b/benches/faststring.rs @@ -117,6 +117,7 @@ fn lookup_hashmap_10_000_exist_string(b: &mut Bencher) { let lookups = (5000..c).map(|x| x.to_string()).collect::>(); b.iter(|| { let mut found = 0; + #[expect(clippy::unnecessary_get_then_check)] for key in &lookups { found += map.get(key).is_some() as i32; } @@ -137,6 +138,7 @@ fn lookup_hashmap_10_000_exist_string_oneshot(b: &mut Bencher) { .collect::>(); b.iter(|| { let mut found = 0; + #[expect(clippy::unnecessary_get_then_check)] for key in &lookups { found += map.get(key).is_some() as i32; } diff --git a/src/map.rs b/src/map.rs index 78c0d3d..380c8a9 100644 --- a/src/map.rs +++ b/src/map.rs @@ -820,7 +820,10 @@ where /// /// ``` /// let mut map = ordermap::OrderMap::from([(1, 'a'), (3, 'b'), (2, 'c')]); - /// assert_eq!(map.get_disjoint_mut([&2, &1]), [Some(&mut 'c'), Some(&mut 'a')]); + /// assert_eq!( + /// map.get_disjoint_mut([&2, &1, &0]), + /// [Some(&mut 'c'), Some(&mut 'a'), None], + /// ); /// ``` #[track_caller] pub fn get_disjoint_mut(&mut self, keys: [&Q; N]) -> [Option<&mut V>; N] @@ -1490,14 +1493,7 @@ impl Index for OrderMap { /// /// ***Panics*** if `index` is out of bounds. fn index(&self, index: usize) -> &V { - if let Some((_, value)) = self.get_index(index) { - value - } else { - panic!( - "index out of bounds: the len is {len} but the index is {index}", - len = self.len() - ); - } + &self.inner[index] } } @@ -1535,13 +1531,7 @@ impl IndexMut for OrderMap { /// /// ***Panics*** if `index` is out of bounds. fn index_mut(&mut self, index: usize) -> &mut V { - let len: usize = self.len(); - - if let Some((_, value)) = self.get_index_mut(index) { - value - } else { - panic!("index out of bounds: the len is {len} but the index is {index}"); - } + &mut self.inner[index] } } diff --git a/src/map/slice.rs b/src/map/slice.rs index db669ed..ab1d390 100644 --- a/src/map/slice.rs +++ b/src/map/slice.rs @@ -58,6 +58,7 @@ mod tests { let slice = map.as_slice(); // RangeFull + #[expect(clippy::redundant_slicing)] check(&vec[..], &map[..], &slice[..]); for i in 0usize..10 { diff --git a/src/map/tests.rs b/src/map/tests.rs index 0341155..c9bcbda 100644 --- a/src/map/tests.rs +++ b/src/map/tests.rs @@ -44,8 +44,8 @@ fn insert() { #[test] fn insert_full() { - let insert = vec![9, 2, 7, 1, 4, 6, 13]; - let present = vec![1, 6, 2]; + let insert = [9, 2, 7, 1, 4, 6, 13]; + let present = [1, 6, 2]; let mut map = OrderMap::with_capacity(insert.len()); for (i, &elt) in insert.iter().enumerate() { @@ -208,10 +208,10 @@ fn reserve() { assert_eq!(map.capacity(), capacity); assert_eq!(map.get(&i), Some(&(i * i))); } - map.insert(capacity, std::usize::MAX); + map.insert(capacity, usize::MAX); assert_eq!(map.len(), capacity + 1); assert!(map.capacity() > capacity); - assert_eq!(map.get(&capacity), Some(&std::usize::MAX)); + assert_eq!(map.get(&capacity), Some(&usize::MAX)); } #[test] @@ -231,7 +231,7 @@ fn shrink_to_fit() { assert_eq!(map.len(), i); map.insert(i, i * i); assert_eq!(map.len(), i + 1); - assert!(map.capacity() >= i + 1); + assert!(map.capacity() > i); assert_eq!(map.get(&i), Some(&(i * i))); map.shrink_to_fit(); assert_eq!(map.len(), i + 1); @@ -324,11 +324,11 @@ fn partial_eq_and_eq() { #[test] fn extend() { let mut map = OrderMap::new(); - map.extend(vec![(&1, &2), (&3, &4)]); - map.extend(vec![(5, 6)]); + map.extend([(&1, &2), (&3, &4)]); + map.extend([(5, 6)]); assert_eq!( map.into_iter().collect::>(), - vec![(1, 2), (3, 4), (5, 6)] + [(1, 2), (3, 4), (5, 6)] ); } @@ -371,18 +371,13 @@ fn entry_and_modify() { fn entry_or_default() { let mut map = OrderMap::new(); - #[derive(Debug, PartialEq)] + #[derive(Debug, Default, PartialEq)] enum TestEnum { + #[default] DefaultValue, NonDefaultValue, } - impl Default for TestEnum { - fn default() -> Self { - TestEnum::DefaultValue - } - } - map.insert(1, TestEnum::NonDefaultValue); assert_eq!(&mut TestEnum::NonDefaultValue, map.entry(1).or_default()); @@ -482,8 +477,7 @@ fn from_entries() { #[test] fn keys() { - let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')]; - let map: OrderMap<_, _> = vec.into_iter().collect(); + let map = OrderMap::<_, _>::from_iter([(1, 'a'), (2, 'b'), (3, 'c')]); let keys: Vec<_> = map.keys().copied().collect(); assert_eq!(keys.len(), 3); assert!(keys.contains(&1)); @@ -493,8 +487,7 @@ fn keys() { #[test] fn into_keys() { - let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')]; - let map: OrderMap<_, _> = vec.into_iter().collect(); + let map = OrderMap::<_, _>::from_iter([(1, 'a'), (2, 'b'), (3, 'c')]); let keys: Vec = map.into_keys().collect(); assert_eq!(keys.len(), 3); assert!(keys.contains(&1)); @@ -504,8 +497,7 @@ fn into_keys() { #[test] fn values() { - let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')]; - let map: OrderMap<_, _> = vec.into_iter().collect(); + let map = OrderMap::<_, _>::from_iter([(1, 'a'), (2, 'b'), (3, 'c')]); let values: Vec<_> = map.values().copied().collect(); assert_eq!(values.len(), 3); assert!(values.contains(&'a')); @@ -515,8 +507,7 @@ fn values() { #[test] fn values_mut() { - let vec = vec![(1, 1), (2, 2), (3, 3)]; - let mut map: OrderMap<_, _> = vec.into_iter().collect(); + let mut map = OrderMap::<_, _>::from_iter([(1, 1), (2, 2), (3, 3)]); for value in map.values_mut() { *value *= 2 } @@ -529,8 +520,7 @@ fn values_mut() { #[test] fn into_values() { - let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')]; - let map: OrderMap<_, _> = vec.into_iter().collect(); + let map = OrderMap::<_, _>::from_iter([(1, 'a'), (2, 'b'), (3, 'c')]); let values: Vec = map.into_values().collect(); assert_eq!(values.len(), 3); assert!(values.contains(&'a')); @@ -695,8 +685,7 @@ fn shift_remove_full() { #[test] fn sorted_unstable_by() { - let mut map: OrderMap = OrderMap::new(); - map.extend(vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50)]); + let map = OrderMap::::from_iter([(1, 10), (2, 20), (3, 30), (4, 40), (5, 50)]); let sorted = map.sorted_unstable_by(|_a, b, _c, d| d.cmp(&b)); assert_eq!( @@ -747,28 +736,24 @@ fn insert_before_oob() { #[test] fn clear() { - let mut map: OrderMap = OrderMap::new(); - map.extend(vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50)]); + let mut map = OrderMap::::from_iter([(1, 10), (2, 20), (3, 30), (4, 40), (5, 50)]); + assert_ne!(map.len(), 0); map.clear(); assert_eq!(map.len(), 0); } #[test] fn get_range() { - let mut index_map: OrderMap = OrderMap::new(); - index_map.insert(1, 10); - index_map.insert(2, 20); - index_map.insert(3, 30); - index_map.insert(4, 40); - index_map.insert(5, 50); + let map = OrderMap::::from_iter([(1, 10), (2, 20), (3, 30), (4, 40), (5, 50)]); - let result = index_map.get_range(2..2); + let result = map.get_range(2..2); assert!(result.unwrap().is_empty()); - let result = index_map.get_range(4..2); + #[expect(clippy::reversed_empty_ranges)] + let result = map.get_range(4..2); assert!(result.is_none()); - let result = index_map.get_range(2..4); + let result = map.get_range(2..4); let slice: &Slice = result.unwrap(); assert_eq!(slice.len(), 2); assert_eq!(slice, &[(3, 30), (4, 40)]); @@ -786,6 +771,7 @@ fn get_range_mut() { let result = index_map.get_range_mut(2..2); assert!(result.unwrap().is_empty()); + #[expect(clippy::reversed_empty_ranges)] let result = index_map.get_range_mut(4..2); assert!(result.is_none()); diff --git a/src/set.rs b/src/set.rs index 4c5410d..c4273b4 100644 --- a/src/set.rs +++ b/src/set.rs @@ -1215,14 +1215,7 @@ impl Index for OrderSet { /// /// ***Panics*** if `index` is out of bounds. fn index(&self, index: usize) -> &T { - if let Some(value) = self.get_index(index) { - value - } else { - panic!( - "index out of bounds: the len is {len} but the index is {index}", - len = self.len() - ); - } + &self.inner[index] } } diff --git a/src/set/slice.rs b/src/set/slice.rs index 7c0bdf0..432b98c 100644 --- a/src/set/slice.rs +++ b/src/set/slice.rs @@ -42,6 +42,7 @@ mod tests { let slice = set.as_slice(); // RangeFull + #[expect(clippy::redundant_slicing)] check(&vec[..], &set[..], &slice[..]); for i in 0usize..10 { diff --git a/src/set/tests.rs b/src/set/tests.rs index db4597d..173679a 100644 --- a/src/set/tests.rs +++ b/src/set/tests.rs @@ -43,8 +43,8 @@ fn insert() { #[test] fn insert_full() { - let insert = vec![9, 2, 7, 1, 4, 6, 13]; - let present = vec![1, 6, 2]; + let insert = [9, 2, 7, 1, 4, 6, 13]; + let present = [1, 6, 2]; let mut set = OrderSet::with_capacity(insert.len()); for (i, &elt) in insert.iter().enumerate() { @@ -91,8 +91,7 @@ fn insert_2() { #[test] fn insert_dup() { - let mut elements = vec![0, 2, 4, 6, 8]; - let mut set: OrderSet = elements.drain(..).collect(); + let mut set = OrderSet::::from_iter([0, 2, 4, 6, 8]); { let (i, v) = set.get_full(&0).unwrap(); assert_eq!(set.len(), 5); @@ -176,8 +175,8 @@ fn replace() { #[test] fn replace_full() { - let replace = vec![9, 2, 7, 1, 4, 6, 13]; - let present = vec![1, 6, 2]; + let replace = [9, 2, 7, 1, 4, 6, 13]; + let present = [1, 6, 2]; let mut set = OrderSet::with_capacity(replace.len()); for (i, &elt) in replace.iter().enumerate() { @@ -224,8 +223,7 @@ fn replace_2() { #[test] fn replace_dup() { - let mut elements = vec![0, 2, 4, 6, 8]; - let mut set: OrderSet = elements.drain(..).collect(); + let mut set = OrderSet::::from_iter([0, 2, 4, 6, 8]); { let (i, v) = set.get_full(&0).unwrap(); assert_eq!(set.len(), 5); @@ -339,7 +337,7 @@ fn shrink_to_fit() { assert_eq!(set.len(), i); set.insert(i); assert_eq!(set.len(), i + 1); - assert!(set.capacity() >= i + 1); + assert!(set.capacity() > i); assert_eq!(set.get(&i), Some(&i)); set.shrink_to_fit(); assert_eq!(set.len(), i + 1); @@ -427,9 +425,9 @@ fn partial_eq_and_eq() { #[test] fn extend() { let mut set = OrderSet::new(); - set.extend(vec![&1, &2, &3, &4]); - set.extend(vec![5, 6]); - assert_eq!(set.into_iter().collect::>(), vec![1, 2, 3, 4, 5, 6]); + set.extend([&1, &2, &3, &4]); + set.extend([5, 6]); + assert_eq!(set.into_iter().collect::>(), [1, 2, 3, 4, 5, 6]); } #[test] @@ -859,6 +857,7 @@ fn get_range() { let result = set.get_range(0..0); assert_eq!(result.unwrap().len(), 0); + #[expect(clippy::reversed_empty_ranges)] let result = set.get_range(2..1); assert!(result.is_none()); } diff --git a/tests/quick.rs b/tests/quick.rs index a24abf2..f076a1f 100644 --- a/tests/quick.rs +++ b/tests/quick.rs @@ -800,9 +800,7 @@ quickcheck_limit! { // value seen for that key! let mut last_val_per_key = HashMap::new(); for &(k, v) in input.iter().rev() { - if !last_val_per_key.contains_key(&k) { - last_val_per_key.insert(k, v); - } + last_val_per_key.entry(k).or_insert(v); } // iterate over the keys in (A) in order, and match each one with