From 7a548a5638bb6fd9228b7edb5cd415d7aaf64c4d Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 27 Sep 2019 07:47:06 -0700 Subject: [PATCH 1/4] Only rerun build script if build script changes Avoids unnecessary rebuilds when locally developing the crate. --- build.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/build.rs b/build.rs index 0b983143a5..818b20182f 100644 --- a/build.rs +++ b/build.rs @@ -1,4 +1,5 @@ fn main() { + println!("cargo:rerun-if-changed=build.rs"); let nightly = std::env::var_os("CARGO_FEATURE_NIGHTLY").is_some(); let has_stable_alloc = || autocfg::new().probe_rustc_version(1, 36); From 94ca7804c94d43068b4c9933e709695530746117 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 27 Sep 2019 07:55:28 -0700 Subject: [PATCH 2/4] Give modules native name instead of `imp` Helps when debugging and looking at symbols to see what we got. --- src/raw/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/raw/mod.rs b/src/raw/mod.rs index 18b55c2f49..e44f7a4d34 100644 --- a/src/raw/mod.rs +++ b/src/raw/mod.rs @@ -23,11 +23,11 @@ cfg_if! { any(target_arch = "x86", target_arch = "x86_64"), not(miri) ))] { - #[path = "sse2.rs"] - mod imp; + mod sse2; + use sse2 as imp; } else { - #[path = "generic.rs"] - mod imp; + mod generic; + use generic as imp; } } From 6d20b6b86668ffe3c69deb6ae3a1d37820dc0b84 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 27 Sep 2019 07:34:33 -0700 Subject: [PATCH 3/4] Remove most `#[inline]` annotations This commit goes through and deletes almost all `#[inline]` annotations in this crate. It looks like before this commit basically every single function is `#[inline]`, but this is generally not necessary for performance and can have a severe impact on compile times in both debug and release modes, most severely in release mode. Some `#[inline]` annotations are definitely necessary, however. Most functions in this crate are already candidates for inlining because they're generic, but functions like `Group` and `BitMask` aren't candidates for inlining without `#[inline]`. Additionally LLVM is by no means perfect, so some `#[inline]` may still be necessary to get some further speedups. The procedure used to generate this commit looked like: * Remove all `#[inline]` annotations. * Run `cargo bench`, comparing against the `master` branch, and add `#[inline]` to hot spots as necessary. * A [PR] was made against rust-lang/rust to [evaluate the impact][run1] on the compiler for more performance data. * Using this data, `perf diff` was used locally to determine further hot spots and more `#[inline]` annotations were added. * A [second round of benchmarking][run2] was done The numbers are at the point where I think this should land in the crate and get published to move into the standard library. There are up to 20% wins in compile time for hashmap-heavy crates (like Cargo) and milder wins (up to 10%) for a number of other large crates. The regressions are all in the 1-3% range and are largely on benchmarks taking a few handful of milliseconds anyway, which I'd personally say is a worthwhile tradeoff. For comparison, the benchmarks of this crate before and after this commit look like so: name baseline ns/iter new ns/iter diff ns/iter diff % speedup insert_ahash_highbits 7,137 9,044 1,907 26.72% x 0.79 insert_ahash_random 7,575 9,789 2,214 29.23% x 0.77 insert_ahash_serial 9,833 9,476 -357 -3.63% x 1.04 insert_erase_ahash_highbits 15,824 19,164 3,340 21.11% x 0.83 insert_erase_ahash_random 16,933 20,353 3,420 20.20% x 0.83 insert_erase_ahash_serial 20,857 27,675 6,818 32.69% x 0.75 insert_erase_std_highbits 35,117 38,385 3,268 9.31% x 0.91 insert_erase_std_random 35,357 37,236 1,879 5.31% x 0.95 insert_erase_std_serial 30,617 34,136 3,519 11.49% x 0.90 insert_std_highbits 15,675 18,180 2,505 15.98% x 0.86 insert_std_random 16,566 17,803 1,237 7.47% x 0.93 insert_std_serial 14,612 16,025 1,413 9.67% x 0.91 iter_ahash_highbits 1,715 1,640 -75 -4.37% x 1.05 iter_ahash_random 1,721 1,634 -87 -5.06% x 1.05 iter_ahash_serial 1,723 1,636 -87 -5.05% x 1.05 iter_std_highbits 1,715 1,634 -81 -4.72% x 1.05 iter_std_random 1,715 1,637 -78 -4.55% x 1.05 iter_std_serial 1,722 1,637 -85 -4.94% x 1.05 lookup_ahash_highbits 4,565 5,809 1,244 27.25% x 0.79 lookup_ahash_random 4,632 4,047 -585 -12.63% x 1.14 lookup_ahash_serial 4,612 4,906 294 6.37% x 0.94 lookup_fail_ahash_highbits 4,206 3,976 -230 -5.47% x 1.06 lookup_fail_ahash_random 4,327 4,211 -116 -2.68% x 1.03 lookup_fail_ahash_serial 8,999 4,386 -4,613 -51.26% x 2.05 lookup_fail_std_highbits 13,284 13,342 58 0.44% x 1.00 lookup_fail_std_random 13,172 13,614 442 3.36% x 0.97 lookup_fail_std_serial 11,240 11,539 299 2.66% x 0.97 lookup_std_highbits 13,075 13,333 258 1.97% x 0.98 lookup_std_random 13,257 13,193 -64 -0.48% x 1.00 lookup_std_serial 10,782 10,917 135 1.25% x 0.99 The summary of this from what I can tell is that the microbenchmarks are sort of all over the place, but they're neither consistently regressing nor improving, as expected. In general I would be surprised if there's much of a significant performance regression attributed to this commit, and `#[inline]` can always be selectively added back in easily without adding it to every function in the crate. [PR]: https://github.com/rust-lang/rust/pull/64846 [run1]: https://github.com/rust-lang/rust/pull/64846#issuecomment-536072300 [run2]: https://github.com/rust-lang/rust/pull/64846#issuecomment-536967792 --- src/external_trait_impls/rayon/map.rs | 17 ---- src/external_trait_impls/rayon/raw.rs | 11 --- src/external_trait_impls/rayon/set.rs | 7 -- src/external_trait_impls/serde.rs | 6 -- src/map.rs | 107 -------------------------- src/raw/generic.rs | 1 - src/raw/mod.rs | 63 --------------- src/raw/sse2.rs | 1 - src/rustc_entry.rs | 21 ----- src/scopeguard.rs | 4 - src/set.rs | 56 -------------- 11 files changed, 294 deletions(-) diff --git a/src/external_trait_impls/rayon/map.rs b/src/external_trait_impls/rayon/map.rs index 6f869ae0a0..d6496c4666 100644 --- a/src/external_trait_impls/rayon/map.rs +++ b/src/external_trait_impls/rayon/map.rs @@ -22,7 +22,6 @@ pub struct ParIter<'a, K, V, S> { impl<'a, K: Sync, V: Sync, S: Sync> ParallelIterator for ParIter<'a, K, V, S> { type Item = (&'a K, &'a V); - #[inline] fn drive_unindexed(self, consumer: C) -> C::Result where C: UnindexedConsumer, @@ -39,7 +38,6 @@ impl<'a, K: Sync, V: Sync, S: Sync> ParallelIterator for ParIter<'a, K, V, S> { } impl Clone for ParIter<'_, K, V, S> { - #[inline] fn clone(&self) -> Self { ParIter { map: self.map } } @@ -65,7 +63,6 @@ pub struct ParKeys<'a, K, V, S> { impl<'a, K: Sync, V: Sync, S: Sync> ParallelIterator for ParKeys<'a, K, V, S> { type Item = &'a K; - #[inline] fn drive_unindexed(self, consumer: C) -> C::Result where C: UnindexedConsumer, @@ -79,7 +76,6 @@ impl<'a, K: Sync, V: Sync, S: Sync> ParallelIterator for ParKeys<'a, K, V, S> { } impl Clone for ParKeys<'_, K, V, S> { - #[inline] fn clone(&self) -> Self { ParKeys { map: self.map } } @@ -105,7 +101,6 @@ pub struct ParValues<'a, K, V, S> { impl<'a, K: Sync, V: Sync, S: Sync> ParallelIterator for ParValues<'a, K, V, S> { type Item = &'a V; - #[inline] fn drive_unindexed(self, consumer: C) -> C::Result where C: UnindexedConsumer, @@ -119,7 +114,6 @@ impl<'a, K: Sync, V: Sync, S: Sync> ParallelIterator for ParValues<'a, K, V, S> } impl Clone for ParValues<'_, K, V, S> { - #[inline] fn clone(&self) -> Self { ParValues { map: self.map } } @@ -147,7 +141,6 @@ pub struct ParIterMut<'a, K, V, S> { impl<'a, K: Send + Sync, V: Send, S: Send> ParallelIterator for ParIterMut<'a, K, V, S> { type Item = (&'a K, &'a mut V); - #[inline] fn drive_unindexed(self, consumer: C) -> C::Result where C: UnindexedConsumer, @@ -185,7 +178,6 @@ pub struct ParValuesMut<'a, K, V, S> { impl<'a, K: Send, V: Send, S: Send> ParallelIterator for ParValuesMut<'a, K, V, S> { type Item = &'a mut V; - #[inline] fn drive_unindexed(self, consumer: C) -> C::Result where C: UnindexedConsumer, @@ -220,7 +212,6 @@ pub struct IntoParIter { impl ParallelIterator for IntoParIter { type Item = (K, V); - #[inline] fn drive_unindexed(self, consumer: C) -> C::Result where C: UnindexedConsumer, @@ -249,7 +240,6 @@ pub struct ParDrain<'a, K, V, S> { impl ParallelIterator for ParDrain<'_, K, V, S> { type Item = (K, V); - #[inline] fn drive_unindexed(self, consumer: C) -> C::Result where C: UnindexedConsumer, @@ -268,13 +258,11 @@ impl fmt::Debug impl HashMap { /// Visits (potentially in parallel) immutably borrowed keys in an arbitrary order. - #[inline] pub fn par_keys(&self) -> ParKeys<'_, K, V, S> { ParKeys { map: self } } /// Visits (potentially in parallel) immutably borrowed values in an arbitrary order. - #[inline] pub fn par_values(&self) -> ParValues<'_, K, V, S> { ParValues { map: self } } @@ -282,14 +270,12 @@ impl HashMap { impl HashMap { /// Visits (potentially in parallel) mutably borrowed values in an arbitrary order. - #[inline] pub fn par_values_mut(&mut self) -> ParValuesMut<'_, K, V, S> { ParValuesMut { map: self } } /// Consumes (potentially in parallel) all values in an arbitrary order, /// while preserving the map's allocated memory for reuse. - #[inline] pub fn par_drain(&mut self) -> ParDrain<'_, K, V, S> { ParDrain { map: self } } @@ -317,7 +303,6 @@ impl IntoParallelIterator for HashMap { type Item = (K, V); type Iter = IntoParIter; - #[inline] fn into_par_iter(self) -> Self::Iter { IntoParIter { map: self } } @@ -327,7 +312,6 @@ impl<'a, K: Sync, V: Sync, S: Sync> IntoParallelIterator for &'a HashMap; - #[inline] fn into_par_iter(self) -> Self::Iter { ParIter { map: self } } @@ -337,7 +321,6 @@ impl<'a, K: Send + Sync, V: Send, S: Send> IntoParallelIterator for &'a mut Hash type Item = (&'a K, &'a mut V); type Iter = ParIterMut<'a, K, V, S>; - #[inline] fn into_par_iter(self) -> Self::Iter { ParIterMut { map: self } } diff --git a/src/external_trait_impls/rayon/raw.rs b/src/external_trait_impls/rayon/raw.rs index 6834705cfd..bbca08d0b8 100644 --- a/src/external_trait_impls/rayon/raw.rs +++ b/src/external_trait_impls/rayon/raw.rs @@ -18,7 +18,6 @@ pub struct RawParIter { impl ParallelIterator for RawParIter { type Item = Bucket; - #[inline] fn drive_unindexed(self, consumer: C) -> C::Result where C: UnindexedConsumer, @@ -36,7 +35,6 @@ struct ParIterProducer { impl UnindexedProducer for ParIterProducer { type Item = Bucket; - #[inline] fn split(self) -> (Self, Option) { let (left, right) = self.iter.split(); let left = ParIterProducer { iter: left }; @@ -44,7 +42,6 @@ impl UnindexedProducer for ParIterProducer { (left, right) } - #[inline] fn fold_with(self, folder: F) -> F where F: Folder, @@ -61,7 +58,6 @@ pub struct RawIntoParIter { impl ParallelIterator for RawIntoParIter { type Item = T; - #[inline] fn drive_unindexed(self, consumer: C) -> C::Result where C: UnindexedConsumer, @@ -92,7 +88,6 @@ unsafe impl Send for RawParDrain<'_, T> {} impl ParallelIterator for RawParDrain<'_, T> { type Item = T; - #[inline] fn drive_unindexed(self, consumer: C) -> C::Result where C: UnindexedConsumer, @@ -123,7 +118,6 @@ struct ParDrainProducer { impl UnindexedProducer for ParDrainProducer { type Item = T; - #[inline] fn split(self) -> (Self, Option) { let (left, right) = self.iter.clone().split(); mem::forget(self); @@ -132,7 +126,6 @@ impl UnindexedProducer for ParDrainProducer { (left, right) } - #[inline] fn fold_with(mut self, mut folder: F) -> F where F: Folder, @@ -153,7 +146,6 @@ impl UnindexedProducer for ParDrainProducer { } impl Drop for ParDrainProducer { - #[inline] fn drop(&mut self) { // Drop all remaining elements if mem::needs_drop::() { @@ -168,7 +160,6 @@ impl Drop for ParDrainProducer { impl RawTable { /// Returns a parallel iterator over the elements in a `RawTable`. - #[inline] pub fn par_iter(&self) -> RawParIter { RawParIter { iter: unsafe { self.iter().iter }, @@ -176,14 +167,12 @@ impl RawTable { } /// Returns a parallel iterator over the elements in a `RawTable`. - #[inline] pub fn into_par_iter(self) -> RawIntoParIter { RawIntoParIter { table: self } } /// Returns a parallel iterator which consumes all elements of a `RawTable` /// without freeing its memory allocation. - #[inline] pub fn par_drain(&mut self) -> RawParDrain<'_, T> { RawParDrain { table: NonNull::from(self), diff --git a/src/external_trait_impls/rayon/set.rs b/src/external_trait_impls/rayon/set.rs index 896be75b0a..5301916e92 100644 --- a/src/external_trait_impls/rayon/set.rs +++ b/src/external_trait_impls/rayon/set.rs @@ -214,14 +214,12 @@ where { /// Visits (potentially in parallel) the values representing the difference, /// i.e. the values that are in `self` but not in `other`. - #[inline] pub fn par_difference<'a>(&'a self, other: &'a Self) -> ParDifference<'a, T, S> { ParDifference { a: self, b: other } } /// Visits (potentially in parallel) the values representing the symmetric /// difference, i.e. the values that are in `self` or in `other` but not in both. - #[inline] pub fn par_symmetric_difference<'a>( &'a self, other: &'a Self, @@ -231,14 +229,12 @@ where /// Visits (potentially in parallel) the values representing the /// intersection, i.e. the values that are both in `self` and `other`. - #[inline] pub fn par_intersection<'a>(&'a self, other: &'a Self) -> ParIntersection<'a, T, S> { ParIntersection { a: self, b: other } } /// Visits (potentially in parallel) the values representing the union, /// i.e. all the values in `self` or `other`, without duplicates. - #[inline] pub fn par_union<'a>(&'a self, other: &'a Self) -> ParUnion<'a, T, S> { ParUnion { a: self, b: other } } @@ -287,7 +283,6 @@ where { /// Consumes (potentially in parallel) all values in an arbitrary order, /// while preserving the set's allocated memory for reuse. - #[inline] pub fn par_drain(&mut self) -> ParDrain<'_, T, S> { ParDrain { set: self } } @@ -297,7 +292,6 @@ impl IntoParallelIterator for HashSet { type Item = T; type Iter = IntoParIter; - #[inline] fn into_par_iter(self) -> Self::Iter { IntoParIter { set: self } } @@ -307,7 +301,6 @@ impl<'a, T: Sync, S: Sync> IntoParallelIterator for &'a HashSet { type Item = &'a T; type Iter = ParIter<'a, T, S>; - #[inline] fn into_par_iter(self) -> Self::Iter { ParIter { set: self } } diff --git a/src/external_trait_impls/serde.rs b/src/external_trait_impls/serde.rs index 5adac8cd43..045aba62c9 100644 --- a/src/external_trait_impls/serde.rs +++ b/src/external_trait_impls/serde.rs @@ -4,7 +4,6 @@ mod size_hint { /// This presumably exists to prevent denial of service attacks. /// /// Original discussion: https://github.com/serde-rs/serde/issues/1114. - #[inline] pub(super) fn cautious(hint: Option) -> usize { cmp::min(hint.unwrap_or(0), 4096) } @@ -27,7 +26,6 @@ mod map { V: Serialize, H: BuildHasher, { - #[inline] fn serialize(&self, serializer: S) -> Result where S: Serializer, @@ -62,7 +60,6 @@ mod map { formatter.write_str("a map") } - #[inline] fn visit_map(self, mut map: A) -> Result where A: MapAccess<'de>, @@ -104,7 +101,6 @@ mod set { T: Serialize + Eq + Hash, H: BuildHasher, { - #[inline] fn serialize(&self, serializer: S) -> Result where S: Serializer, @@ -137,7 +133,6 @@ mod set { formatter.write_str("a sequence") } - #[inline] fn visit_seq(self, mut seq: A) -> Result where A: SeqAccess<'de>, @@ -178,7 +173,6 @@ mod set { formatter.write_str("a sequence") } - #[inline] fn visit_seq(self, mut seq: A) -> Result where A: SeqAccess<'de>, diff --git a/src/map.rs b/src/map.rs index eb95d48e60..03e3b979dc 100644 --- a/src/map.rs +++ b/src/map.rs @@ -196,7 +196,6 @@ pub struct HashMap { pub(crate) table: RawTable<(K, V)>, } -#[inline] pub(crate) fn make_hash(hash_builder: &impl BuildHasher, val: &K) -> u64 { let mut state = hash_builder.build_hasher(); val.hash(&mut state); @@ -216,7 +215,6 @@ impl HashMap { /// use hashbrown::HashMap; /// let mut map: HashMap<&str, i32> = HashMap::new(); /// ``` - #[inline] pub fn new() -> Self { Self::default() } @@ -232,7 +230,6 @@ impl HashMap { /// use hashbrown::HashMap; /// let mut map: HashMap<&str, i32> = HashMap::with_capacity(10); /// ``` - #[inline] pub fn with_capacity(capacity: usize) -> Self { Self::with_capacity_and_hasher(capacity, DefaultHashBuilder::default()) } @@ -259,7 +256,6 @@ impl HashMap { /// let mut map = HashMap::with_hasher(s); /// map.insert(1, 2); /// ``` - #[inline] pub fn with_hasher(hash_builder: S) -> Self { Self { hash_builder, @@ -288,7 +284,6 @@ impl HashMap { /// let mut map = HashMap::with_capacity_and_hasher(10, s); /// map.insert(1, 2); /// ``` - #[inline] pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self { Self { hash_builder, @@ -310,7 +305,6 @@ impl HashMap { /// let map: HashMap = HashMap::with_hasher(hasher); /// let hasher: &DefaultHashBuilder = map.hasher(); /// ``` - #[inline] pub fn hasher(&self) -> &S { &self.hash_builder } @@ -327,7 +321,6 @@ impl HashMap { /// let map: HashMap = HashMap::with_capacity(100); /// assert!(map.capacity() >= 100); /// ``` - #[inline] pub fn capacity(&self) -> usize { self.table.capacity() } @@ -349,7 +342,6 @@ impl HashMap { /// println!("{}", key); /// } /// ``` - #[inline] pub fn keys(&self) -> Keys<'_, K, V> { Keys { inner: self.iter() } } @@ -371,7 +363,6 @@ impl HashMap { /// println!("{}", val); /// } /// ``` - #[inline] pub fn values(&self) -> Values<'_, K, V> { Values { inner: self.iter() } } @@ -398,7 +389,6 @@ impl HashMap { /// println!("{}", val); /// } /// ``` - #[inline] pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> { ValuesMut { inner: self.iter_mut(), @@ -422,7 +412,6 @@ impl HashMap { /// println!("key: {} val: {}", key, val); /// } /// ``` - #[inline] pub fn iter(&self) -> Iter<'_, K, V> { // Here we tie the lifetime of self to the iter. unsafe { @@ -456,7 +445,6 @@ impl HashMap { /// println!("key: {} val: {}", key, val); /// } /// ``` - #[inline] pub fn iter_mut(&mut self) -> IterMut<'_, K, V> { // Here we tie the lifetime of self to the iter. unsafe { @@ -468,7 +456,6 @@ impl HashMap { } #[cfg(test)] - #[inline] fn raw_capacity(&self) -> usize { self.table.buckets() } @@ -485,7 +472,6 @@ impl HashMap { /// a.insert(1, "a"); /// assert_eq!(a.len(), 1); /// ``` - #[inline] pub fn len(&self) -> usize { self.table.len() } @@ -502,7 +488,6 @@ impl HashMap { /// a.insert(1, "a"); /// assert!(!a.is_empty()); /// ``` - #[inline] pub fn is_empty(&self) -> bool { self.len() == 0 } @@ -526,7 +511,6 @@ impl HashMap { /// /// assert!(a.is_empty()); /// ``` - #[inline] pub fn drain(&mut self) -> Drain<'_, K, V> { // Here we tie the lifetime of self to the iter. unsafe { @@ -549,7 +533,6 @@ impl HashMap { /// a.clear(); /// assert!(a.is_empty()); /// ``` - #[inline] pub fn clear(&mut self) { self.table.clear(); } @@ -577,7 +560,6 @@ where /// let mut map: HashMap<&str, i32> = HashMap::new(); /// map.reserve(10); /// ``` - #[inline] pub fn reserve(&mut self, additional: usize) { let hash_builder = &self.hash_builder; self.table @@ -600,7 +582,6 @@ where /// let mut map: HashMap<&str, isize> = HashMap::new(); /// map.try_reserve(10).expect("why is the test harness OOMing on 10 bytes?"); /// ``` - #[inline] pub fn try_reserve(&mut self, additional: usize) -> Result<(), CollectionAllocErr> { let hash_builder = &self.hash_builder; self.table @@ -623,7 +604,6 @@ where /// map.shrink_to_fit(); /// assert!(map.capacity() >= 2); /// ``` - #[inline] pub fn shrink_to_fit(&mut self) { let hash_builder = &self.hash_builder; self.table.shrink_to(0, |x| make_hash(hash_builder, &x.0)); @@ -652,7 +632,6 @@ where /// map.shrink_to(10); /// assert!(map.capacity() >= 2); /// ``` - #[inline] pub fn shrink_to(&mut self, min_capacity: usize) { let hash_builder = &self.hash_builder; self.table @@ -678,7 +657,6 @@ where /// assert_eq!(letters[&'u'], 1); /// assert_eq!(letters.get(&'y'), None); /// ``` - #[inline] pub fn entry(&mut self, key: K) -> Entry<'_, K, V, S> { let hash = make_hash(&self.hash_builder, &key); if let Some(elem) = self.table.find(hash, |q| q.0.eq(&key)) { @@ -777,7 +755,6 @@ where /// assert_eq!(map.contains_key(&1), true); /// assert_eq!(map.contains_key(&2), false); /// ``` - #[inline] pub fn contains_key(&self, k: &Q) -> bool where K: Borrow, @@ -807,7 +784,6 @@ where /// } /// assert_eq!(map[&1], "b"); /// ``` - #[inline] pub fn get_mut(&mut self, k: &Q) -> Option<&mut V> where K: Borrow, @@ -844,7 +820,6 @@ where /// assert_eq!(map.insert(37, "c"), Some("b")); /// assert_eq!(map[&37], "c"); /// ``` - #[inline] pub fn insert(&mut self, k: K, v: V) -> Option { unsafe { let hash = make_hash(&self.hash_builder, &k); @@ -879,7 +854,6 @@ where /// assert_eq!(map.remove(&1), Some("a")); /// assert_eq!(map.remove(&1), None); /// ``` - #[inline] pub fn remove(&mut self, k: &Q) -> Option where K: Borrow, @@ -910,7 +884,6 @@ where /// assert_eq!(map.remove(&1), None); /// # } /// ``` - #[inline] pub fn remove_entry(&mut self, k: &Q) -> Option<(K, V)> where K: Borrow, @@ -993,7 +966,6 @@ where /// so that the map now contains keys which compare equal, search may start /// acting erratically, with two keys randomly masking each other. Implementations /// are free to assume this doesn't happen (within the limits of memory-safety). - #[inline] pub fn raw_entry_mut(&mut self) -> RawEntryBuilderMut<'_, K, V, S> { RawEntryBuilderMut { map: self } } @@ -1013,7 +985,6 @@ where /// `get` should be preferred. /// /// Immutable raw entries have very limited use; you might instead want `raw_entry_mut`. - #[inline] pub fn raw_entry(&self) -> RawEntryBuilder<'_, K, V, S> { RawEntryBuilder { map: self } } @@ -1059,7 +1030,6 @@ where S: BuildHasher + Default, { /// Creates an empty `HashMap`, with the `Default` value for the hasher. - #[inline] fn default() -> Self { Self::with_hasher(Default::default()) } @@ -1078,7 +1048,6 @@ where /// # Panics /// /// Panics if the key is not present in the `HashMap`. - #[inline] fn index(&self, key: &Q) -> &V { self.get(key).expect("no entry found for key") } @@ -1098,7 +1067,6 @@ pub struct Iter<'a, K, V> { // FIXME(#26925) Remove in favor of `#[derive(Clone)]` impl Clone for Iter<'_, K, V> { - #[inline] fn clone(&self) -> Self { Iter { inner: self.inner.clone(), @@ -1133,7 +1101,6 @@ unsafe impl Send for IterMut<'_, K, V> {} impl IterMut<'_, K, V> { /// Returns a iterator of references over the remaining items. - #[inline] pub(super) fn iter(&self) -> Iter<'_, K, V> { Iter { inner: self.inner.clone(), @@ -1155,7 +1122,6 @@ pub struct IntoIter { impl IntoIter { /// Returns a iterator of references over the remaining items. - #[inline] pub(super) fn iter(&self) -> Iter<'_, K, V> { Iter { inner: self.inner.iter(), @@ -1177,7 +1143,6 @@ pub struct Keys<'a, K, V> { // FIXME(#26925) Remove in favor of `#[derive(Clone)]` impl Clone for Keys<'_, K, V> { - #[inline] fn clone(&self) -> Self { Keys { inner: self.inner.clone(), @@ -1204,7 +1169,6 @@ pub struct Values<'a, K, V> { // FIXME(#26925) Remove in favor of `#[derive(Clone)]` impl Clone for Values<'_, K, V> { - #[inline] fn clone(&self) -> Self { Values { inner: self.inner.clone(), @@ -1231,7 +1195,6 @@ pub struct Drain<'a, K, V> { impl Drain<'_, K, V> { /// Returns a iterator of references over the remaining items. - #[inline] pub(super) fn iter(&self) -> Iter<'_, K, V> { Iter { inner: self.inner.iter(), @@ -1323,7 +1286,6 @@ where S: BuildHasher, { /// Creates a `RawEntryMut` from the given key. - #[inline] #[allow(clippy::wrong_self_convention)] pub fn from_key(self, k: &Q) -> RawEntryMut<'a, K, V, S> where @@ -1352,7 +1314,6 @@ where S: BuildHasher, { /// Creates a `RawEntryMut` from the given hash. - #[inline] #[allow(clippy::wrong_self_convention)] pub fn from_hash(self, hash: u64, is_match: F) -> RawEntryMut<'a, K, V, S> where @@ -1361,7 +1322,6 @@ where self.search(hash, is_match) } - #[inline] fn search(self, hash: u64, mut is_match: F) -> RawEntryMut<'a, K, V, S> where for<'b> F: FnMut(&'b K) -> bool, @@ -1384,7 +1344,6 @@ where S: BuildHasher, { /// Access an entry by key. - #[inline] #[allow(clippy::wrong_self_convention)] pub fn from_key(self, k: &Q) -> Option<(&'a K, &'a V)> where @@ -1397,7 +1356,6 @@ where } /// Access an entry by a key and its hash. - #[inline] #[allow(clippy::wrong_self_convention)] pub fn from_key_hashed_nocheck(self, hash: u64, k: &Q) -> Option<(&'a K, &'a V)> where @@ -1407,7 +1365,6 @@ where self.from_hash(hash, |q| q.borrow().eq(k)) } - #[inline] fn search(self, hash: u64, mut is_match: F) -> Option<(&'a K, &'a V)> where F: FnMut(&K) -> bool, @@ -1422,7 +1379,6 @@ where } /// Access an entry by hash. - #[inline] #[allow(clippy::wrong_self_convention)] pub fn from_hash(self, hash: u64, is_match: F) -> Option<(&'a K, &'a V)> where @@ -1476,7 +1432,6 @@ impl<'a, K, V, S> RawEntryMut<'a, K, V, S> { /// *map.raw_entry_mut().from_key("poneyland").or_insert("poneyland", 10).1 *= 2; /// assert_eq!(map["poneyland"], 6); /// ``` - #[inline] pub fn or_insert(self, default_key: K, default_val: V) -> (&'a mut K, &'a mut V) where K: Hash, @@ -1504,7 +1459,6 @@ impl<'a, K, V, S> RawEntryMut<'a, K, V, S> { /// /// assert_eq!(map["poneyland"], "hoho".to_string()); /// ``` - #[inline] pub fn or_insert_with(self, default: F) -> (&'a mut K, &'a mut V) where F: FnOnce() -> (K, V), @@ -1542,7 +1496,6 @@ impl<'a, K, V, S> RawEntryMut<'a, K, V, S> { /// .or_insert("poneyland", 0); /// assert_eq!(map["poneyland"], 43); /// ``` - #[inline] pub fn and_modify(self, f: F) -> Self where F: FnOnce(&mut K, &mut V), @@ -1562,45 +1515,38 @@ impl<'a, K, V, S> RawEntryMut<'a, K, V, S> { impl<'a, K, V> RawOccupiedEntryMut<'a, K, V> { /// Gets a reference to the key in the entry. - #[inline] pub fn key(&self) -> &K { unsafe { &self.elem.as_ref().0 } } /// Gets a mutable reference to the key in the entry. - #[inline] pub fn key_mut(&mut self) -> &mut K { unsafe { &mut self.elem.as_mut().0 } } /// Converts the entry into a mutable reference to the key in the entry /// with a lifetime bound to the map itself. - #[inline] pub fn into_key(self) -> &'a mut K { unsafe { &mut self.elem.as_mut().0 } } /// Gets a reference to the value in the entry. - #[inline] pub fn get(&self) -> &V { unsafe { &self.elem.as_ref().1 } } /// Converts the OccupiedEntry into a mutable reference to the value in the entry /// with a lifetime bound to the map itself. - #[inline] pub fn into_mut(self) -> &'a mut V { unsafe { &mut self.elem.as_mut().1 } } /// Gets a mutable reference to the value in the entry. - #[inline] pub fn get_mut(&mut self) -> &mut V { unsafe { &mut self.elem.as_mut().1 } } /// Gets a reference to the key and value in the entry. - #[inline] pub fn get_key_value(&mut self) -> (&K, &V) { unsafe { let &(ref key, ref value) = self.elem.as_ref(); @@ -1609,7 +1555,6 @@ impl<'a, K, V> RawOccupiedEntryMut<'a, K, V> { } /// Gets a mutable reference to the key and value in the entry. - #[inline] pub fn get_key_value_mut(&mut self) -> (&mut K, &mut V) { unsafe { let &mut (ref mut key, ref mut value) = self.elem.as_mut(); @@ -1619,7 +1564,6 @@ impl<'a, K, V> RawOccupiedEntryMut<'a, K, V> { /// Converts the OccupiedEntry into a mutable reference to the key and value in the entry /// with a lifetime bound to the map itself. - #[inline] pub fn into_key_value(self) -> (&'a mut K, &'a mut V) { unsafe { let &mut (ref mut key, ref mut value) = self.elem.as_mut(); @@ -1628,25 +1572,21 @@ impl<'a, K, V> RawOccupiedEntryMut<'a, K, V> { } /// Sets the value of the entry, and returns the entry's old value. - #[inline] pub fn insert(&mut self, value: V) -> V { mem::replace(self.get_mut(), value) } /// Sets the value of the entry, and returns the entry's old value. - #[inline] pub fn insert_key(&mut self, key: K) -> K { mem::replace(self.key_mut(), key) } /// Takes the value out of the entry, and returns it. - #[inline] pub fn remove(self) -> V { self.remove_entry().1 } /// Take the ownership of the key and value from the map. - #[inline] pub fn remove_entry(self) -> (K, V) { unsafe { self.table.erase_no_drop(&self.elem); @@ -1658,7 +1598,6 @@ impl<'a, K, V> RawOccupiedEntryMut<'a, K, V> { impl<'a, K, V, S> RawVacantEntryMut<'a, K, V, S> { /// Sets the value of the entry with the VacantEntry's key, /// and returns a mutable reference to it. - #[inline] pub fn insert(self, key: K, value: V) -> (&'a mut K, &'a mut V) where K: Hash, @@ -1671,7 +1610,6 @@ impl<'a, K, V, S> RawVacantEntryMut<'a, K, V, S> { /// Sets the value of the entry with the VacantEntry's key, /// and returns a mutable reference to it. - #[inline] #[allow(clippy::shadow_unrelated)] pub fn insert_hashed_nocheck(self, hash: u64, key: K, value: V) -> (&'a mut K, &'a mut V) where @@ -1683,7 +1621,6 @@ impl<'a, K, V, S> RawVacantEntryMut<'a, K, V, S> { } /// Set the value of an entry with a custom hasher function. - #[inline] pub fn insert_with_hasher( self, hash: u64, @@ -1835,7 +1772,6 @@ impl<'a, K, V, S> IntoIterator for &'a HashMap { type Item = (&'a K, &'a V); type IntoIter = Iter<'a, K, V>; - #[inline] fn into_iter(self) -> Iter<'a, K, V> { self.iter() } @@ -1845,7 +1781,6 @@ impl<'a, K, V, S> IntoIterator for &'a mut HashMap { type Item = (&'a K, &'a mut V); type IntoIter = IterMut<'a, K, V>; - #[inline] fn into_iter(self) -> IterMut<'a, K, V> { self.iter_mut() } @@ -1872,7 +1807,6 @@ impl IntoIterator for HashMap { /// // Not possible with .iter() /// let vec: Vec<(&str, i32)> = map.into_iter().collect(); /// ``` - #[inline] fn into_iter(self) -> IntoIter { IntoIter { inner: self.table.into_iter(), @@ -1883,20 +1817,17 @@ impl IntoIterator for HashMap { impl<'a, K, V> Iterator for Iter<'a, K, V> { type Item = (&'a K, &'a V); - #[inline] fn next(&mut self) -> Option<(&'a K, &'a V)> { self.inner.next().map(|x| unsafe { let r = x.as_ref(); (&r.0, &r.1) }) } - #[inline] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } } impl ExactSizeIterator for Iter<'_, K, V> { - #[inline] fn len(&self) -> usize { self.inner.len() } @@ -1907,20 +1838,17 @@ impl FusedIterator for Iter<'_, K, V> {} impl<'a, K, V> Iterator for IterMut<'a, K, V> { type Item = (&'a K, &'a mut V); - #[inline] fn next(&mut self) -> Option<(&'a K, &'a mut V)> { self.inner.next().map(|x| unsafe { let r = x.as_mut(); (&r.0, &mut r.1) }) } - #[inline] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } } impl ExactSizeIterator for IterMut<'_, K, V> { - #[inline] fn len(&self) -> usize { self.inner.len() } @@ -1940,17 +1868,14 @@ where impl Iterator for IntoIter { type Item = (K, V); - #[inline] fn next(&mut self) -> Option<(K, V)> { self.inner.next() } - #[inline] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } } impl ExactSizeIterator for IntoIter { - #[inline] fn len(&self) -> usize { self.inner.len() } @@ -1966,17 +1891,14 @@ impl fmt::Debug for IntoIter { impl<'a, K, V> Iterator for Keys<'a, K, V> { type Item = &'a K; - #[inline] fn next(&mut self) -> Option<(&'a K)> { self.inner.next().map(|(k, _)| k) } - #[inline] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } } impl ExactSizeIterator for Keys<'_, K, V> { - #[inline] fn len(&self) -> usize { self.inner.len() } @@ -1986,17 +1908,14 @@ impl FusedIterator for Keys<'_, K, V> {} impl<'a, K, V> Iterator for Values<'a, K, V> { type Item = &'a V; - #[inline] fn next(&mut self) -> Option<(&'a V)> { self.inner.next().map(|(_, v)| v) } - #[inline] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } } impl ExactSizeIterator for Values<'_, K, V> { - #[inline] fn len(&self) -> usize { self.inner.len() } @@ -2006,17 +1925,14 @@ impl FusedIterator for Values<'_, K, V> {} impl<'a, K, V> Iterator for ValuesMut<'a, K, V> { type Item = &'a mut V; - #[inline] fn next(&mut self) -> Option<(&'a mut V)> { self.inner.next().map(|(_, v)| v) } - #[inline] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } } impl ExactSizeIterator for ValuesMut<'_, K, V> { - #[inline] fn len(&self) -> usize { self.inner.len() } @@ -2036,17 +1952,14 @@ where impl<'a, K, V> Iterator for Drain<'a, K, V> { type Item = (K, V); - #[inline] fn next(&mut self) -> Option<(K, V)> { self.inner.next() } - #[inline] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } } impl ExactSizeIterator for Drain<'_, K, V> { - #[inline] fn len(&self) -> usize { self.inner.len() } @@ -2107,7 +2020,6 @@ impl<'a, K, V, S> Entry<'a, K, V, S> { /// *map.entry("poneyland").or_insert(10) *= 2; /// assert_eq!(map["poneyland"], 6); /// ``` - #[inline] pub fn or_insert(self, default: V) -> &'a mut V where K: Hash, @@ -2134,7 +2046,6 @@ impl<'a, K, V, S> Entry<'a, K, V, S> { /// /// assert_eq!(map["poneyland"], "hoho".to_string()); /// ``` - #[inline] pub fn or_insert_with V>(self, default: F) -> &'a mut V where K: Hash, @@ -2156,7 +2067,6 @@ impl<'a, K, V, S> Entry<'a, K, V, S> { /// let mut map: HashMap<&str, u32> = HashMap::new(); /// assert_eq!(map.entry("poneyland").key(), &"poneyland"); /// ``` - #[inline] pub fn key(&self) -> &K { match *self { Entry::Occupied(ref entry) => entry.key(), @@ -2184,7 +2094,6 @@ impl<'a, K, V, S> Entry<'a, K, V, S> { /// .or_insert(42); /// assert_eq!(map["poneyland"], 43); /// ``` - #[inline] pub fn and_modify(self, f: F) -> Self where F: FnOnce(&mut V), @@ -2215,7 +2124,6 @@ impl<'a, K, V: Default, S> Entry<'a, K, V, S> { /// assert_eq!(map["poneyland"], None); /// # } /// ``` - #[inline] pub fn or_default(self) -> &'a mut V where K: Hash, @@ -2240,7 +2148,6 @@ impl<'a, K, V, S> OccupiedEntry<'a, K, V, S> { /// map.entry("poneyland").or_insert(12); /// assert_eq!(map.entry("poneyland").key(), &"poneyland"); /// ``` - #[inline] pub fn key(&self) -> &K { unsafe { &self.elem.as_ref().0 } } @@ -2263,7 +2170,6 @@ impl<'a, K, V, S> OccupiedEntry<'a, K, V, S> { /// /// assert_eq!(map.contains_key("poneyland"), false); /// ``` - #[inline] pub fn remove_entry(self) -> (K, V) { unsafe { self.table.table.erase_no_drop(&self.elem); @@ -2286,7 +2192,6 @@ impl<'a, K, V, S> OccupiedEntry<'a, K, V, S> { /// assert_eq!(o.get(), &12); /// } /// ``` - #[inline] pub fn get(&self) -> &V { unsafe { &self.elem.as_ref().1 } } @@ -2318,7 +2223,6 @@ impl<'a, K, V, S> OccupiedEntry<'a, K, V, S> { /// /// assert_eq!(map["poneyland"], 24); /// ``` - #[inline] pub fn get_mut(&mut self) -> &mut V { unsafe { &mut self.elem.as_mut().1 } } @@ -2346,7 +2250,6 @@ impl<'a, K, V, S> OccupiedEntry<'a, K, V, S> { /// /// assert_eq!(map["poneyland"], 22); /// ``` - #[inline] pub fn into_mut(self) -> &'a mut V { unsafe { &mut self.elem.as_mut().1 } } @@ -2368,7 +2271,6 @@ impl<'a, K, V, S> OccupiedEntry<'a, K, V, S> { /// /// assert_eq!(map["poneyland"], 15); /// ``` - #[inline] pub fn insert(&mut self, mut value: V) -> V { let old_value = self.get_mut(); mem::swap(&mut value, old_value); @@ -2392,7 +2294,6 @@ impl<'a, K, V, S> OccupiedEntry<'a, K, V, S> { /// /// assert_eq!(map.contains_key("poneyland"), false); /// ``` - #[inline] pub fn remove(self) -> V { self.remove_entry().1 } @@ -2417,7 +2318,6 @@ impl<'a, K, V, S> OccupiedEntry<'a, K, V, S> { /// } /// /// ``` - #[inline] pub fn replace_entry(self, value: V) -> (K, V) { let entry = unsafe { self.elem.as_mut() }; @@ -2451,7 +2351,6 @@ impl<'a, K, V, S> OccupiedEntry<'a, K, V, S> { /// } /// } /// ``` - #[inline] pub fn replace_key(self) -> K { let entry = unsafe { self.elem.as_mut() }; mem::replace(&mut entry.0, self.key.unwrap()) @@ -2470,7 +2369,6 @@ impl<'a, K, V, S> VacantEntry<'a, K, V, S> { /// let mut map: HashMap<&str, u32> = HashMap::new(); /// assert_eq!(map.entry("poneyland").key(), &"poneyland"); /// ``` - #[inline] pub fn key(&self) -> &K { &self.key } @@ -2489,7 +2387,6 @@ impl<'a, K, V, S> VacantEntry<'a, K, V, S> { /// v.into_key(); /// } /// ``` - #[inline] pub fn into_key(self) -> K { self.key } @@ -2510,7 +2407,6 @@ impl<'a, K, V, S> VacantEntry<'a, K, V, S> { /// } /// assert_eq!(map["poneyland"], 37); /// ``` - #[inline] pub fn insert(self, value: V) -> &'a mut V where K: Hash, @@ -2546,7 +2442,6 @@ where K: Eq + Hash, S: BuildHasher + Default, { - #[inline] fn from_iter>(iter: T) -> Self { let iter = iter.into_iter(); let mut map = Self::with_capacity_and_hasher(iter.size_hint().0, S::default()); @@ -2562,7 +2457,6 @@ where K: Eq + Hash, S: BuildHasher, { - #[inline] fn extend>(&mut self, iter: T) { // Keys may be already present or show multiple times in the iterator. // Reserve the entire hint lower bound if the map is empty. @@ -2587,7 +2481,6 @@ where V: Copy, S: BuildHasher, { - #[inline] fn extend>(&mut self, iter: T) { self.extend(iter.into_iter().map(|(&key, &value)| (key, value))); } diff --git a/src/raw/generic.rs b/src/raw/generic.rs index 0e00159d59..329e12f197 100644 --- a/src/raw/generic.rs +++ b/src/raw/generic.rs @@ -55,7 +55,6 @@ impl Group { /// a static variable to ensure the address is consistent across dylibs. /// /// This is guaranteed to be aligned to the group size. - #[inline] pub fn static_empty() -> &'static [u8] { union AlignedBytes { _align: Group, diff --git a/src/raw/mod.rs b/src/raw/mod.rs index e44f7a4d34..10ec4f160c 100644 --- a/src/raw/mod.rs +++ b/src/raw/mod.rs @@ -52,12 +52,10 @@ fn unlikely(b: bool) -> bool { } #[cfg(feature = "nightly")] -#[inline] unsafe fn offset_from(to: *const T, from: *const T) -> usize { to.offset_from(from) as usize } #[cfg(not(feature = "nightly"))] -#[inline] unsafe fn offset_from(to: *const T, from: *const T) -> usize { (to as usize - from as usize) / mem::size_of::() } @@ -71,7 +69,6 @@ enum Fallibility { impl Fallibility { /// Error to return on capacity overflow. - #[inline] fn capacity_overflow(self) -> CollectionAllocErr { use Fallibility::*; match self { @@ -81,7 +78,6 @@ impl Fallibility { } /// Error to return on allocation error. - #[inline] fn alloc_err(self, layout: Layout) -> CollectionAllocErr { use Fallibility::*; match self { @@ -174,7 +170,6 @@ impl Iterator for ProbeSeq { /// taking the maximum load factor into account. /// /// Returns `None` if an overflow occurs. -#[inline] // Workaround for emscripten bug emscripten-core/emscripten-fastcomp#258 #[cfg_attr(target_os = "emscripten", inline(never))] fn capacity_to_buckets(cap: usize) -> Option { @@ -197,7 +192,6 @@ fn capacity_to_buckets(cap: usize) -> Option { /// Returns the maximum effective capacity for the given bucket mask, taking /// the maximum load factor into account. -#[inline] fn bucket_mask_to_capacity(bucket_mask: usize) -> usize { if bucket_mask < 8 { // For tables with 1/2/4/8 buckets, we always reserve one empty slot. @@ -213,7 +207,6 @@ fn bucket_mask_to_capacity(bucket_mask: usize) -> usize { // and the offset of the buckets in the allocation. /// /// Returns `None` if an overflow occurs. -#[inline] #[cfg(feature = "nightly")] fn calculate_layout(buckets: usize) -> Option<(Layout, usize)> { debug_assert!(buckets.is_power_of_two()); @@ -236,7 +229,6 @@ fn calculate_layout(buckets: usize) -> Option<(Layout, usize)> { // Returns a Layout which describes the allocation required for a hash table, // and the offset of the buckets in the allocation. -#[inline] #[cfg(not(feature = "nightly"))] fn calculate_layout(buckets: usize) -> Option<(Layout, usize)> { debug_assert!(buckets.is_power_of_two()); @@ -267,14 +259,12 @@ pub struct Bucket { unsafe impl Send for Bucket {} impl Clone for Bucket { - #[inline] fn clone(&self) -> Self { Self { ptr: self.ptr } } } impl Bucket { - #[inline] unsafe fn from_base_index(base: *const T, index: usize) -> Self { let ptr = if mem::size_of::() == 0 { index as *const T @@ -283,7 +273,6 @@ impl Bucket { }; Self { ptr } } - #[inline] pub unsafe fn as_ptr(&self) -> *mut T { if mem::size_of::() == 0 { // Just return an arbitrary ZST pointer which is properly aligned @@ -292,7 +281,6 @@ impl Bucket { self.ptr as *mut T } } - #[inline] unsafe fn add(&self, offset: usize) -> Self { let ptr = if mem::size_of::() == 0 { (self.ptr as usize + offset) as *const T @@ -301,27 +289,21 @@ impl Bucket { }; Self { ptr } } - #[inline] pub unsafe fn drop(&self) { self.as_ptr().drop_in_place(); } - #[inline] pub unsafe fn read(&self) -> T { self.as_ptr().read() } - #[inline] pub unsafe fn write(&self, val: T) { self.as_ptr().write(val); } - #[inline] pub unsafe fn as_ref<'a>(&self) -> &'a T { &*self.as_ptr() } - #[inline] pub unsafe fn as_mut<'a>(&self) -> &'a mut T { &mut *self.as_ptr() } - #[inline] pub unsafe fn copy_from_nonoverlapping(&self, other: &Self) { self.as_ptr().copy_from_nonoverlapping(other.as_ptr(), 1); } @@ -355,7 +337,6 @@ impl RawTable { /// In effect this returns a table with exactly 1 bucket. However we can /// leave the data pointer dangling since that bucket is never written to /// due to our load factor forcing us to always have at least 1 free bucket. - #[inline] pub fn new() -> Self { Self { data: NonNull::dangling(), @@ -371,7 +352,6 @@ impl RawTable { /// Allocates a new hash table with the given number of buckets. /// /// The control bytes are left uninitialized. - #[inline] unsafe fn new_uninitialized( buckets: usize, fallability: Fallibility, @@ -419,7 +399,6 @@ impl RawTable { } /// Deallocates the table without dropping any entries. - #[inline] unsafe fn free_buckets(&mut self) { let (layout, _) = calculate_layout::(self.buckets()).unwrap_or_else(|| hint::unreachable_unchecked()); @@ -427,7 +406,6 @@ impl RawTable { } /// Returns the index of a bucket from a `Bucket`. - #[inline] unsafe fn bucket_index(&self, bucket: &Bucket) -> usize { if mem::size_of::() == 0 { bucket.ptr as usize @@ -437,14 +415,12 @@ impl RawTable { } /// Returns a pointer to a control byte. - #[inline] unsafe fn ctrl(&self, index: usize) -> *mut u8 { debug_assert!(index < self.num_ctrl_bytes()); self.ctrl.as_ptr().add(index) } /// Returns a pointer to an element in the table. - #[inline] pub unsafe fn bucket(&self, index: usize) -> Bucket { debug_assert_ne!(self.bucket_mask, 0); debug_assert!(index < self.buckets()); @@ -452,7 +428,6 @@ impl RawTable { } /// Erases an element from the table without dropping it. - #[inline] pub unsafe fn erase_no_drop(&mut self, item: &Bucket) { let index = self.bucket_index(item); debug_assert!(is_full(*self.ctrl(index))); @@ -483,7 +458,6 @@ impl RawTable { /// This iterator never terminates, but is guaranteed to visit each bucket /// group exactly once. The loop using `probe_seq` must terminate upon /// reaching a group containing an empty bucket. - #[inline] fn probe_seq(&self, hash: u64) -> ProbeSeq { ProbeSeq { bucket_mask: self.bucket_mask, @@ -494,7 +468,6 @@ impl RawTable { /// Sets a control byte, and possibly also the replicated control byte at /// the end of the array. - #[inline] unsafe fn set_ctrl(&self, index: usize, ctrl: u8) { // Replicate the first Group::WIDTH control bytes at the end of // the array without using a branch: @@ -524,7 +497,6 @@ impl RawTable { /// a new element. /// /// There must be at least 1 empty bucket in the table. - #[inline] fn find_insert_slot(&self, hash: u64) -> usize { for pos in self.probe_seq(hash) { unsafe { @@ -559,7 +531,6 @@ impl RawTable { } /// Marks all table buckets as empty without dropping their contents. - #[inline] pub fn clear_no_drop(&mut self) { if !self.is_empty_singleton() { unsafe { @@ -571,7 +542,6 @@ impl RawTable { } /// Removes all elements from the table without freeing the backing memory. - #[inline] pub fn clear(&mut self) { // Ensure that the table is reset even if one of the drops panic let self_ = guard(self, |self_| self_.clear_no_drop()); @@ -586,7 +556,6 @@ impl RawTable { } /// Shrinks the table to fit `max(self.len(), min_size)` elements. - #[inline] pub fn shrink_to(&mut self, min_size: usize, hasher: impl Fn(&T) -> u64) { // Calculate the minimal number of elements that we need to reserve // space for. @@ -619,7 +588,6 @@ impl RawTable { /// Ensures that at least `additional` items can be inserted into the table /// without reallocation. - #[inline] pub fn reserve(&mut self, additional: usize, hasher: impl Fn(&T) -> u64) { if additional > self.growth_left { self.reserve_rehash(additional, hasher, Fallibility::Infallible) @@ -629,7 +597,6 @@ impl RawTable { /// Tries to ensure that at least `additional` items can be inserted into /// the table without reallocation. - #[inline] pub fn try_reserve( &mut self, additional: usize, @@ -827,7 +794,6 @@ impl RawTable { /// Inserts a new element into the table. /// /// This does not check if the given element already exists in the table. - #[inline] pub fn insert(&mut self, hash: u64, value: T, hasher: impl Fn(&T) -> u64) -> Bucket { unsafe { let mut index = self.find_insert_slot(hash); @@ -855,7 +821,6 @@ impl RawTable { /// There must be enough space in the table to insert the new element. /// /// This does not check if the given element already exists in the table. - #[inline] #[cfg(feature = "rustc-internal-api")] pub fn insert_no_grow(&mut self, hash: u64, value: T) -> Bucket { unsafe { @@ -901,32 +866,27 @@ impl RawTable { /// /// This number is a lower bound; the table might be able to hold /// more, but is guaranteed to be able to hold at least this many. - #[inline] pub fn capacity(&self) -> usize { self.items + self.growth_left } /// Returns the number of elements in the table. - #[inline] pub fn len(&self) -> usize { self.items } /// Returns the number of buckets in the table. - #[inline] pub fn buckets(&self) -> usize { self.bucket_mask + 1 } /// Returns the number of control bytes in the table. - #[inline] fn num_ctrl_bytes(&self) -> usize { self.bucket_mask + 1 + Group::WIDTH } /// Returns whether this table points to the empty singleton with a capacity /// of 0. - #[inline] fn is_empty_singleton(&self) -> bool { self.bucket_mask == 0 } @@ -935,7 +895,6 @@ impl RawTable { /// the caller to ensure that the `RawTable` outlives the `RawIter`. /// Because we cannot make the `next` method unsafe on the `RawIter` /// struct, we have to make the `iter` method unsafe. - #[inline] pub unsafe fn iter(&self) -> RawIter { let data = Bucket::from_base_index(self.data.as_ptr(), 0); RawIter { @@ -948,7 +907,6 @@ impl RawTable { /// freeing the memory. It is up to the caller to ensure that the `RawTable` /// outlives the `RawDrain`. Because we cannot make the `next` method unsafe /// on the `RawDrain`, we have to make the `drain` method unsafe. - #[inline] pub unsafe fn drain(&mut self) -> RawDrain<'_, T> { RawDrain { iter: self.iter(), @@ -960,7 +918,6 @@ impl RawTable { /// Converts the table into a raw allocation. The contents of the table /// should be dropped using a `RawIter` before freeing the allocation. - #[inline] pub(crate) fn into_alloc(self) -> Option<(NonNull, Layout)> { let alloc = if self.is_empty_singleton() { None @@ -1031,7 +988,6 @@ impl Clone for RawTable { #[cfg(feature = "nightly")] unsafe impl<#[may_dangle] T> Drop for RawTable { - #[inline] fn drop(&mut self) { if !self.is_empty_singleton() { unsafe { @@ -1047,7 +1003,6 @@ unsafe impl<#[may_dangle] T> Drop for RawTable { } #[cfg(not(feature = "nightly"))] impl Drop for RawTable { - #[inline] fn drop(&mut self) { if !self.is_empty_singleton() { unsafe { @@ -1066,7 +1021,6 @@ impl IntoIterator for RawTable { type Item = T; type IntoIter = RawIntoIter; - #[inline] fn into_iter(self) -> RawIntoIter { unsafe { let iter = self.iter(); @@ -1102,7 +1056,6 @@ impl RawIterRange { /// Returns a `RawIterRange` covering a subset of a table. /// /// The control byte address must be aligned to the group size. - #[inline] unsafe fn new(ctrl: *const u8, data: Bucket, len: usize) -> Self { debug_assert_ne!(len, 0); debug_assert_eq!(ctrl as usize % Group::WIDTH, 0); @@ -1124,7 +1077,6 @@ impl RawIterRange { /// /// Returns `None` if the remaining range is smaller than or equal to the /// group width. - #[inline] #[cfg(feature = "rayon")] pub(crate) fn split(mut self) -> (Self, Option>) { unsafe { @@ -1168,7 +1120,6 @@ unsafe impl Send for RawIterRange {} unsafe impl Sync for RawIterRange {} impl Clone for RawIterRange { - #[inline] fn clone(&self) -> Self { Self { data: self.data.clone(), @@ -1182,7 +1133,6 @@ impl Clone for RawIterRange { impl Iterator for RawIterRange { type Item = Bucket; - #[inline] fn next(&mut self) -> Option> { unsafe { loop { @@ -1207,7 +1157,6 @@ impl Iterator for RawIterRange { } } - #[inline] fn size_hint(&self) -> (usize, Option) { // We don't have an item count, so just guess based on the range size. ( @@ -1226,7 +1175,6 @@ pub struct RawIter { } impl Clone for RawIter { - #[inline] fn clone(&self) -> Self { Self { iter: self.iter.clone(), @@ -1238,7 +1186,6 @@ impl Clone for RawIter { impl Iterator for RawIter { type Item = Bucket; - #[inline] fn next(&mut self) -> Option> { if let Some(b) = self.iter.next() { self.items -= 1; @@ -1252,7 +1199,6 @@ impl Iterator for RawIter { } } - #[inline] fn size_hint(&self) -> (usize, Option) { (self.items, Some(self.items)) } @@ -1269,7 +1215,6 @@ pub struct RawIntoIter { } impl RawIntoIter { - #[inline] pub fn iter(&self) -> RawIter { self.iter.clone() } @@ -1280,7 +1225,6 @@ unsafe impl Sync for RawIntoIter where T: Sync {} #[cfg(feature = "nightly")] unsafe impl<#[may_dangle] T> Drop for RawIntoIter { - #[inline] fn drop(&mut self) { unsafe { // Drop all remaining elements @@ -1299,7 +1243,6 @@ unsafe impl<#[may_dangle] T> Drop for RawIntoIter { } #[cfg(not(feature = "nightly"))] impl Drop for RawIntoIter { - #[inline] fn drop(&mut self) { unsafe { // Drop all remaining elements @@ -1320,12 +1263,10 @@ impl Drop for RawIntoIter { impl Iterator for RawIntoIter { type Item = T; - #[inline] fn next(&mut self) -> Option { unsafe { Some(self.iter.next()?.read()) } } - #[inline] fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } @@ -1350,7 +1291,6 @@ pub struct RawDrain<'a, T> { } impl RawDrain<'_, T> { - #[inline] pub fn iter(&self) -> RawIter { self.iter.clone() } @@ -1360,7 +1300,6 @@ unsafe impl Send for RawDrain<'_, T> where T: Send {} unsafe impl Sync for RawDrain<'_, T> where T: Sync {} impl Drop for RawDrain<'_, T> { - #[inline] fn drop(&mut self) { unsafe { // Drop all remaining elements. Note that this may panic. @@ -1385,7 +1324,6 @@ impl Drop for RawDrain<'_, T> { impl Iterator for RawDrain<'_, T> { type Item = T; - #[inline] fn next(&mut self) -> Option { unsafe { let item = self.iter.next()?; @@ -1393,7 +1331,6 @@ impl Iterator for RawDrain<'_, T> { } } - #[inline] fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } diff --git a/src/raw/sse2.rs b/src/raw/sse2.rs index 422b878122..79b0aad42d 100644 --- a/src/raw/sse2.rs +++ b/src/raw/sse2.rs @@ -29,7 +29,6 @@ impl Group { /// a static variable to ensure the address is consistent across dylibs. /// /// This is guaranteed to be aligned to the group size. - #[inline] pub fn static_empty() -> &'static [u8] { union AlignedBytes { _align: Group, diff --git a/src/rustc_entry.rs b/src/rustc_entry.rs index 8cf0024e35..1ab88ef90f 100644 --- a/src/rustc_entry.rs +++ b/src/rustc_entry.rs @@ -29,7 +29,6 @@ where /// assert_eq!(letters[&'u'], 1); /// assert_eq!(letters.get(&'y'), None); /// ``` - #[inline] pub fn rustc_entry(&mut self, key: K) -> RustcEntry<'_, K, V> { let hash = make_hash(&self.hash_builder, &key); if let Some(elem) = self.table.find(hash, |q| q.0.eq(&key)) { @@ -163,7 +162,6 @@ impl<'a, K, V> RustcEntry<'a, K, V> { /// *map.rustc_entry("poneyland").or_insert(10) *= 2; /// assert_eq!(map["poneyland"], 6); /// ``` - #[inline] pub fn or_insert(self, default: V) -> &'a mut V where K: Hash, @@ -189,7 +187,6 @@ impl<'a, K, V> RustcEntry<'a, K, V> { /// /// assert_eq!(map["poneyland"], "hoho".to_string()); /// ``` - #[inline] pub fn or_insert_with V>(self, default: F) -> &'a mut V where K: Hash, @@ -210,7 +207,6 @@ impl<'a, K, V> RustcEntry<'a, K, V> { /// let mut map: HashMap<&str, u32> = HashMap::new(); /// assert_eq!(map.rustc_entry("poneyland").key(), &"poneyland"); /// ``` - #[inline] pub fn key(&self) -> &K { match *self { Occupied(ref entry) => entry.key(), @@ -238,7 +234,6 @@ impl<'a, K, V> RustcEntry<'a, K, V> { /// .or_insert(42); /// assert_eq!(map["poneyland"], 43); /// ``` - #[inline] pub fn and_modify(self, f: F) -> Self where F: FnOnce(&mut V), @@ -269,7 +264,6 @@ impl<'a, K, V: Default> RustcEntry<'a, K, V> { /// assert_eq!(map["poneyland"], None); /// # } /// ``` - #[inline] pub fn or_default(self) -> &'a mut V where K: Hash, @@ -293,7 +287,6 @@ impl<'a, K, V> RustcOccupiedEntry<'a, K, V> { /// map.rustc_entry("poneyland").or_insert(12); /// assert_eq!(map.rustc_entry("poneyland").key(), &"poneyland"); /// ``` - #[inline] pub fn key(&self) -> &K { unsafe { &self.elem.as_ref().0 } } @@ -316,7 +309,6 @@ impl<'a, K, V> RustcOccupiedEntry<'a, K, V> { /// /// assert_eq!(map.contains_key("poneyland"), false); /// ``` - #[inline] pub fn remove_entry(self) -> (K, V) { unsafe { self.table.erase_no_drop(&self.elem); @@ -339,7 +331,6 @@ impl<'a, K, V> RustcOccupiedEntry<'a, K, V> { /// assert_eq!(o.get(), &12); /// } /// ``` - #[inline] pub fn get(&self) -> &V { unsafe { &self.elem.as_ref().1 } } @@ -371,7 +362,6 @@ impl<'a, K, V> RustcOccupiedEntry<'a, K, V> { /// /// assert_eq!(map["poneyland"], 24); /// ``` - #[inline] pub fn get_mut(&mut self) -> &mut V { unsafe { &mut self.elem.as_mut().1 } } @@ -399,7 +389,6 @@ impl<'a, K, V> RustcOccupiedEntry<'a, K, V> { /// /// assert_eq!(map["poneyland"], 22); /// ``` - #[inline] pub fn into_mut(self) -> &'a mut V { unsafe { &mut self.elem.as_mut().1 } } @@ -421,7 +410,6 @@ impl<'a, K, V> RustcOccupiedEntry<'a, K, V> { /// /// assert_eq!(map["poneyland"], 15); /// ``` - #[inline] pub fn insert(&mut self, mut value: V) -> V { let old_value = self.get_mut(); mem::swap(&mut value, old_value); @@ -445,7 +433,6 @@ impl<'a, K, V> RustcOccupiedEntry<'a, K, V> { /// /// assert_eq!(map.contains_key("poneyland"), false); /// ``` - #[inline] pub fn remove(self) -> V { self.remove_entry().1 } @@ -470,7 +457,6 @@ impl<'a, K, V> RustcOccupiedEntry<'a, K, V> { /// } /// /// ``` - #[inline] pub fn replace_entry(self, value: V) -> (K, V) { let entry = unsafe { self.elem.as_mut() }; @@ -504,7 +490,6 @@ impl<'a, K, V> RustcOccupiedEntry<'a, K, V> { /// } /// } /// ``` - #[inline] pub fn replace_key(self) -> K { let entry = unsafe { self.elem.as_mut() }; mem::replace(&mut entry.0, self.key.unwrap()) @@ -523,7 +508,6 @@ impl<'a, K, V> RustcVacantEntry<'a, K, V> { /// let mut map: HashMap<&str, u32> = HashMap::new(); /// assert_eq!(map.rustc_entry("poneyland").key(), &"poneyland"); /// ``` - #[inline] pub fn key(&self) -> &K { &self.key } @@ -542,7 +526,6 @@ impl<'a, K, V> RustcVacantEntry<'a, K, V> { /// v.into_key(); /// } /// ``` - #[inline] pub fn into_key(self) -> K { self.key } @@ -563,7 +546,6 @@ impl<'a, K, V> RustcVacantEntry<'a, K, V> { /// } /// assert_eq!(map["poneyland"], 37); /// ``` - #[inline] pub fn insert(self, value: V) -> &'a mut V { let bucket = self.table.insert_no_grow(self.hash, (self.key, value)); unsafe { &mut bucket.as_mut().1 } @@ -598,7 +580,6 @@ impl<'a, K, V> RustcVacantEntry<'a, K, V> { impl IterMut<'_, K, V> { /// Returns a iterator of references over the remaining items. - #[inline] pub fn rustc_iter(&self) -> Iter<'_, K, V> { self.iter() } @@ -606,7 +587,6 @@ impl IterMut<'_, K, V> { impl IntoIter { /// Returns a iterator of references over the remaining items. - #[inline] pub fn rustc_iter(&self) -> Iter<'_, K, V> { self.iter() } @@ -614,7 +594,6 @@ impl IntoIter { impl Drain<'_, K, V> { /// Returns a iterator of references over the remaining items. - #[inline] pub fn rustc_iter(&self) -> Iter<'_, K, V> { self.iter() } diff --git a/src/scopeguard.rs b/src/scopeguard.rs index 4e9bf045ad..ba99e7ffff 100644 --- a/src/scopeguard.rs +++ b/src/scopeguard.rs @@ -9,7 +9,6 @@ where value: T, } -#[inline] pub fn guard(value: T, dropfn: F) -> ScopeGuard where F: FnMut(&mut T), @@ -22,7 +21,6 @@ where F: FnMut(&mut T), { type Target = T; - #[inline] fn deref(&self) -> &T { &self.value } @@ -32,7 +30,6 @@ impl DerefMut for ScopeGuard where F: FnMut(&mut T), { - #[inline] fn deref_mut(&mut self) -> &mut T { &mut self.value } @@ -42,7 +39,6 @@ impl Drop for ScopeGuard where F: FnMut(&mut T), { - #[inline] fn drop(&mut self) { (self.dropfn)(&mut self.value) } diff --git a/src/set.rs b/src/set.rs index 633feaeec6..ef8eb8bfef 100644 --- a/src/set.rs +++ b/src/set.rs @@ -129,7 +129,6 @@ impl HashSet { /// use hashbrown::HashSet; /// let set: HashSet = HashSet::new(); /// ``` - #[inline] pub fn new() -> Self { Self { map: HashMap::new(), @@ -148,7 +147,6 @@ impl HashSet { /// let set: HashSet = HashSet::with_capacity(10); /// assert!(set.capacity() >= 10); /// ``` - #[inline] pub fn with_capacity(capacity: usize) -> Self { Self { map: HashMap::with_capacity(capacity), @@ -166,7 +164,6 @@ impl HashSet { /// let set: HashSet = HashSet::with_capacity(100); /// assert!(set.capacity() >= 100); /// ``` - #[inline] pub fn capacity(&self) -> usize { self.map.capacity() } @@ -187,7 +184,6 @@ impl HashSet { /// println!("{}", x); /// } /// ``` - #[inline] pub fn iter(&self) -> Iter<'_, T> { Iter { iter: self.map.keys(), @@ -206,7 +202,6 @@ impl HashSet { /// v.insert(1); /// assert_eq!(v.len(), 1); /// ``` - #[inline] pub fn len(&self) -> usize { self.map.len() } @@ -223,7 +218,6 @@ impl HashSet { /// v.insert(1); /// assert!(!v.is_empty()); /// ``` - #[inline] pub fn is_empty(&self) -> bool { self.map.is_empty() } @@ -245,7 +239,6 @@ impl HashSet { /// /// assert!(set.is_empty()); /// ``` - #[inline] pub fn drain(&mut self) -> Drain<'_, T> { Drain { iter: self.map.drain(), @@ -264,7 +257,6 @@ impl HashSet { /// v.clear(); /// assert!(v.is_empty()); /// ``` - #[inline] pub fn clear(&mut self) { self.map.clear() } @@ -295,7 +287,6 @@ where /// let mut set = HashSet::with_hasher(s); /// set.insert(2); /// ``` - #[inline] pub fn with_hasher(hasher: S) -> Self { Self { map: HashMap::with_hasher(hasher), @@ -323,7 +314,6 @@ where /// let mut set = HashSet::with_capacity_and_hasher(10, s); /// set.insert(1); /// ``` - #[inline] pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Self { Self { map: HashMap::with_capacity_and_hasher(capacity, hasher), @@ -344,7 +334,6 @@ where /// let set: HashSet = HashSet::with_hasher(hasher); /// let hasher: &DefaultHashBuilder = set.hasher(); /// ``` - #[inline] pub fn hasher(&self) -> &S { self.map.hasher() } @@ -365,7 +354,6 @@ where /// set.reserve(10); /// assert!(set.capacity() >= 10); /// ``` - #[inline] pub fn reserve(&mut self, additional: usize) { self.map.reserve(additional) } @@ -386,7 +374,6 @@ where /// let mut set: HashSet = HashSet::new(); /// set.try_reserve(10).expect("why is the test harness OOMing on 10 bytes?"); /// ``` - #[inline] pub fn try_reserve(&mut self, additional: usize) -> Result<(), CollectionAllocErr> { self.map.try_reserve(additional) } @@ -407,7 +394,6 @@ where /// set.shrink_to_fit(); /// assert!(set.capacity() >= 2); /// ``` - #[inline] pub fn shrink_to_fit(&mut self) { self.map.shrink_to_fit() } @@ -433,7 +419,6 @@ where /// set.shrink_to(0); /// assert!(set.capacity() >= 2); /// ``` - #[inline] pub fn shrink_to(&mut self, min_capacity: usize) { self.map.shrink_to(min_capacity) } @@ -461,7 +446,6 @@ where /// let diff: HashSet<_> = b.difference(&a).collect(); /// assert_eq!(diff, [4].iter().collect()); /// ``` - #[inline] pub fn difference<'a>(&'a self, other: &'a Self) -> Difference<'a, T, S> { Difference { iter: self.iter(), @@ -490,7 +474,6 @@ where /// assert_eq!(diff1, diff2); /// assert_eq!(diff1, [1, 4].iter().collect()); /// ``` - #[inline] pub fn symmetric_difference<'a>(&'a self, other: &'a Self) -> SymmetricDifference<'a, T, S> { SymmetricDifference { iter: self.difference(other).chain(other.difference(self)), @@ -515,7 +498,6 @@ where /// let intersection: HashSet<_> = a.intersection(&b).collect(); /// assert_eq!(intersection, [2, 3].iter().collect()); /// ``` - #[inline] pub fn intersection<'a>(&'a self, other: &'a Self) -> Intersection<'a, T, S> { Intersection { iter: self.iter(), @@ -541,7 +523,6 @@ where /// let union: HashSet<_> = a.union(&b).collect(); /// assert_eq!(union, [1, 2, 3, 4].iter().collect()); /// ``` - #[inline] pub fn union<'a>(&'a self, other: &'a Self) -> Union<'a, T, S> { Union { iter: self.iter().chain(other.difference(self)), @@ -566,7 +547,6 @@ where /// /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html - #[inline] pub fn contains(&self, value: &Q) -> bool where T: Borrow, @@ -593,7 +573,6 @@ where /// /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html - #[inline] pub fn get(&self, value: &Q) -> Option<&T> where T: Borrow, @@ -616,7 +595,6 @@ where /// assert_eq!(set.get_or_insert(100), &100); /// assert_eq!(set.len(), 4); // 100 was inserted /// ``` - #[inline] pub fn get_or_insert(&mut self, value: T) -> &T { // Although the raw entry gives us `&mut T`, we only return `&T` to be consistent with // `get`. Key mutation is "raw" because you're not supposed to affect `Eq` or `Hash`. @@ -645,7 +623,6 @@ where /// } /// assert_eq!(set.len(), 4); // a new "fish" was inserted /// ``` - #[inline] pub fn get_or_insert_with(&mut self, value: &Q, f: F) -> &T where T: Borrow, @@ -727,7 +704,6 @@ where /// set.insert(2); /// assert_eq!(set.is_superset(&sub), true); /// ``` - #[inline] pub fn is_superset(&self, other: &Self) -> bool { other.is_subset(self) } @@ -749,7 +725,6 @@ where /// assert_eq!(set.insert(2), false); /// assert_eq!(set.len(), 1); /// ``` - #[inline] pub fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()).is_none() } @@ -769,7 +744,6 @@ where /// set.replace(Vec::with_capacity(10)); /// assert_eq!(set.get(&[][..]).unwrap().capacity(), 10); /// ``` - #[inline] pub fn replace(&mut self, value: T) -> Option { match self.map.entry(value) { map::Entry::Occupied(occupied) => Some(occupied.replace_key()), @@ -801,7 +775,6 @@ where /// /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html - #[inline] pub fn remove(&mut self, value: &Q) -> bool where T: Borrow, @@ -828,7 +801,6 @@ where /// /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html - #[inline] pub fn take(&mut self, value: &Q) -> Option where T: Borrow, @@ -895,7 +867,6 @@ where T: Eq + Hash, S: BuildHasher + Default, { - #[inline] fn from_iter>(iter: I) -> Self { let mut set = Self::with_hasher(Default::default()); set.extend(iter); @@ -908,7 +879,6 @@ where T: Eq + Hash, S: BuildHasher, { - #[inline] fn extend>(&mut self, iter: I) { self.map.extend(iter.into_iter().map(|k| (k, ()))); } @@ -919,7 +889,6 @@ where T: 'a + Eq + Hash + Copy, S: BuildHasher, { - #[inline] fn extend>(&mut self, iter: I) { self.extend(iter.into_iter().cloned()); } @@ -931,7 +900,6 @@ where S: BuildHasher + Default, { /// Creates an empty `HashSet` with the `Default` value for the hasher. - #[inline] fn default() -> Self { Self { map: HashMap::default(), @@ -1154,7 +1122,6 @@ impl<'a, T, S> IntoIterator for &'a HashSet { type Item = &'a T; type IntoIter = Iter<'a, T>; - #[inline] fn into_iter(self) -> Iter<'a, T> { self.iter() } @@ -1184,7 +1151,6 @@ impl IntoIterator for HashSet { /// println!("{}", x); /// } /// ``` - #[inline] fn into_iter(self) -> IntoIter { IntoIter { iter: self.map.into_iter(), @@ -1193,7 +1159,6 @@ impl IntoIterator for HashSet { } impl Clone for Iter<'_, K> { - #[inline] fn clone(&self) -> Self { Iter { iter: self.iter.clone(), @@ -1203,17 +1168,14 @@ impl Clone for Iter<'_, K> { impl<'a, K> Iterator for Iter<'a, K> { type Item = &'a K; - #[inline] fn next(&mut self) -> Option<&'a K> { self.iter.next() } - #[inline] fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } } impl<'a, K> ExactSizeIterator for Iter<'a, K> { - #[inline] fn len(&self) -> usize { self.iter.len() } @@ -1229,17 +1191,14 @@ impl fmt::Debug for Iter<'_, K> { impl Iterator for IntoIter { type Item = K; - #[inline] fn next(&mut self) -> Option { self.iter.next().map(|(k, _)| k) } - #[inline] fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } } impl ExactSizeIterator for IntoIter { - #[inline] fn len(&self) -> usize { self.iter.len() } @@ -1256,17 +1215,14 @@ impl fmt::Debug for IntoIter { impl Iterator for Drain<'_, K> { type Item = K; - #[inline] fn next(&mut self) -> Option { self.iter.next().map(|(k, _)| k) } - #[inline] fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } } impl ExactSizeIterator for Drain<'_, K> { - #[inline] fn len(&self) -> usize { self.iter.len() } @@ -1281,7 +1237,6 @@ impl fmt::Debug for Drain<'_, K> { } impl Clone for Intersection<'_, T, S> { - #[inline] fn clone(&self) -> Self { Intersection { iter: self.iter.clone(), @@ -1297,7 +1252,6 @@ where { type Item = &'a T; - #[inline] fn next(&mut self) -> Option<&'a T> { loop { let elt = self.iter.next()?; @@ -1307,7 +1261,6 @@ where } } - #[inline] fn size_hint(&self) -> (usize, Option) { let (_, upper) = self.iter.size_hint(); (0, upper) @@ -1332,7 +1285,6 @@ where } impl Clone for Difference<'_, T, S> { - #[inline] fn clone(&self) -> Self { Difference { iter: self.iter.clone(), @@ -1348,7 +1300,6 @@ where { type Item = &'a T; - #[inline] fn next(&mut self) -> Option<&'a T> { loop { let elt = self.iter.next()?; @@ -1358,7 +1309,6 @@ where } } - #[inline] fn size_hint(&self) -> (usize, Option) { let (_, upper) = self.iter.size_hint(); (0, upper) @@ -1383,7 +1333,6 @@ where } impl Clone for SymmetricDifference<'_, T, S> { - #[inline] fn clone(&self) -> Self { SymmetricDifference { iter: self.iter.clone(), @@ -1398,11 +1347,9 @@ where { type Item = &'a T; - #[inline] fn next(&mut self) -> Option<&'a T> { self.iter.next() } - #[inline] fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } @@ -1426,7 +1373,6 @@ where } impl Clone for Union<'_, T, S> { - #[inline] fn clone(&self) -> Self { Union { iter: self.iter.clone(), @@ -1458,11 +1404,9 @@ where { type Item = &'a T; - #[inline] fn next(&mut self) -> Option<&'a T> { self.iter.next() } - #[inline] fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } From 4e9e27dc9c72ac7630f4ab781898e9236d0e303b Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 8 Oct 2019 22:15:21 -0700 Subject: [PATCH 4/4] Add back many `#[inline]` behind a `#[cfg]` --- Cargo.toml | 5 ++ src/external_trait_impls/rayon/map.rs | 17 ++++ src/external_trait_impls/rayon/raw.rs | 11 +++ src/external_trait_impls/rayon/set.rs | 7 ++ src/external_trait_impls/serde.rs | 6 ++ src/map.rs | 115 +++++++++++++++++++++++++- src/raw/generic.rs | 1 + src/raw/mod.rs | 64 ++++++++++++++ src/rustc_entry.rs | 23 +++++- src/scopeguard.rs | 4 + src/set.rs | 56 +++++++++++++ 11 files changed, 304 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 1eb6c1298d..6f73ff3956 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,5 +43,10 @@ rustc-internal-api = [] rustc-dep-of-std = ["nightly", "core", "compiler_builtins", "alloc", "rustc-internal-api"] raw = [] +# Enables usage of `#[inline]` on far more functions than by default in this +# crate. This may lead to a performance increase but often comes at a compile +# time cost. +inline-more = [] + [package.metadata.docs.rs] features = ["nightly", "rayon", "serde", "raw"] diff --git a/src/external_trait_impls/rayon/map.rs b/src/external_trait_impls/rayon/map.rs index d6496c4666..022e23e0f3 100644 --- a/src/external_trait_impls/rayon/map.rs +++ b/src/external_trait_impls/rayon/map.rs @@ -22,6 +22,7 @@ pub struct ParIter<'a, K, V, S> { impl<'a, K: Sync, V: Sync, S: Sync> ParallelIterator for ParIter<'a, K, V, S> { type Item = (&'a K, &'a V); + #[cfg_attr(feature = "inline-more", inline)] fn drive_unindexed(self, consumer: C) -> C::Result where C: UnindexedConsumer, @@ -38,6 +39,7 @@ impl<'a, K: Sync, V: Sync, S: Sync> ParallelIterator for ParIter<'a, K, V, S> { } impl Clone for ParIter<'_, K, V, S> { + #[cfg_attr(feature = "inline-more", inline)] fn clone(&self) -> Self { ParIter { map: self.map } } @@ -63,6 +65,7 @@ pub struct ParKeys<'a, K, V, S> { impl<'a, K: Sync, V: Sync, S: Sync> ParallelIterator for ParKeys<'a, K, V, S> { type Item = &'a K; + #[cfg_attr(feature = "inline-more", inline)] fn drive_unindexed(self, consumer: C) -> C::Result where C: UnindexedConsumer, @@ -76,6 +79,7 @@ impl<'a, K: Sync, V: Sync, S: Sync> ParallelIterator for ParKeys<'a, K, V, S> { } impl Clone for ParKeys<'_, K, V, S> { + #[cfg_attr(feature = "inline-more", inline)] fn clone(&self) -> Self { ParKeys { map: self.map } } @@ -101,6 +105,7 @@ pub struct ParValues<'a, K, V, S> { impl<'a, K: Sync, V: Sync, S: Sync> ParallelIterator for ParValues<'a, K, V, S> { type Item = &'a V; + #[cfg_attr(feature = "inline-more", inline)] fn drive_unindexed(self, consumer: C) -> C::Result where C: UnindexedConsumer, @@ -114,6 +119,7 @@ impl<'a, K: Sync, V: Sync, S: Sync> ParallelIterator for ParValues<'a, K, V, S> } impl Clone for ParValues<'_, K, V, S> { + #[cfg_attr(feature = "inline-more", inline)] fn clone(&self) -> Self { ParValues { map: self.map } } @@ -141,6 +147,7 @@ pub struct ParIterMut<'a, K, V, S> { impl<'a, K: Send + Sync, V: Send, S: Send> ParallelIterator for ParIterMut<'a, K, V, S> { type Item = (&'a K, &'a mut V); + #[cfg_attr(feature = "inline-more", inline)] fn drive_unindexed(self, consumer: C) -> C::Result where C: UnindexedConsumer, @@ -178,6 +185,7 @@ pub struct ParValuesMut<'a, K, V, S> { impl<'a, K: Send, V: Send, S: Send> ParallelIterator for ParValuesMut<'a, K, V, S> { type Item = &'a mut V; + #[cfg_attr(feature = "inline-more", inline)] fn drive_unindexed(self, consumer: C) -> C::Result where C: UnindexedConsumer, @@ -212,6 +220,7 @@ pub struct IntoParIter { impl ParallelIterator for IntoParIter { type Item = (K, V); + #[cfg_attr(feature = "inline-more", inline)] fn drive_unindexed(self, consumer: C) -> C::Result where C: UnindexedConsumer, @@ -240,6 +249,7 @@ pub struct ParDrain<'a, K, V, S> { impl ParallelIterator for ParDrain<'_, K, V, S> { type Item = (K, V); + #[cfg_attr(feature = "inline-more", inline)] fn drive_unindexed(self, consumer: C) -> C::Result where C: UnindexedConsumer, @@ -258,11 +268,13 @@ impl fmt::Debug impl HashMap { /// Visits (potentially in parallel) immutably borrowed keys in an arbitrary order. + #[cfg_attr(feature = "inline-more", inline)] pub fn par_keys(&self) -> ParKeys<'_, K, V, S> { ParKeys { map: self } } /// Visits (potentially in parallel) immutably borrowed values in an arbitrary order. + #[cfg_attr(feature = "inline-more", inline)] pub fn par_values(&self) -> ParValues<'_, K, V, S> { ParValues { map: self } } @@ -270,12 +282,14 @@ impl HashMap { impl HashMap { /// Visits (potentially in parallel) mutably borrowed values in an arbitrary order. + #[cfg_attr(feature = "inline-more", inline)] pub fn par_values_mut(&mut self) -> ParValuesMut<'_, K, V, S> { ParValuesMut { map: self } } /// Consumes (potentially in parallel) all values in an arbitrary order, /// while preserving the map's allocated memory for reuse. + #[cfg_attr(feature = "inline-more", inline)] pub fn par_drain(&mut self) -> ParDrain<'_, K, V, S> { ParDrain { map: self } } @@ -303,6 +317,7 @@ impl IntoParallelIterator for HashMap { type Item = (K, V); type Iter = IntoParIter; + #[cfg_attr(feature = "inline-more", inline)] fn into_par_iter(self) -> Self::Iter { IntoParIter { map: self } } @@ -312,6 +327,7 @@ impl<'a, K: Sync, V: Sync, S: Sync> IntoParallelIterator for &'a HashMap; + #[cfg_attr(feature = "inline-more", inline)] fn into_par_iter(self) -> Self::Iter { ParIter { map: self } } @@ -321,6 +337,7 @@ impl<'a, K: Send + Sync, V: Send, S: Send> IntoParallelIterator for &'a mut Hash type Item = (&'a K, &'a mut V); type Iter = ParIterMut<'a, K, V, S>; + #[cfg_attr(feature = "inline-more", inline)] fn into_par_iter(self) -> Self::Iter { ParIterMut { map: self } } diff --git a/src/external_trait_impls/rayon/raw.rs b/src/external_trait_impls/rayon/raw.rs index bbca08d0b8..c6fe09dff1 100644 --- a/src/external_trait_impls/rayon/raw.rs +++ b/src/external_trait_impls/rayon/raw.rs @@ -18,6 +18,7 @@ pub struct RawParIter { impl ParallelIterator for RawParIter { type Item = Bucket; + #[cfg_attr(feature = "inline-more", inline)] fn drive_unindexed(self, consumer: C) -> C::Result where C: UnindexedConsumer, @@ -35,6 +36,7 @@ struct ParIterProducer { impl UnindexedProducer for ParIterProducer { type Item = Bucket; + #[cfg_attr(feature = "inline-more", inline)] fn split(self) -> (Self, Option) { let (left, right) = self.iter.split(); let left = ParIterProducer { iter: left }; @@ -42,6 +44,7 @@ impl UnindexedProducer for ParIterProducer { (left, right) } + #[cfg_attr(feature = "inline-more", inline)] fn fold_with(self, folder: F) -> F where F: Folder, @@ -58,6 +61,7 @@ pub struct RawIntoParIter { impl ParallelIterator for RawIntoParIter { type Item = T; + #[cfg_attr(feature = "inline-more", inline)] fn drive_unindexed(self, consumer: C) -> C::Result where C: UnindexedConsumer, @@ -88,6 +92,7 @@ unsafe impl Send for RawParDrain<'_, T> {} impl ParallelIterator for RawParDrain<'_, T> { type Item = T; + #[cfg_attr(feature = "inline-more", inline)] fn drive_unindexed(self, consumer: C) -> C::Result where C: UnindexedConsumer, @@ -118,6 +123,7 @@ struct ParDrainProducer { impl UnindexedProducer for ParDrainProducer { type Item = T; + #[cfg_attr(feature = "inline-more", inline)] fn split(self) -> (Self, Option) { let (left, right) = self.iter.clone().split(); mem::forget(self); @@ -126,6 +132,7 @@ impl UnindexedProducer for ParDrainProducer { (left, right) } + #[cfg_attr(feature = "inline-more", inline)] fn fold_with(mut self, mut folder: F) -> F where F: Folder, @@ -146,6 +153,7 @@ impl UnindexedProducer for ParDrainProducer { } impl Drop for ParDrainProducer { + #[cfg_attr(feature = "inline-more", inline)] fn drop(&mut self) { // Drop all remaining elements if mem::needs_drop::() { @@ -160,6 +168,7 @@ impl Drop for ParDrainProducer { impl RawTable { /// Returns a parallel iterator over the elements in a `RawTable`. + #[cfg_attr(feature = "inline-more", inline)] pub fn par_iter(&self) -> RawParIter { RawParIter { iter: unsafe { self.iter().iter }, @@ -167,12 +176,14 @@ impl RawTable { } /// Returns a parallel iterator over the elements in a `RawTable`. + #[cfg_attr(feature = "inline-more", inline)] pub fn into_par_iter(self) -> RawIntoParIter { RawIntoParIter { table: self } } /// Returns a parallel iterator which consumes all elements of a `RawTable` /// without freeing its memory allocation. + #[cfg_attr(feature = "inline-more", inline)] pub fn par_drain(&mut self) -> RawParDrain<'_, T> { RawParDrain { table: NonNull::from(self), diff --git a/src/external_trait_impls/rayon/set.rs b/src/external_trait_impls/rayon/set.rs index 5301916e92..53d2660d58 100644 --- a/src/external_trait_impls/rayon/set.rs +++ b/src/external_trait_impls/rayon/set.rs @@ -214,12 +214,14 @@ where { /// Visits (potentially in parallel) the values representing the difference, /// i.e. the values that are in `self` but not in `other`. + #[cfg_attr(feature = "inline-more", inline)] pub fn par_difference<'a>(&'a self, other: &'a Self) -> ParDifference<'a, T, S> { ParDifference { a: self, b: other } } /// Visits (potentially in parallel) the values representing the symmetric /// difference, i.e. the values that are in `self` or in `other` but not in both. + #[cfg_attr(feature = "inline-more", inline)] pub fn par_symmetric_difference<'a>( &'a self, other: &'a Self, @@ -229,12 +231,14 @@ where /// Visits (potentially in parallel) the values representing the /// intersection, i.e. the values that are both in `self` and `other`. + #[cfg_attr(feature = "inline-more", inline)] pub fn par_intersection<'a>(&'a self, other: &'a Self) -> ParIntersection<'a, T, S> { ParIntersection { a: self, b: other } } /// Visits (potentially in parallel) the values representing the union, /// i.e. all the values in `self` or `other`, without duplicates. + #[cfg_attr(feature = "inline-more", inline)] pub fn par_union<'a>(&'a self, other: &'a Self) -> ParUnion<'a, T, S> { ParUnion { a: self, b: other } } @@ -283,6 +287,7 @@ where { /// Consumes (potentially in parallel) all values in an arbitrary order, /// while preserving the set's allocated memory for reuse. + #[cfg_attr(feature = "inline-more", inline)] pub fn par_drain(&mut self) -> ParDrain<'_, T, S> { ParDrain { set: self } } @@ -292,6 +297,7 @@ impl IntoParallelIterator for HashSet { type Item = T; type Iter = IntoParIter; + #[cfg_attr(feature = "inline-more", inline)] fn into_par_iter(self) -> Self::Iter { IntoParIter { set: self } } @@ -301,6 +307,7 @@ impl<'a, T: Sync, S: Sync> IntoParallelIterator for &'a HashSet { type Item = &'a T; type Iter = ParIter<'a, T, S>; + #[cfg_attr(feature = "inline-more", inline)] fn into_par_iter(self) -> Self::Iter { ParIter { set: self } } diff --git a/src/external_trait_impls/serde.rs b/src/external_trait_impls/serde.rs index 045aba62c9..7816e78039 100644 --- a/src/external_trait_impls/serde.rs +++ b/src/external_trait_impls/serde.rs @@ -4,6 +4,7 @@ mod size_hint { /// This presumably exists to prevent denial of service attacks. /// /// Original discussion: https://github.com/serde-rs/serde/issues/1114. + #[cfg_attr(feature = "inline-more", inline)] pub(super) fn cautious(hint: Option) -> usize { cmp::min(hint.unwrap_or(0), 4096) } @@ -26,6 +27,7 @@ mod map { V: Serialize, H: BuildHasher, { + #[cfg_attr(feature = "inline-more", inline)] fn serialize(&self, serializer: S) -> Result where S: Serializer, @@ -60,6 +62,7 @@ mod map { formatter.write_str("a map") } + #[cfg_attr(feature = "inline-more", inline)] fn visit_map(self, mut map: A) -> Result where A: MapAccess<'de>, @@ -101,6 +104,7 @@ mod set { T: Serialize + Eq + Hash, H: BuildHasher, { + #[cfg_attr(feature = "inline-more", inline)] fn serialize(&self, serializer: S) -> Result where S: Serializer, @@ -133,6 +137,7 @@ mod set { formatter.write_str("a sequence") } + #[cfg_attr(feature = "inline-more", inline)] fn visit_seq(self, mut seq: A) -> Result where A: SeqAccess<'de>, @@ -173,6 +178,7 @@ mod set { formatter.write_str("a sequence") } + #[cfg_attr(feature = "inline-more", inline)] fn visit_seq(self, mut seq: A) -> Result where A: SeqAccess<'de>, diff --git a/src/map.rs b/src/map.rs index 03e3b979dc..2f6bf777b1 100644 --- a/src/map.rs +++ b/src/map.rs @@ -196,6 +196,7 @@ pub struct HashMap { pub(crate) table: RawTable<(K, V)>, } +#[cfg_attr(feature = "inline-more", inline)] pub(crate) fn make_hash(hash_builder: &impl BuildHasher, val: &K) -> u64 { let mut state = hash_builder.build_hasher(); val.hash(&mut state); @@ -215,6 +216,7 @@ impl HashMap { /// use hashbrown::HashMap; /// let mut map: HashMap<&str, i32> = HashMap::new(); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn new() -> Self { Self::default() } @@ -230,6 +232,7 @@ impl HashMap { /// use hashbrown::HashMap; /// let mut map: HashMap<&str, i32> = HashMap::with_capacity(10); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn with_capacity(capacity: usize) -> Self { Self::with_capacity_and_hasher(capacity, DefaultHashBuilder::default()) } @@ -256,6 +259,7 @@ impl HashMap { /// let mut map = HashMap::with_hasher(s); /// map.insert(1, 2); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn with_hasher(hash_builder: S) -> Self { Self { hash_builder, @@ -284,6 +288,7 @@ impl HashMap { /// let mut map = HashMap::with_capacity_and_hasher(10, s); /// map.insert(1, 2); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self { Self { hash_builder, @@ -305,6 +310,7 @@ impl HashMap { /// let map: HashMap = HashMap::with_hasher(hasher); /// let hasher: &DefaultHashBuilder = map.hasher(); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn hasher(&self) -> &S { &self.hash_builder } @@ -321,6 +327,7 @@ impl HashMap { /// let map: HashMap = HashMap::with_capacity(100); /// assert!(map.capacity() >= 100); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn capacity(&self) -> usize { self.table.capacity() } @@ -342,6 +349,7 @@ impl HashMap { /// println!("{}", key); /// } /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn keys(&self) -> Keys<'_, K, V> { Keys { inner: self.iter() } } @@ -363,6 +371,7 @@ impl HashMap { /// println!("{}", val); /// } /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn values(&self) -> Values<'_, K, V> { Values { inner: self.iter() } } @@ -389,6 +398,7 @@ impl HashMap { /// println!("{}", val); /// } /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> { ValuesMut { inner: self.iter_mut(), @@ -412,6 +422,7 @@ impl HashMap { /// println!("key: {} val: {}", key, val); /// } /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn iter(&self) -> Iter<'_, K, V> { // Here we tie the lifetime of self to the iter. unsafe { @@ -445,6 +456,7 @@ impl HashMap { /// println!("key: {} val: {}", key, val); /// } /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn iter_mut(&mut self) -> IterMut<'_, K, V> { // Here we tie the lifetime of self to the iter. unsafe { @@ -456,6 +468,7 @@ impl HashMap { } #[cfg(test)] + #[cfg_attr(feature = "inline-more", inline)] fn raw_capacity(&self) -> usize { self.table.buckets() } @@ -472,6 +485,7 @@ impl HashMap { /// a.insert(1, "a"); /// assert_eq!(a.len(), 1); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn len(&self) -> usize { self.table.len() } @@ -488,6 +502,7 @@ impl HashMap { /// a.insert(1, "a"); /// assert!(!a.is_empty()); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn is_empty(&self) -> bool { self.len() == 0 } @@ -511,6 +526,7 @@ impl HashMap { /// /// assert!(a.is_empty()); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn drain(&mut self) -> Drain<'_, K, V> { // Here we tie the lifetime of self to the iter. unsafe { @@ -533,6 +549,7 @@ impl HashMap { /// a.clear(); /// assert!(a.is_empty()); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn clear(&mut self) { self.table.clear(); } @@ -560,6 +577,7 @@ where /// let mut map: HashMap<&str, i32> = HashMap::new(); /// map.reserve(10); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn reserve(&mut self, additional: usize) { let hash_builder = &self.hash_builder; self.table @@ -582,6 +600,7 @@ where /// let mut map: HashMap<&str, isize> = HashMap::new(); /// map.try_reserve(10).expect("why is the test harness OOMing on 10 bytes?"); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn try_reserve(&mut self, additional: usize) -> Result<(), CollectionAllocErr> { let hash_builder = &self.hash_builder; self.table @@ -604,6 +623,7 @@ where /// map.shrink_to_fit(); /// assert!(map.capacity() >= 2); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn shrink_to_fit(&mut self) { let hash_builder = &self.hash_builder; self.table.shrink_to(0, |x| make_hash(hash_builder, &x.0)); @@ -632,6 +652,7 @@ where /// map.shrink_to(10); /// assert!(map.capacity() >= 2); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn shrink_to(&mut self, min_capacity: usize) { let hash_builder = &self.hash_builder; self.table @@ -657,6 +678,7 @@ where /// assert_eq!(letters[&'u'], 1); /// assert_eq!(letters.get(&'y'), None); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn entry(&mut self, key: K) -> Entry<'_, K, V, S> { let hash = make_hash(&self.hash_builder, &key); if let Some(elem) = self.table.find(hash, |q| q.0.eq(&key)) { @@ -755,6 +777,7 @@ where /// assert_eq!(map.contains_key(&1), true); /// assert_eq!(map.contains_key(&2), false); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn contains_key(&self, k: &Q) -> bool where K: Borrow, @@ -784,6 +807,7 @@ where /// } /// assert_eq!(map[&1], "b"); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn get_mut(&mut self, k: &Q) -> Option<&mut V> where K: Borrow, @@ -820,6 +844,7 @@ where /// assert_eq!(map.insert(37, "c"), Some("b")); /// assert_eq!(map[&37], "c"); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn insert(&mut self, k: K, v: V) -> Option { unsafe { let hash = make_hash(&self.hash_builder, &k); @@ -854,6 +879,7 @@ where /// assert_eq!(map.remove(&1), Some("a")); /// assert_eq!(map.remove(&1), None); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn remove(&mut self, k: &Q) -> Option where K: Borrow, @@ -884,6 +910,7 @@ where /// assert_eq!(map.remove(&1), None); /// # } /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn remove_entry(&mut self, k: &Q) -> Option<(K, V)> where K: Borrow, @@ -966,6 +993,7 @@ where /// so that the map now contains keys which compare equal, search may start /// acting erratically, with two keys randomly masking each other. Implementations /// are free to assume this doesn't happen (within the limits of memory-safety). + #[cfg_attr(feature = "inline-more", inline)] pub fn raw_entry_mut(&mut self) -> RawEntryBuilderMut<'_, K, V, S> { RawEntryBuilderMut { map: self } } @@ -985,6 +1013,7 @@ where /// `get` should be preferred. /// /// Immutable raw entries have very limited use; you might instead want `raw_entry_mut`. + #[cfg_attr(feature = "inline-more", inline)] pub fn raw_entry(&self) -> RawEntryBuilder<'_, K, V, S> { RawEntryBuilder { map: self } } @@ -1030,6 +1059,7 @@ where S: BuildHasher + Default, { /// Creates an empty `HashMap`, with the `Default` value for the hasher. + #[cfg_attr(feature = "inline-more", inline)] fn default() -> Self { Self::with_hasher(Default::default()) } @@ -1048,6 +1078,7 @@ where /// # Panics /// /// Panics if the key is not present in the `HashMap`. + #[cfg_attr(feature = "inline-more", inline)] fn index(&self, key: &Q) -> &V { self.get(key).expect("no entry found for key") } @@ -1067,6 +1098,7 @@ pub struct Iter<'a, K, V> { // FIXME(#26925) Remove in favor of `#[derive(Clone)]` impl Clone for Iter<'_, K, V> { + #[cfg_attr(feature = "inline-more", inline)] fn clone(&self) -> Self { Iter { inner: self.inner.clone(), @@ -1101,6 +1133,7 @@ unsafe impl Send for IterMut<'_, K, V> {} impl IterMut<'_, K, V> { /// Returns a iterator of references over the remaining items. + #[cfg_attr(feature = "inline-more", inline)] pub(super) fn iter(&self) -> Iter<'_, K, V> { Iter { inner: self.inner.clone(), @@ -1122,6 +1155,7 @@ pub struct IntoIter { impl IntoIter { /// Returns a iterator of references over the remaining items. + #[cfg_attr(feature = "inline-more", inline)] pub(super) fn iter(&self) -> Iter<'_, K, V> { Iter { inner: self.inner.iter(), @@ -1143,6 +1177,7 @@ pub struct Keys<'a, K, V> { // FIXME(#26925) Remove in favor of `#[derive(Clone)]` impl Clone for Keys<'_, K, V> { + #[cfg_attr(feature = "inline-more", inline)] fn clone(&self) -> Self { Keys { inner: self.inner.clone(), @@ -1169,6 +1204,7 @@ pub struct Values<'a, K, V> { // FIXME(#26925) Remove in favor of `#[derive(Clone)]` impl Clone for Values<'_, K, V> { + #[cfg_attr(feature = "inline-more", inline)] fn clone(&self) -> Self { Values { inner: self.inner.clone(), @@ -1195,6 +1231,7 @@ pub struct Drain<'a, K, V> { impl Drain<'_, K, V> { /// Returns a iterator of references over the remaining items. + #[cfg_attr(feature = "inline-more", inline)] pub(super) fn iter(&self) -> Iter<'_, K, V> { Iter { inner: self.inner.iter(), @@ -1286,6 +1323,7 @@ where S: BuildHasher, { /// Creates a `RawEntryMut` from the given key. + #[cfg_attr(feature = "inline-more", inline)] #[allow(clippy::wrong_self_convention)] pub fn from_key(self, k: &Q) -> RawEntryMut<'a, K, V, S> where @@ -1314,6 +1352,7 @@ where S: BuildHasher, { /// Creates a `RawEntryMut` from the given hash. + #[cfg_attr(feature = "inline-more", inline)] #[allow(clippy::wrong_self_convention)] pub fn from_hash(self, hash: u64, is_match: F) -> RawEntryMut<'a, K, V, S> where @@ -1322,6 +1361,7 @@ where self.search(hash, is_match) } + #[cfg_attr(feature = "inline-more", inline)] fn search(self, hash: u64, mut is_match: F) -> RawEntryMut<'a, K, V, S> where for<'b> F: FnMut(&'b K) -> bool, @@ -1344,6 +1384,7 @@ where S: BuildHasher, { /// Access an entry by key. + #[cfg_attr(feature = "inline-more", inline)] #[allow(clippy::wrong_self_convention)] pub fn from_key(self, k: &Q) -> Option<(&'a K, &'a V)> where @@ -1356,6 +1397,7 @@ where } /// Access an entry by a key and its hash. + #[cfg_attr(feature = "inline-more", inline)] #[allow(clippy::wrong_self_convention)] pub fn from_key_hashed_nocheck(self, hash: u64, k: &Q) -> Option<(&'a K, &'a V)> where @@ -1365,6 +1407,7 @@ where self.from_hash(hash, |q| q.borrow().eq(k)) } + #[cfg_attr(feature = "inline-more", inline)] fn search(self, hash: u64, mut is_match: F) -> Option<(&'a K, &'a V)> where F: FnMut(&K) -> bool, @@ -1379,6 +1422,7 @@ where } /// Access an entry by hash. + #[cfg_attr(feature = "inline-more", inline)] #[allow(clippy::wrong_self_convention)] pub fn from_hash(self, hash: u64, is_match: F) -> Option<(&'a K, &'a V)> where @@ -1401,7 +1445,7 @@ impl<'a, K, V, S> RawEntryMut<'a, K, V, S> { /// /// assert_eq!(entry.remove_entry(), ("horseyland", 37)); /// ``` - #[inline] + #[cfg_attr(feature = "inline-more", inline)] pub fn insert(self, key: K, value: V) -> RawOccupiedEntryMut<'a, K, V> where K: Hash, @@ -1432,6 +1476,7 @@ impl<'a, K, V, S> RawEntryMut<'a, K, V, S> { /// *map.raw_entry_mut().from_key("poneyland").or_insert("poneyland", 10).1 *= 2; /// assert_eq!(map["poneyland"], 6); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn or_insert(self, default_key: K, default_val: V) -> (&'a mut K, &'a mut V) where K: Hash, @@ -1459,6 +1504,7 @@ impl<'a, K, V, S> RawEntryMut<'a, K, V, S> { /// /// assert_eq!(map["poneyland"], "hoho".to_string()); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn or_insert_with(self, default: F) -> (&'a mut K, &'a mut V) where F: FnOnce() -> (K, V), @@ -1496,6 +1542,7 @@ impl<'a, K, V, S> RawEntryMut<'a, K, V, S> { /// .or_insert("poneyland", 0); /// assert_eq!(map["poneyland"], 43); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn and_modify(self, f: F) -> Self where F: FnOnce(&mut K, &mut V), @@ -1515,38 +1562,45 @@ impl<'a, K, V, S> RawEntryMut<'a, K, V, S> { impl<'a, K, V> RawOccupiedEntryMut<'a, K, V> { /// Gets a reference to the key in the entry. + #[cfg_attr(feature = "inline-more", inline)] pub fn key(&self) -> &K { unsafe { &self.elem.as_ref().0 } } /// Gets a mutable reference to the key in the entry. + #[cfg_attr(feature = "inline-more", inline)] pub fn key_mut(&mut self) -> &mut K { unsafe { &mut self.elem.as_mut().0 } } /// Converts the entry into a mutable reference to the key in the entry /// with a lifetime bound to the map itself. + #[cfg_attr(feature = "inline-more", inline)] pub fn into_key(self) -> &'a mut K { unsafe { &mut self.elem.as_mut().0 } } /// Gets a reference to the value in the entry. + #[cfg_attr(feature = "inline-more", inline)] pub fn get(&self) -> &V { unsafe { &self.elem.as_ref().1 } } /// Converts the OccupiedEntry into a mutable reference to the value in the entry /// with a lifetime bound to the map itself. + #[cfg_attr(feature = "inline-more", inline)] pub fn into_mut(self) -> &'a mut V { unsafe { &mut self.elem.as_mut().1 } } /// Gets a mutable reference to the value in the entry. + #[cfg_attr(feature = "inline-more", inline)] pub fn get_mut(&mut self) -> &mut V { unsafe { &mut self.elem.as_mut().1 } } /// Gets a reference to the key and value in the entry. + #[cfg_attr(feature = "inline-more", inline)] pub fn get_key_value(&mut self) -> (&K, &V) { unsafe { let &(ref key, ref value) = self.elem.as_ref(); @@ -1555,6 +1609,7 @@ impl<'a, K, V> RawOccupiedEntryMut<'a, K, V> { } /// Gets a mutable reference to the key and value in the entry. + #[cfg_attr(feature = "inline-more", inline)] pub fn get_key_value_mut(&mut self) -> (&mut K, &mut V) { unsafe { let &mut (ref mut key, ref mut value) = self.elem.as_mut(); @@ -1564,6 +1619,7 @@ impl<'a, K, V> RawOccupiedEntryMut<'a, K, V> { /// Converts the OccupiedEntry into a mutable reference to the key and value in the entry /// with a lifetime bound to the map itself. + #[cfg_attr(feature = "inline-more", inline)] pub fn into_key_value(self) -> (&'a mut K, &'a mut V) { unsafe { let &mut (ref mut key, ref mut value) = self.elem.as_mut(); @@ -1572,21 +1628,25 @@ impl<'a, K, V> RawOccupiedEntryMut<'a, K, V> { } /// Sets the value of the entry, and returns the entry's old value. + #[cfg_attr(feature = "inline-more", inline)] pub fn insert(&mut self, value: V) -> V { mem::replace(self.get_mut(), value) } /// Sets the value of the entry, and returns the entry's old value. + #[cfg_attr(feature = "inline-more", inline)] pub fn insert_key(&mut self, key: K) -> K { mem::replace(self.key_mut(), key) } /// Takes the value out of the entry, and returns it. + #[cfg_attr(feature = "inline-more", inline)] pub fn remove(self) -> V { self.remove_entry().1 } /// Take the ownership of the key and value from the map. + #[cfg_attr(feature = "inline-more", inline)] pub fn remove_entry(self) -> (K, V) { unsafe { self.table.erase_no_drop(&self.elem); @@ -1598,6 +1658,7 @@ impl<'a, K, V> RawOccupiedEntryMut<'a, K, V> { impl<'a, K, V, S> RawVacantEntryMut<'a, K, V, S> { /// Sets the value of the entry with the VacantEntry's key, /// and returns a mutable reference to it. + #[cfg_attr(feature = "inline-more", inline)] pub fn insert(self, key: K, value: V) -> (&'a mut K, &'a mut V) where K: Hash, @@ -1610,6 +1671,7 @@ impl<'a, K, V, S> RawVacantEntryMut<'a, K, V, S> { /// Sets the value of the entry with the VacantEntry's key, /// and returns a mutable reference to it. + #[cfg_attr(feature = "inline-more", inline)] #[allow(clippy::shadow_unrelated)] pub fn insert_hashed_nocheck(self, hash: u64, key: K, value: V) -> (&'a mut K, &'a mut V) where @@ -1621,6 +1683,7 @@ impl<'a, K, V, S> RawVacantEntryMut<'a, K, V, S> { } /// Set the value of an entry with a custom hasher function. + #[cfg_attr(feature = "inline-more", inline)] pub fn insert_with_hasher( self, hash: u64, @@ -1639,7 +1702,7 @@ impl<'a, K, V, S> RawVacantEntryMut<'a, K, V, S> { } } - #[inline] + #[cfg_attr(feature = "inline-more", inline)] fn insert_entry(self, key: K, value: V) -> RawOccupiedEntryMut<'a, K, V> where K: Hash, @@ -1772,6 +1835,7 @@ impl<'a, K, V, S> IntoIterator for &'a HashMap { type Item = (&'a K, &'a V); type IntoIter = Iter<'a, K, V>; + #[cfg_attr(feature = "inline-more", inline)] fn into_iter(self) -> Iter<'a, K, V> { self.iter() } @@ -1781,6 +1845,7 @@ impl<'a, K, V, S> IntoIterator for &'a mut HashMap { type Item = (&'a K, &'a mut V); type IntoIter = IterMut<'a, K, V>; + #[cfg_attr(feature = "inline-more", inline)] fn into_iter(self) -> IterMut<'a, K, V> { self.iter_mut() } @@ -1807,6 +1872,7 @@ impl IntoIterator for HashMap { /// // Not possible with .iter() /// let vec: Vec<(&str, i32)> = map.into_iter().collect(); /// ``` + #[cfg_attr(feature = "inline-more", inline)] fn into_iter(self) -> IntoIter { IntoIter { inner: self.table.into_iter(), @@ -1817,17 +1883,20 @@ impl IntoIterator for HashMap { impl<'a, K, V> Iterator for Iter<'a, K, V> { type Item = (&'a K, &'a V); + #[cfg_attr(feature = "inline-more", inline)] fn next(&mut self) -> Option<(&'a K, &'a V)> { self.inner.next().map(|x| unsafe { let r = x.as_ref(); (&r.0, &r.1) }) } + #[cfg_attr(feature = "inline-more", inline)] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } } impl ExactSizeIterator for Iter<'_, K, V> { + #[cfg_attr(feature = "inline-more", inline)] fn len(&self) -> usize { self.inner.len() } @@ -1838,17 +1907,20 @@ impl FusedIterator for Iter<'_, K, V> {} impl<'a, K, V> Iterator for IterMut<'a, K, V> { type Item = (&'a K, &'a mut V); + #[cfg_attr(feature = "inline-more", inline)] fn next(&mut self) -> Option<(&'a K, &'a mut V)> { self.inner.next().map(|x| unsafe { let r = x.as_mut(); (&r.0, &mut r.1) }) } + #[cfg_attr(feature = "inline-more", inline)] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } } impl ExactSizeIterator for IterMut<'_, K, V> { + #[cfg_attr(feature = "inline-more", inline)] fn len(&self) -> usize { self.inner.len() } @@ -1868,14 +1940,17 @@ where impl Iterator for IntoIter { type Item = (K, V); + #[cfg_attr(feature = "inline-more", inline)] fn next(&mut self) -> Option<(K, V)> { self.inner.next() } + #[cfg_attr(feature = "inline-more", inline)] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } } impl ExactSizeIterator for IntoIter { + #[cfg_attr(feature = "inline-more", inline)] fn len(&self) -> usize { self.inner.len() } @@ -1891,14 +1966,17 @@ impl fmt::Debug for IntoIter { impl<'a, K, V> Iterator for Keys<'a, K, V> { type Item = &'a K; + #[cfg_attr(feature = "inline-more", inline)] fn next(&mut self) -> Option<(&'a K)> { self.inner.next().map(|(k, _)| k) } + #[cfg_attr(feature = "inline-more", inline)] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } } impl ExactSizeIterator for Keys<'_, K, V> { + #[cfg_attr(feature = "inline-more", inline)] fn len(&self) -> usize { self.inner.len() } @@ -1908,14 +1986,17 @@ impl FusedIterator for Keys<'_, K, V> {} impl<'a, K, V> Iterator for Values<'a, K, V> { type Item = &'a V; + #[cfg_attr(feature = "inline-more", inline)] fn next(&mut self) -> Option<(&'a V)> { self.inner.next().map(|(_, v)| v) } + #[cfg_attr(feature = "inline-more", inline)] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } } impl ExactSizeIterator for Values<'_, K, V> { + #[cfg_attr(feature = "inline-more", inline)] fn len(&self) -> usize { self.inner.len() } @@ -1925,14 +2006,17 @@ impl FusedIterator for Values<'_, K, V> {} impl<'a, K, V> Iterator for ValuesMut<'a, K, V> { type Item = &'a mut V; + #[cfg_attr(feature = "inline-more", inline)] fn next(&mut self) -> Option<(&'a mut V)> { self.inner.next().map(|(_, v)| v) } + #[cfg_attr(feature = "inline-more", inline)] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } } impl ExactSizeIterator for ValuesMut<'_, K, V> { + #[cfg_attr(feature = "inline-more", inline)] fn len(&self) -> usize { self.inner.len() } @@ -1952,14 +2036,17 @@ where impl<'a, K, V> Iterator for Drain<'a, K, V> { type Item = (K, V); + #[cfg_attr(feature = "inline-more", inline)] fn next(&mut self) -> Option<(K, V)> { self.inner.next() } + #[cfg_attr(feature = "inline-more", inline)] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } } impl ExactSizeIterator for Drain<'_, K, V> { + #[cfg_attr(feature = "inline-more", inline)] fn len(&self) -> usize { self.inner.len() } @@ -1989,7 +2076,7 @@ impl<'a, K, V, S> Entry<'a, K, V, S> { /// /// assert_eq!(entry.key(), &"horseyland"); /// ``` - #[inline] + #[cfg_attr(feature = "inline-more", inline)] pub fn insert(self, value: V) -> OccupiedEntry<'a, K, V, S> where K: Hash, @@ -2020,6 +2107,7 @@ impl<'a, K, V, S> Entry<'a, K, V, S> { /// *map.entry("poneyland").or_insert(10) *= 2; /// assert_eq!(map["poneyland"], 6); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn or_insert(self, default: V) -> &'a mut V where K: Hash, @@ -2046,6 +2134,7 @@ impl<'a, K, V, S> Entry<'a, K, V, S> { /// /// assert_eq!(map["poneyland"], "hoho".to_string()); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn or_insert_with V>(self, default: F) -> &'a mut V where K: Hash, @@ -2067,6 +2156,7 @@ impl<'a, K, V, S> Entry<'a, K, V, S> { /// let mut map: HashMap<&str, u32> = HashMap::new(); /// assert_eq!(map.entry("poneyland").key(), &"poneyland"); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn key(&self) -> &K { match *self { Entry::Occupied(ref entry) => entry.key(), @@ -2094,6 +2184,7 @@ impl<'a, K, V, S> Entry<'a, K, V, S> { /// .or_insert(42); /// assert_eq!(map["poneyland"], 43); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn and_modify(self, f: F) -> Self where F: FnOnce(&mut V), @@ -2124,6 +2215,7 @@ impl<'a, K, V: Default, S> Entry<'a, K, V, S> { /// assert_eq!(map["poneyland"], None); /// # } /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn or_default(self) -> &'a mut V where K: Hash, @@ -2148,6 +2240,7 @@ impl<'a, K, V, S> OccupiedEntry<'a, K, V, S> { /// map.entry("poneyland").or_insert(12); /// assert_eq!(map.entry("poneyland").key(), &"poneyland"); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn key(&self) -> &K { unsafe { &self.elem.as_ref().0 } } @@ -2170,6 +2263,7 @@ impl<'a, K, V, S> OccupiedEntry<'a, K, V, S> { /// /// assert_eq!(map.contains_key("poneyland"), false); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn remove_entry(self) -> (K, V) { unsafe { self.table.table.erase_no_drop(&self.elem); @@ -2192,6 +2286,7 @@ impl<'a, K, V, S> OccupiedEntry<'a, K, V, S> { /// assert_eq!(o.get(), &12); /// } /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn get(&self) -> &V { unsafe { &self.elem.as_ref().1 } } @@ -2223,6 +2318,7 @@ impl<'a, K, V, S> OccupiedEntry<'a, K, V, S> { /// /// assert_eq!(map["poneyland"], 24); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn get_mut(&mut self) -> &mut V { unsafe { &mut self.elem.as_mut().1 } } @@ -2250,6 +2346,7 @@ impl<'a, K, V, S> OccupiedEntry<'a, K, V, S> { /// /// assert_eq!(map["poneyland"], 22); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn into_mut(self) -> &'a mut V { unsafe { &mut self.elem.as_mut().1 } } @@ -2271,6 +2368,7 @@ impl<'a, K, V, S> OccupiedEntry<'a, K, V, S> { /// /// assert_eq!(map["poneyland"], 15); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn insert(&mut self, mut value: V) -> V { let old_value = self.get_mut(); mem::swap(&mut value, old_value); @@ -2294,6 +2392,7 @@ impl<'a, K, V, S> OccupiedEntry<'a, K, V, S> { /// /// assert_eq!(map.contains_key("poneyland"), false); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn remove(self) -> V { self.remove_entry().1 } @@ -2318,6 +2417,7 @@ impl<'a, K, V, S> OccupiedEntry<'a, K, V, S> { /// } /// /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn replace_entry(self, value: V) -> (K, V) { let entry = unsafe { self.elem.as_mut() }; @@ -2351,6 +2451,7 @@ impl<'a, K, V, S> OccupiedEntry<'a, K, V, S> { /// } /// } /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn replace_key(self) -> K { let entry = unsafe { self.elem.as_mut() }; mem::replace(&mut entry.0, self.key.unwrap()) @@ -2369,6 +2470,7 @@ impl<'a, K, V, S> VacantEntry<'a, K, V, S> { /// let mut map: HashMap<&str, u32> = HashMap::new(); /// assert_eq!(map.entry("poneyland").key(), &"poneyland"); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn key(&self) -> &K { &self.key } @@ -2387,6 +2489,7 @@ impl<'a, K, V, S> VacantEntry<'a, K, V, S> { /// v.into_key(); /// } /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn into_key(self) -> K { self.key } @@ -2407,6 +2510,7 @@ impl<'a, K, V, S> VacantEntry<'a, K, V, S> { /// } /// assert_eq!(map["poneyland"], 37); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn insert(self, value: V) -> &'a mut V where K: Hash, @@ -2419,7 +2523,7 @@ impl<'a, K, V, S> VacantEntry<'a, K, V, S> { unsafe { &mut bucket.as_mut().1 } } - #[inline] + #[cfg_attr(feature = "inline-more", inline)] fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V, S> where K: Hash, @@ -2442,6 +2546,7 @@ where K: Eq + Hash, S: BuildHasher + Default, { + #[cfg_attr(feature = "inline-more", inline)] fn from_iter>(iter: T) -> Self { let iter = iter.into_iter(); let mut map = Self::with_capacity_and_hasher(iter.size_hint().0, S::default()); @@ -2457,6 +2562,7 @@ where K: Eq + Hash, S: BuildHasher, { + #[cfg_attr(feature = "inline-more", inline)] fn extend>(&mut self, iter: T) { // Keys may be already present or show multiple times in the iterator. // Reserve the entire hint lower bound if the map is empty. @@ -2481,6 +2587,7 @@ where V: Copy, S: BuildHasher, { + #[cfg_attr(feature = "inline-more", inline)] fn extend>(&mut self, iter: T) { self.extend(iter.into_iter().map(|(&key, &value)| (key, value))); } diff --git a/src/raw/generic.rs b/src/raw/generic.rs index 329e12f197..0e00159d59 100644 --- a/src/raw/generic.rs +++ b/src/raw/generic.rs @@ -55,6 +55,7 @@ impl Group { /// a static variable to ensure the address is consistent across dylibs. /// /// This is guaranteed to be aligned to the group size. + #[inline] pub fn static_empty() -> &'static [u8] { union AlignedBytes { _align: Group, diff --git a/src/raw/mod.rs b/src/raw/mod.rs index 10ec4f160c..052f950796 100644 --- a/src/raw/mod.rs +++ b/src/raw/mod.rs @@ -26,6 +26,7 @@ cfg_if! { mod sse2; use sse2 as imp; } else { + #[path = "generic.rs"] mod generic; use generic as imp; } @@ -52,10 +53,12 @@ fn unlikely(b: bool) -> bool { } #[cfg(feature = "nightly")] +#[cfg_attr(feature = "inline-more", inline)] unsafe fn offset_from(to: *const T, from: *const T) -> usize { to.offset_from(from) as usize } #[cfg(not(feature = "nightly"))] +#[cfg_attr(feature = "inline-more", inline)] unsafe fn offset_from(to: *const T, from: *const T) -> usize { (to as usize - from as usize) / mem::size_of::() } @@ -69,6 +72,7 @@ enum Fallibility { impl Fallibility { /// Error to return on capacity overflow. + #[cfg_attr(feature = "inline-more", inline)] fn capacity_overflow(self) -> CollectionAllocErr { use Fallibility::*; match self { @@ -78,6 +82,7 @@ impl Fallibility { } /// Error to return on allocation error. + #[cfg_attr(feature = "inline-more", inline)] fn alloc_err(self, layout: Layout) -> CollectionAllocErr { use Fallibility::*; match self { @@ -170,6 +175,7 @@ impl Iterator for ProbeSeq { /// taking the maximum load factor into account. /// /// Returns `None` if an overflow occurs. +#[cfg_attr(feature = "inline-more", inline)] // Workaround for emscripten bug emscripten-core/emscripten-fastcomp#258 #[cfg_attr(target_os = "emscripten", inline(never))] fn capacity_to_buckets(cap: usize) -> Option { @@ -192,6 +198,7 @@ fn capacity_to_buckets(cap: usize) -> Option { /// Returns the maximum effective capacity for the given bucket mask, taking /// the maximum load factor into account. +#[cfg_attr(feature = "inline-more", inline)] fn bucket_mask_to_capacity(bucket_mask: usize) -> usize { if bucket_mask < 8 { // For tables with 1/2/4/8 buckets, we always reserve one empty slot. @@ -207,6 +214,7 @@ fn bucket_mask_to_capacity(bucket_mask: usize) -> usize { // and the offset of the buckets in the allocation. /// /// Returns `None` if an overflow occurs. +#[cfg_attr(feature = "inline-more", inline)] #[cfg(feature = "nightly")] fn calculate_layout(buckets: usize) -> Option<(Layout, usize)> { debug_assert!(buckets.is_power_of_two()); @@ -229,6 +237,7 @@ fn calculate_layout(buckets: usize) -> Option<(Layout, usize)> { // Returns a Layout which describes the allocation required for a hash table, // and the offset of the buckets in the allocation. +#[cfg_attr(feature = "inline-more", inline)] #[cfg(not(feature = "nightly"))] fn calculate_layout(buckets: usize) -> Option<(Layout, usize)> { debug_assert!(buckets.is_power_of_two()); @@ -259,12 +268,14 @@ pub struct Bucket { unsafe impl Send for Bucket {} impl Clone for Bucket { + #[cfg_attr(feature = "inline-more", inline)] fn clone(&self) -> Self { Self { ptr: self.ptr } } } impl Bucket { + #[cfg_attr(feature = "inline-more", inline)] unsafe fn from_base_index(base: *const T, index: usize) -> Self { let ptr = if mem::size_of::() == 0 { index as *const T @@ -273,6 +284,7 @@ impl Bucket { }; Self { ptr } } + #[cfg_attr(feature = "inline-more", inline)] pub unsafe fn as_ptr(&self) -> *mut T { if mem::size_of::() == 0 { // Just return an arbitrary ZST pointer which is properly aligned @@ -281,6 +293,7 @@ impl Bucket { self.ptr as *mut T } } + #[cfg_attr(feature = "inline-more", inline)] unsafe fn add(&self, offset: usize) -> Self { let ptr = if mem::size_of::() == 0 { (self.ptr as usize + offset) as *const T @@ -289,21 +302,27 @@ impl Bucket { }; Self { ptr } } + #[cfg_attr(feature = "inline-more", inline)] pub unsafe fn drop(&self) { self.as_ptr().drop_in_place(); } + #[cfg_attr(feature = "inline-more", inline)] pub unsafe fn read(&self) -> T { self.as_ptr().read() } + #[cfg_attr(feature = "inline-more", inline)] pub unsafe fn write(&self, val: T) { self.as_ptr().write(val); } + #[cfg_attr(feature = "inline-more", inline)] pub unsafe fn as_ref<'a>(&self) -> &'a T { &*self.as_ptr() } + #[cfg_attr(feature = "inline-more", inline)] pub unsafe fn as_mut<'a>(&self) -> &'a mut T { &mut *self.as_ptr() } + #[cfg_attr(feature = "inline-more", inline)] pub unsafe fn copy_from_nonoverlapping(&self, other: &Self) { self.as_ptr().copy_from_nonoverlapping(other.as_ptr(), 1); } @@ -337,6 +356,7 @@ impl RawTable { /// In effect this returns a table with exactly 1 bucket. However we can /// leave the data pointer dangling since that bucket is never written to /// due to our load factor forcing us to always have at least 1 free bucket. + #[cfg_attr(feature = "inline-more", inline)] pub fn new() -> Self { Self { data: NonNull::dangling(), @@ -352,6 +372,7 @@ impl RawTable { /// Allocates a new hash table with the given number of buckets. /// /// The control bytes are left uninitialized. + #[cfg_attr(feature = "inline-more", inline)] unsafe fn new_uninitialized( buckets: usize, fallability: Fallibility, @@ -399,6 +420,7 @@ impl RawTable { } /// Deallocates the table without dropping any entries. + #[cfg_attr(feature = "inline-more", inline)] unsafe fn free_buckets(&mut self) { let (layout, _) = calculate_layout::(self.buckets()).unwrap_or_else(|| hint::unreachable_unchecked()); @@ -406,6 +428,7 @@ impl RawTable { } /// Returns the index of a bucket from a `Bucket`. + #[cfg_attr(feature = "inline-more", inline)] unsafe fn bucket_index(&self, bucket: &Bucket) -> usize { if mem::size_of::() == 0 { bucket.ptr as usize @@ -415,12 +438,14 @@ impl RawTable { } /// Returns a pointer to a control byte. + #[cfg_attr(feature = "inline-more", inline)] unsafe fn ctrl(&self, index: usize) -> *mut u8 { debug_assert!(index < self.num_ctrl_bytes()); self.ctrl.as_ptr().add(index) } /// Returns a pointer to an element in the table. + #[cfg_attr(feature = "inline-more", inline)] pub unsafe fn bucket(&self, index: usize) -> Bucket { debug_assert_ne!(self.bucket_mask, 0); debug_assert!(index < self.buckets()); @@ -428,6 +453,7 @@ impl RawTable { } /// Erases an element from the table without dropping it. + #[cfg_attr(feature = "inline-more", inline)] pub unsafe fn erase_no_drop(&mut self, item: &Bucket) { let index = self.bucket_index(item); debug_assert!(is_full(*self.ctrl(index))); @@ -458,6 +484,7 @@ impl RawTable { /// This iterator never terminates, but is guaranteed to visit each bucket /// group exactly once. The loop using `probe_seq` must terminate upon /// reaching a group containing an empty bucket. + #[cfg_attr(feature = "inline-more", inline)] fn probe_seq(&self, hash: u64) -> ProbeSeq { ProbeSeq { bucket_mask: self.bucket_mask, @@ -468,6 +495,7 @@ impl RawTable { /// Sets a control byte, and possibly also the replicated control byte at /// the end of the array. + #[cfg_attr(feature = "inline-more", inline)] unsafe fn set_ctrl(&self, index: usize, ctrl: u8) { // Replicate the first Group::WIDTH control bytes at the end of // the array without using a branch: @@ -497,6 +525,7 @@ impl RawTable { /// a new element. /// /// There must be at least 1 empty bucket in the table. + #[cfg_attr(feature = "inline-more", inline)] fn find_insert_slot(&self, hash: u64) -> usize { for pos in self.probe_seq(hash) { unsafe { @@ -531,6 +560,7 @@ impl RawTable { } /// Marks all table buckets as empty without dropping their contents. + #[cfg_attr(feature = "inline-more", inline)] pub fn clear_no_drop(&mut self) { if !self.is_empty_singleton() { unsafe { @@ -542,6 +572,7 @@ impl RawTable { } /// Removes all elements from the table without freeing the backing memory. + #[cfg_attr(feature = "inline-more", inline)] pub fn clear(&mut self) { // Ensure that the table is reset even if one of the drops panic let self_ = guard(self, |self_| self_.clear_no_drop()); @@ -556,6 +587,7 @@ impl RawTable { } /// Shrinks the table to fit `max(self.len(), min_size)` elements. + #[cfg_attr(feature = "inline-more", inline)] pub fn shrink_to(&mut self, min_size: usize, hasher: impl Fn(&T) -> u64) { // Calculate the minimal number of elements that we need to reserve // space for. @@ -588,6 +620,7 @@ impl RawTable { /// Ensures that at least `additional` items can be inserted into the table /// without reallocation. + #[cfg_attr(feature = "inline-more", inline)] pub fn reserve(&mut self, additional: usize, hasher: impl Fn(&T) -> u64) { if additional > self.growth_left { self.reserve_rehash(additional, hasher, Fallibility::Infallible) @@ -597,6 +630,7 @@ impl RawTable { /// Tries to ensure that at least `additional` items can be inserted into /// the table without reallocation. + #[cfg_attr(feature = "inline-more", inline)] pub fn try_reserve( &mut self, additional: usize, @@ -794,6 +828,7 @@ impl RawTable { /// Inserts a new element into the table. /// /// This does not check if the given element already exists in the table. + #[cfg_attr(feature = "inline-more", inline)] pub fn insert(&mut self, hash: u64, value: T, hasher: impl Fn(&T) -> u64) -> Bucket { unsafe { let mut index = self.find_insert_slot(hash); @@ -821,6 +856,7 @@ impl RawTable { /// There must be enough space in the table to insert the new element. /// /// This does not check if the given element already exists in the table. + #[cfg_attr(feature = "inline-more", inline)] #[cfg(feature = "rustc-internal-api")] pub fn insert_no_grow(&mut self, hash: u64, value: T) -> Bucket { unsafe { @@ -866,27 +902,32 @@ impl RawTable { /// /// This number is a lower bound; the table might be able to hold /// more, but is guaranteed to be able to hold at least this many. + #[cfg_attr(feature = "inline-more", inline)] pub fn capacity(&self) -> usize { self.items + self.growth_left } /// Returns the number of elements in the table. + #[cfg_attr(feature = "inline-more", inline)] pub fn len(&self) -> usize { self.items } /// Returns the number of buckets in the table. + #[cfg_attr(feature = "inline-more", inline)] pub fn buckets(&self) -> usize { self.bucket_mask + 1 } /// Returns the number of control bytes in the table. + #[cfg_attr(feature = "inline-more", inline)] fn num_ctrl_bytes(&self) -> usize { self.bucket_mask + 1 + Group::WIDTH } /// Returns whether this table points to the empty singleton with a capacity /// of 0. + #[cfg_attr(feature = "inline-more", inline)] fn is_empty_singleton(&self) -> bool { self.bucket_mask == 0 } @@ -895,6 +936,7 @@ impl RawTable { /// the caller to ensure that the `RawTable` outlives the `RawIter`. /// Because we cannot make the `next` method unsafe on the `RawIter` /// struct, we have to make the `iter` method unsafe. + #[cfg_attr(feature = "inline-more", inline)] pub unsafe fn iter(&self) -> RawIter { let data = Bucket::from_base_index(self.data.as_ptr(), 0); RawIter { @@ -907,6 +949,7 @@ impl RawTable { /// freeing the memory. It is up to the caller to ensure that the `RawTable` /// outlives the `RawDrain`. Because we cannot make the `next` method unsafe /// on the `RawDrain`, we have to make the `drain` method unsafe. + #[cfg_attr(feature = "inline-more", inline)] pub unsafe fn drain(&mut self) -> RawDrain<'_, T> { RawDrain { iter: self.iter(), @@ -918,6 +961,7 @@ impl RawTable { /// Converts the table into a raw allocation. The contents of the table /// should be dropped using a `RawIter` before freeing the allocation. + #[cfg_attr(feature = "inline-more", inline)] pub(crate) fn into_alloc(self) -> Option<(NonNull, Layout)> { let alloc = if self.is_empty_singleton() { None @@ -988,6 +1032,7 @@ impl Clone for RawTable { #[cfg(feature = "nightly")] unsafe impl<#[may_dangle] T> Drop for RawTable { + #[cfg_attr(feature = "inline-more", inline)] fn drop(&mut self) { if !self.is_empty_singleton() { unsafe { @@ -1003,6 +1048,7 @@ unsafe impl<#[may_dangle] T> Drop for RawTable { } #[cfg(not(feature = "nightly"))] impl Drop for RawTable { + #[cfg_attr(feature = "inline-more", inline)] fn drop(&mut self) { if !self.is_empty_singleton() { unsafe { @@ -1021,6 +1067,7 @@ impl IntoIterator for RawTable { type Item = T; type IntoIter = RawIntoIter; + #[cfg_attr(feature = "inline-more", inline)] fn into_iter(self) -> RawIntoIter { unsafe { let iter = self.iter(); @@ -1056,6 +1103,7 @@ impl RawIterRange { /// Returns a `RawIterRange` covering a subset of a table. /// /// The control byte address must be aligned to the group size. + #[cfg_attr(feature = "inline-more", inline)] unsafe fn new(ctrl: *const u8, data: Bucket, len: usize) -> Self { debug_assert_ne!(len, 0); debug_assert_eq!(ctrl as usize % Group::WIDTH, 0); @@ -1077,6 +1125,7 @@ impl RawIterRange { /// /// Returns `None` if the remaining range is smaller than or equal to the /// group width. + #[cfg_attr(feature = "inline-more", inline)] #[cfg(feature = "rayon")] pub(crate) fn split(mut self) -> (Self, Option>) { unsafe { @@ -1120,6 +1169,7 @@ unsafe impl Send for RawIterRange {} unsafe impl Sync for RawIterRange {} impl Clone for RawIterRange { + #[cfg_attr(feature = "inline-more", inline)] fn clone(&self) -> Self { Self { data: self.data.clone(), @@ -1133,6 +1183,7 @@ impl Clone for RawIterRange { impl Iterator for RawIterRange { type Item = Bucket; + #[cfg_attr(feature = "inline-more", inline)] fn next(&mut self) -> Option> { unsafe { loop { @@ -1157,6 +1208,7 @@ impl Iterator for RawIterRange { } } + #[cfg_attr(feature = "inline-more", inline)] fn size_hint(&self) -> (usize, Option) { // We don't have an item count, so just guess based on the range size. ( @@ -1175,6 +1227,7 @@ pub struct RawIter { } impl Clone for RawIter { + #[cfg_attr(feature = "inline-more", inline)] fn clone(&self) -> Self { Self { iter: self.iter.clone(), @@ -1186,6 +1239,7 @@ impl Clone for RawIter { impl Iterator for RawIter { type Item = Bucket; + #[cfg_attr(feature = "inline-more", inline)] fn next(&mut self) -> Option> { if let Some(b) = self.iter.next() { self.items -= 1; @@ -1199,6 +1253,7 @@ impl Iterator for RawIter { } } + #[cfg_attr(feature = "inline-more", inline)] fn size_hint(&self) -> (usize, Option) { (self.items, Some(self.items)) } @@ -1215,6 +1270,7 @@ pub struct RawIntoIter { } impl RawIntoIter { + #[cfg_attr(feature = "inline-more", inline)] pub fn iter(&self) -> RawIter { self.iter.clone() } @@ -1225,6 +1281,7 @@ unsafe impl Sync for RawIntoIter where T: Sync {} #[cfg(feature = "nightly")] unsafe impl<#[may_dangle] T> Drop for RawIntoIter { + #[cfg_attr(feature = "inline-more", inline)] fn drop(&mut self) { unsafe { // Drop all remaining elements @@ -1243,6 +1300,7 @@ unsafe impl<#[may_dangle] T> Drop for RawIntoIter { } #[cfg(not(feature = "nightly"))] impl Drop for RawIntoIter { + #[cfg_attr(feature = "inline-more", inline)] fn drop(&mut self) { unsafe { // Drop all remaining elements @@ -1263,10 +1321,12 @@ impl Drop for RawIntoIter { impl Iterator for RawIntoIter { type Item = T; + #[cfg_attr(feature = "inline-more", inline)] fn next(&mut self) -> Option { unsafe { Some(self.iter.next()?.read()) } } + #[cfg_attr(feature = "inline-more", inline)] fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } @@ -1291,6 +1351,7 @@ pub struct RawDrain<'a, T> { } impl RawDrain<'_, T> { + #[cfg_attr(feature = "inline-more", inline)] pub fn iter(&self) -> RawIter { self.iter.clone() } @@ -1300,6 +1361,7 @@ unsafe impl Send for RawDrain<'_, T> where T: Send {} unsafe impl Sync for RawDrain<'_, T> where T: Sync {} impl Drop for RawDrain<'_, T> { + #[cfg_attr(feature = "inline-more", inline)] fn drop(&mut self) { unsafe { // Drop all remaining elements. Note that this may panic. @@ -1324,6 +1386,7 @@ impl Drop for RawDrain<'_, T> { impl Iterator for RawDrain<'_, T> { type Item = T; + #[cfg_attr(feature = "inline-more", inline)] fn next(&mut self) -> Option { unsafe { let item = self.iter.next()?; @@ -1331,6 +1394,7 @@ impl Iterator for RawDrain<'_, T> { } } + #[cfg_attr(feature = "inline-more", inline)] fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } diff --git a/src/rustc_entry.rs b/src/rustc_entry.rs index 1ab88ef90f..39dc51aa27 100644 --- a/src/rustc_entry.rs +++ b/src/rustc_entry.rs @@ -29,6 +29,7 @@ where /// assert_eq!(letters[&'u'], 1); /// assert_eq!(letters.get(&'y'), None); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn rustc_entry(&mut self, key: K) -> RustcEntry<'_, K, V> { let hash = make_hash(&self.hash_builder, &key); if let Some(elem) = self.table.find(hash, |q| q.0.eq(&key)) { @@ -162,6 +163,7 @@ impl<'a, K, V> RustcEntry<'a, K, V> { /// *map.rustc_entry("poneyland").or_insert(10) *= 2; /// assert_eq!(map["poneyland"], 6); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn or_insert(self, default: V) -> &'a mut V where K: Hash, @@ -187,6 +189,7 @@ impl<'a, K, V> RustcEntry<'a, K, V> { /// /// assert_eq!(map["poneyland"], "hoho".to_string()); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn or_insert_with V>(self, default: F) -> &'a mut V where K: Hash, @@ -207,6 +210,7 @@ impl<'a, K, V> RustcEntry<'a, K, V> { /// let mut map: HashMap<&str, u32> = HashMap::new(); /// assert_eq!(map.rustc_entry("poneyland").key(), &"poneyland"); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn key(&self) -> &K { match *self { Occupied(ref entry) => entry.key(), @@ -234,6 +238,7 @@ impl<'a, K, V> RustcEntry<'a, K, V> { /// .or_insert(42); /// assert_eq!(map["poneyland"], 43); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn and_modify(self, f: F) -> Self where F: FnOnce(&mut V), @@ -264,6 +269,7 @@ impl<'a, K, V: Default> RustcEntry<'a, K, V> { /// assert_eq!(map["poneyland"], None); /// # } /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn or_default(self) -> &'a mut V where K: Hash, @@ -287,6 +293,7 @@ impl<'a, K, V> RustcOccupiedEntry<'a, K, V> { /// map.rustc_entry("poneyland").or_insert(12); /// assert_eq!(map.rustc_entry("poneyland").key(), &"poneyland"); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn key(&self) -> &K { unsafe { &self.elem.as_ref().0 } } @@ -309,6 +316,7 @@ impl<'a, K, V> RustcOccupiedEntry<'a, K, V> { /// /// assert_eq!(map.contains_key("poneyland"), false); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn remove_entry(self) -> (K, V) { unsafe { self.table.erase_no_drop(&self.elem); @@ -331,6 +339,7 @@ impl<'a, K, V> RustcOccupiedEntry<'a, K, V> { /// assert_eq!(o.get(), &12); /// } /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn get(&self) -> &V { unsafe { &self.elem.as_ref().1 } } @@ -362,6 +371,7 @@ impl<'a, K, V> RustcOccupiedEntry<'a, K, V> { /// /// assert_eq!(map["poneyland"], 24); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn get_mut(&mut self) -> &mut V { unsafe { &mut self.elem.as_mut().1 } } @@ -389,6 +399,7 @@ impl<'a, K, V> RustcOccupiedEntry<'a, K, V> { /// /// assert_eq!(map["poneyland"], 22); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn into_mut(self) -> &'a mut V { unsafe { &mut self.elem.as_mut().1 } } @@ -410,6 +421,7 @@ impl<'a, K, V> RustcOccupiedEntry<'a, K, V> { /// /// assert_eq!(map["poneyland"], 15); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn insert(&mut self, mut value: V) -> V { let old_value = self.get_mut(); mem::swap(&mut value, old_value); @@ -433,6 +445,7 @@ impl<'a, K, V> RustcOccupiedEntry<'a, K, V> { /// /// assert_eq!(map.contains_key("poneyland"), false); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn remove(self) -> V { self.remove_entry().1 } @@ -457,6 +470,7 @@ impl<'a, K, V> RustcOccupiedEntry<'a, K, V> { /// } /// /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn replace_entry(self, value: V) -> (K, V) { let entry = unsafe { self.elem.as_mut() }; @@ -490,6 +504,7 @@ impl<'a, K, V> RustcOccupiedEntry<'a, K, V> { /// } /// } /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn replace_key(self) -> K { let entry = unsafe { self.elem.as_mut() }; mem::replace(&mut entry.0, self.key.unwrap()) @@ -508,6 +523,7 @@ impl<'a, K, V> RustcVacantEntry<'a, K, V> { /// let mut map: HashMap<&str, u32> = HashMap::new(); /// assert_eq!(map.rustc_entry("poneyland").key(), &"poneyland"); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn key(&self) -> &K { &self.key } @@ -526,6 +542,7 @@ impl<'a, K, V> RustcVacantEntry<'a, K, V> { /// v.into_key(); /// } /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn into_key(self) -> K { self.key } @@ -546,6 +563,7 @@ impl<'a, K, V> RustcVacantEntry<'a, K, V> { /// } /// assert_eq!(map["poneyland"], 37); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn insert(self, value: V) -> &'a mut V { let bucket = self.table.insert_no_grow(self.hash, (self.key, value)); unsafe { &mut bucket.as_mut().1 } @@ -567,7 +585,7 @@ impl<'a, K, V> RustcVacantEntry<'a, K, V> { /// assert_eq!(o.get(), &37); /// } /// ``` - #[inline] + #[cfg_attr(feature = "inline-more", inline)] pub fn insert_entry(self, value: V) -> RustcOccupiedEntry<'a, K, V> { let bucket = self.table.insert_no_grow(self.hash, (self.key, value)); RustcOccupiedEntry { @@ -580,6 +598,7 @@ impl<'a, K, V> RustcVacantEntry<'a, K, V> { impl IterMut<'_, K, V> { /// Returns a iterator of references over the remaining items. + #[cfg_attr(feature = "inline-more", inline)] pub fn rustc_iter(&self) -> Iter<'_, K, V> { self.iter() } @@ -587,6 +606,7 @@ impl IterMut<'_, K, V> { impl IntoIter { /// Returns a iterator of references over the remaining items. + #[cfg_attr(feature = "inline-more", inline)] pub fn rustc_iter(&self) -> Iter<'_, K, V> { self.iter() } @@ -594,6 +614,7 @@ impl IntoIter { impl Drain<'_, K, V> { /// Returns a iterator of references over the remaining items. + #[cfg_attr(feature = "inline-more", inline)] pub fn rustc_iter(&self) -> Iter<'_, K, V> { self.iter() } diff --git a/src/scopeguard.rs b/src/scopeguard.rs index ba99e7ffff..32c9694372 100644 --- a/src/scopeguard.rs +++ b/src/scopeguard.rs @@ -9,6 +9,7 @@ where value: T, } +#[cfg_attr(feature = "inline-more", inline)] pub fn guard(value: T, dropfn: F) -> ScopeGuard where F: FnMut(&mut T), @@ -21,6 +22,7 @@ where F: FnMut(&mut T), { type Target = T; + #[cfg_attr(feature = "inline-more", inline)] fn deref(&self) -> &T { &self.value } @@ -30,6 +32,7 @@ impl DerefMut for ScopeGuard where F: FnMut(&mut T), { + #[cfg_attr(feature = "inline-more", inline)] fn deref_mut(&mut self) -> &mut T { &mut self.value } @@ -39,6 +42,7 @@ impl Drop for ScopeGuard where F: FnMut(&mut T), { + #[cfg_attr(feature = "inline-more", inline)] fn drop(&mut self) { (self.dropfn)(&mut self.value) } diff --git a/src/set.rs b/src/set.rs index ef8eb8bfef..7e440a21c7 100644 --- a/src/set.rs +++ b/src/set.rs @@ -129,6 +129,7 @@ impl HashSet { /// use hashbrown::HashSet; /// let set: HashSet = HashSet::new(); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn new() -> Self { Self { map: HashMap::new(), @@ -147,6 +148,7 @@ impl HashSet { /// let set: HashSet = HashSet::with_capacity(10); /// assert!(set.capacity() >= 10); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn with_capacity(capacity: usize) -> Self { Self { map: HashMap::with_capacity(capacity), @@ -164,6 +166,7 @@ impl HashSet { /// let set: HashSet = HashSet::with_capacity(100); /// assert!(set.capacity() >= 100); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn capacity(&self) -> usize { self.map.capacity() } @@ -184,6 +187,7 @@ impl HashSet { /// println!("{}", x); /// } /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn iter(&self) -> Iter<'_, T> { Iter { iter: self.map.keys(), @@ -202,6 +206,7 @@ impl HashSet { /// v.insert(1); /// assert_eq!(v.len(), 1); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn len(&self) -> usize { self.map.len() } @@ -218,6 +223,7 @@ impl HashSet { /// v.insert(1); /// assert!(!v.is_empty()); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn is_empty(&self) -> bool { self.map.is_empty() } @@ -239,6 +245,7 @@ impl HashSet { /// /// assert!(set.is_empty()); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn drain(&mut self) -> Drain<'_, T> { Drain { iter: self.map.drain(), @@ -257,6 +264,7 @@ impl HashSet { /// v.clear(); /// assert!(v.is_empty()); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn clear(&mut self) { self.map.clear() } @@ -287,6 +295,7 @@ where /// let mut set = HashSet::with_hasher(s); /// set.insert(2); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn with_hasher(hasher: S) -> Self { Self { map: HashMap::with_hasher(hasher), @@ -314,6 +323,7 @@ where /// let mut set = HashSet::with_capacity_and_hasher(10, s); /// set.insert(1); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Self { Self { map: HashMap::with_capacity_and_hasher(capacity, hasher), @@ -334,6 +344,7 @@ where /// let set: HashSet = HashSet::with_hasher(hasher); /// let hasher: &DefaultHashBuilder = set.hasher(); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn hasher(&self) -> &S { self.map.hasher() } @@ -354,6 +365,7 @@ where /// set.reserve(10); /// assert!(set.capacity() >= 10); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn reserve(&mut self, additional: usize) { self.map.reserve(additional) } @@ -374,6 +386,7 @@ where /// let mut set: HashSet = HashSet::new(); /// set.try_reserve(10).expect("why is the test harness OOMing on 10 bytes?"); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn try_reserve(&mut self, additional: usize) -> Result<(), CollectionAllocErr> { self.map.try_reserve(additional) } @@ -394,6 +407,7 @@ where /// set.shrink_to_fit(); /// assert!(set.capacity() >= 2); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn shrink_to_fit(&mut self) { self.map.shrink_to_fit() } @@ -419,6 +433,7 @@ where /// set.shrink_to(0); /// assert!(set.capacity() >= 2); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn shrink_to(&mut self, min_capacity: usize) { self.map.shrink_to(min_capacity) } @@ -446,6 +461,7 @@ where /// let diff: HashSet<_> = b.difference(&a).collect(); /// assert_eq!(diff, [4].iter().collect()); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn difference<'a>(&'a self, other: &'a Self) -> Difference<'a, T, S> { Difference { iter: self.iter(), @@ -474,6 +490,7 @@ where /// assert_eq!(diff1, diff2); /// assert_eq!(diff1, [1, 4].iter().collect()); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn symmetric_difference<'a>(&'a self, other: &'a Self) -> SymmetricDifference<'a, T, S> { SymmetricDifference { iter: self.difference(other).chain(other.difference(self)), @@ -498,6 +515,7 @@ where /// let intersection: HashSet<_> = a.intersection(&b).collect(); /// assert_eq!(intersection, [2, 3].iter().collect()); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn intersection<'a>(&'a self, other: &'a Self) -> Intersection<'a, T, S> { Intersection { iter: self.iter(), @@ -523,6 +541,7 @@ where /// let union: HashSet<_> = a.union(&b).collect(); /// assert_eq!(union, [1, 2, 3, 4].iter().collect()); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn union<'a>(&'a self, other: &'a Self) -> Union<'a, T, S> { Union { iter: self.iter().chain(other.difference(self)), @@ -547,6 +566,7 @@ where /// /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html + #[cfg_attr(feature = "inline-more", inline)] pub fn contains(&self, value: &Q) -> bool where T: Borrow, @@ -573,6 +593,7 @@ where /// /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html + #[cfg_attr(feature = "inline-more", inline)] pub fn get(&self, value: &Q) -> Option<&T> where T: Borrow, @@ -595,6 +616,7 @@ where /// assert_eq!(set.get_or_insert(100), &100); /// assert_eq!(set.len(), 4); // 100 was inserted /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn get_or_insert(&mut self, value: T) -> &T { // Although the raw entry gives us `&mut T`, we only return `&T` to be consistent with // `get`. Key mutation is "raw" because you're not supposed to affect `Eq` or `Hash`. @@ -623,6 +645,7 @@ where /// } /// assert_eq!(set.len(), 4); // a new "fish" was inserted /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn get_or_insert_with(&mut self, value: &Q, f: F) -> &T where T: Borrow, @@ -704,6 +727,7 @@ where /// set.insert(2); /// assert_eq!(set.is_superset(&sub), true); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn is_superset(&self, other: &Self) -> bool { other.is_subset(self) } @@ -725,6 +749,7 @@ where /// assert_eq!(set.insert(2), false); /// assert_eq!(set.len(), 1); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()).is_none() } @@ -744,6 +769,7 @@ where /// set.replace(Vec::with_capacity(10)); /// assert_eq!(set.get(&[][..]).unwrap().capacity(), 10); /// ``` + #[cfg_attr(feature = "inline-more", inline)] pub fn replace(&mut self, value: T) -> Option { match self.map.entry(value) { map::Entry::Occupied(occupied) => Some(occupied.replace_key()), @@ -775,6 +801,7 @@ where /// /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html + #[cfg_attr(feature = "inline-more", inline)] pub fn remove(&mut self, value: &Q) -> bool where T: Borrow, @@ -801,6 +828,7 @@ where /// /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html + #[cfg_attr(feature = "inline-more", inline)] pub fn take(&mut self, value: &Q) -> Option where T: Borrow, @@ -867,6 +895,7 @@ where T: Eq + Hash, S: BuildHasher + Default, { + #[cfg_attr(feature = "inline-more", inline)] fn from_iter>(iter: I) -> Self { let mut set = Self::with_hasher(Default::default()); set.extend(iter); @@ -879,6 +908,7 @@ where T: Eq + Hash, S: BuildHasher, { + #[cfg_attr(feature = "inline-more", inline)] fn extend>(&mut self, iter: I) { self.map.extend(iter.into_iter().map(|k| (k, ()))); } @@ -889,6 +919,7 @@ where T: 'a + Eq + Hash + Copy, S: BuildHasher, { + #[cfg_attr(feature = "inline-more", inline)] fn extend>(&mut self, iter: I) { self.extend(iter.into_iter().cloned()); } @@ -900,6 +931,7 @@ where S: BuildHasher + Default, { /// Creates an empty `HashSet` with the `Default` value for the hasher. + #[cfg_attr(feature = "inline-more", inline)] fn default() -> Self { Self { map: HashMap::default(), @@ -1122,6 +1154,7 @@ impl<'a, T, S> IntoIterator for &'a HashSet { type Item = &'a T; type IntoIter = Iter<'a, T>; + #[cfg_attr(feature = "inline-more", inline)] fn into_iter(self) -> Iter<'a, T> { self.iter() } @@ -1151,6 +1184,7 @@ impl IntoIterator for HashSet { /// println!("{}", x); /// } /// ``` + #[cfg_attr(feature = "inline-more", inline)] fn into_iter(self) -> IntoIter { IntoIter { iter: self.map.into_iter(), @@ -1159,6 +1193,7 @@ impl IntoIterator for HashSet { } impl Clone for Iter<'_, K> { + #[cfg_attr(feature = "inline-more", inline)] fn clone(&self) -> Self { Iter { iter: self.iter.clone(), @@ -1168,14 +1203,17 @@ impl Clone for Iter<'_, K> { impl<'a, K> Iterator for Iter<'a, K> { type Item = &'a K; + #[cfg_attr(feature = "inline-more", inline)] fn next(&mut self) -> Option<&'a K> { self.iter.next() } + #[cfg_attr(feature = "inline-more", inline)] fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } } impl<'a, K> ExactSizeIterator for Iter<'a, K> { + #[cfg_attr(feature = "inline-more", inline)] fn len(&self) -> usize { self.iter.len() } @@ -1191,14 +1229,17 @@ impl fmt::Debug for Iter<'_, K> { impl Iterator for IntoIter { type Item = K; + #[cfg_attr(feature = "inline-more", inline)] fn next(&mut self) -> Option { self.iter.next().map(|(k, _)| k) } + #[cfg_attr(feature = "inline-more", inline)] fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } } impl ExactSizeIterator for IntoIter { + #[cfg_attr(feature = "inline-more", inline)] fn len(&self) -> usize { self.iter.len() } @@ -1215,14 +1256,17 @@ impl fmt::Debug for IntoIter { impl Iterator for Drain<'_, K> { type Item = K; + #[cfg_attr(feature = "inline-more", inline)] fn next(&mut self) -> Option { self.iter.next().map(|(k, _)| k) } + #[cfg_attr(feature = "inline-more", inline)] fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } } impl ExactSizeIterator for Drain<'_, K> { + #[cfg_attr(feature = "inline-more", inline)] fn len(&self) -> usize { self.iter.len() } @@ -1237,6 +1281,7 @@ impl fmt::Debug for Drain<'_, K> { } impl Clone for Intersection<'_, T, S> { + #[cfg_attr(feature = "inline-more", inline)] fn clone(&self) -> Self { Intersection { iter: self.iter.clone(), @@ -1252,6 +1297,7 @@ where { type Item = &'a T; + #[cfg_attr(feature = "inline-more", inline)] fn next(&mut self) -> Option<&'a T> { loop { let elt = self.iter.next()?; @@ -1261,6 +1307,7 @@ where } } + #[cfg_attr(feature = "inline-more", inline)] fn size_hint(&self) -> (usize, Option) { let (_, upper) = self.iter.size_hint(); (0, upper) @@ -1285,6 +1332,7 @@ where } impl Clone for Difference<'_, T, S> { + #[cfg_attr(feature = "inline-more", inline)] fn clone(&self) -> Self { Difference { iter: self.iter.clone(), @@ -1300,6 +1348,7 @@ where { type Item = &'a T; + #[cfg_attr(feature = "inline-more", inline)] fn next(&mut self) -> Option<&'a T> { loop { let elt = self.iter.next()?; @@ -1309,6 +1358,7 @@ where } } + #[cfg_attr(feature = "inline-more", inline)] fn size_hint(&self) -> (usize, Option) { let (_, upper) = self.iter.size_hint(); (0, upper) @@ -1333,6 +1383,7 @@ where } impl Clone for SymmetricDifference<'_, T, S> { + #[cfg_attr(feature = "inline-more", inline)] fn clone(&self) -> Self { SymmetricDifference { iter: self.iter.clone(), @@ -1347,9 +1398,11 @@ where { type Item = &'a T; + #[cfg_attr(feature = "inline-more", inline)] fn next(&mut self) -> Option<&'a T> { self.iter.next() } + #[cfg_attr(feature = "inline-more", inline)] fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } @@ -1373,6 +1426,7 @@ where } impl Clone for Union<'_, T, S> { + #[cfg_attr(feature = "inline-more", inline)] fn clone(&self) -> Self { Union { iter: self.iter.clone(), @@ -1404,9 +1458,11 @@ where { type Item = &'a T; + #[cfg_attr(feature = "inline-more", inline)] fn next(&mut self) -> Option<&'a T> { self.iter.next() } + #[cfg_attr(feature = "inline-more", inline)] fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() }