Rollup merge of #67642 - Mark-Simulacrum:relax-bounds, r=Amanieu
Relax bounds on HashMap/HashSet These APIs changed from the old bound listed to the new bound (possibly empty): K: Hash + Eq -> K * new * with_capacity K: Eq + Hash, S: BuildHasher -> K, S * with_hasher * with_capacity_and_hasher * hasher K: Eq + Hash + Debug -> K: Debug S: BuildHasher -> S HashMap as Debug K: Eq + Hash -> K S: BuildHasher + Default -> S: Default HashMap as Default Resolves #44777.
This commit is contained in:
commit
2a201336ed
@ -203,7 +203,7 @@ pub struct HashMap<K, V, S = RandomState> {
|
||||
base: base::HashMap<K, V, S>,
|
||||
}
|
||||
|
||||
impl<K: Hash + Eq, V> HashMap<K, V, RandomState> {
|
||||
impl<K, V> HashMap<K, V, RandomState> {
|
||||
/// Creates an empty `HashMap`.
|
||||
///
|
||||
/// The hash map is initially created with a capacity of 0, so it will not allocate until it
|
||||
@ -240,6 +240,59 @@ pub fn with_capacity(capacity: usize) -> HashMap<K, V, RandomState> {
|
||||
}
|
||||
|
||||
impl<K, V, S> HashMap<K, V, S> {
|
||||
/// Creates an empty `HashMap` which will use the given hash builder to hash
|
||||
/// keys.
|
||||
///
|
||||
/// The created map has the default initial capacity.
|
||||
///
|
||||
/// Warning: `hash_builder` is normally randomly generated, and
|
||||
/// is designed to allow HashMaps to be resistant to attacks that
|
||||
/// cause many collisions and very poor performance. Setting it
|
||||
/// manually using this function can expose a DoS attack vector.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::HashMap;
|
||||
/// use std::collections::hash_map::RandomState;
|
||||
///
|
||||
/// let s = RandomState::new();
|
||||
/// let mut map = HashMap::with_hasher(s);
|
||||
/// map.insert(1, 2);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
|
||||
pub fn with_hasher(hash_builder: S) -> HashMap<K, V, S> {
|
||||
HashMap { base: base::HashMap::with_hasher(hash_builder) }
|
||||
}
|
||||
|
||||
/// Creates an empty `HashMap` with the specified capacity, using `hash_builder`
|
||||
/// to hash the keys.
|
||||
///
|
||||
/// The hash map will be able to hold at least `capacity` elements without
|
||||
/// reallocating. If `capacity` is 0, the hash map will not allocate.
|
||||
///
|
||||
/// Warning: `hash_builder` is normally randomly generated, and
|
||||
/// is designed to allow HashMaps to be resistant to attacks that
|
||||
/// cause many collisions and very poor performance. Setting it
|
||||
/// manually using this function can expose a DoS attack vector.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::HashMap;
|
||||
/// use std::collections::hash_map::RandomState;
|
||||
///
|
||||
/// let s = RandomState::new();
|
||||
/// let mut map = HashMap::with_capacity_and_hasher(10, s);
|
||||
/// map.insert(1, 2);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
|
||||
pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> HashMap<K, V, S> {
|
||||
HashMap { base: base::HashMap::with_capacity_and_hasher(capacity, hash_builder) }
|
||||
}
|
||||
|
||||
/// Returns the number of elements the map can hold without reallocating.
|
||||
///
|
||||
/// This number is a lower bound; the `HashMap<K, V>` might be able to hold
|
||||
@ -457,65 +510,6 @@ pub fn drain(&mut self) -> Drain<'_, K, V> {
|
||||
pub fn clear(&mut self) {
|
||||
self.base.clear();
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V, S> HashMap<K, V, S>
|
||||
where
|
||||
K: Eq + Hash,
|
||||
S: BuildHasher,
|
||||
{
|
||||
/// Creates an empty `HashMap` which will use the given hash builder to hash
|
||||
/// keys.
|
||||
///
|
||||
/// The created map has the default initial capacity.
|
||||
///
|
||||
/// Warning: `hash_builder` is normally randomly generated, and
|
||||
/// is designed to allow HashMaps to be resistant to attacks that
|
||||
/// cause many collisions and very poor performance. Setting it
|
||||
/// manually using this function can expose a DoS attack vector.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::HashMap;
|
||||
/// use std::collections::hash_map::RandomState;
|
||||
///
|
||||
/// let s = RandomState::new();
|
||||
/// let mut map = HashMap::with_hasher(s);
|
||||
/// map.insert(1, 2);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
|
||||
pub fn with_hasher(hash_builder: S) -> HashMap<K, V, S> {
|
||||
HashMap { base: base::HashMap::with_hasher(hash_builder) }
|
||||
}
|
||||
|
||||
/// Creates an empty `HashMap` with the specified capacity, using `hash_builder`
|
||||
/// to hash the keys.
|
||||
///
|
||||
/// The hash map will be able to hold at least `capacity` elements without
|
||||
/// reallocating. If `capacity` is 0, the hash map will not allocate.
|
||||
///
|
||||
/// Warning: `hash_builder` is normally randomly generated, and
|
||||
/// is designed to allow HashMaps to be resistant to attacks that
|
||||
/// cause many collisions and very poor performance. Setting it
|
||||
/// manually using this function can expose a DoS attack vector.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::HashMap;
|
||||
/// use std::collections::hash_map::RandomState;
|
||||
///
|
||||
/// let s = RandomState::new();
|
||||
/// let mut map = HashMap::with_capacity_and_hasher(10, s);
|
||||
/// map.insert(1, 2);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
|
||||
pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> HashMap<K, V, S> {
|
||||
HashMap { base: base::HashMap::with_capacity_and_hasher(capacity, hash_builder) }
|
||||
}
|
||||
|
||||
/// Returns a reference to the map's [`BuildHasher`].
|
||||
///
|
||||
@ -536,7 +530,13 @@ pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> HashMap<K,
|
||||
pub fn hasher(&self) -> &S {
|
||||
self.base.hasher()
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V, S> HashMap<K, V, S>
|
||||
where
|
||||
K: Eq + Hash,
|
||||
S: BuildHasher,
|
||||
{
|
||||
/// Reserves capacity for at least `additional` more elements to be inserted
|
||||
/// in the `HashMap`. The collection may reserve more space to avoid
|
||||
/// frequent reallocations.
|
||||
@ -984,9 +984,8 @@ impl<K, V, S> Eq for HashMap<K, V, S>
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<K, V, S> Debug for HashMap<K, V, S>
|
||||
where
|
||||
K: Eq + Hash + Debug,
|
||||
K: Debug,
|
||||
V: Debug,
|
||||
S: BuildHasher,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_map().entries(self.iter()).finish()
|
||||
@ -996,8 +995,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<K, V, S> Default for HashMap<K, V, S>
|
||||
where
|
||||
K: Eq + Hash,
|
||||
S: BuildHasher + Default,
|
||||
S: Default,
|
||||
{
|
||||
/// Creates an empty `HashMap<K, V, S>`, with the `Default` value for the hasher.
|
||||
#[inline]
|
||||
|
@ -110,7 +110,7 @@ pub struct HashSet<T, S = RandomState> {
|
||||
map: HashMap<T, (), S>,
|
||||
}
|
||||
|
||||
impl<T: Hash + Eq> HashSet<T, RandomState> {
|
||||
impl<T> HashSet<T, RandomState> {
|
||||
/// Creates an empty `HashSet`.
|
||||
///
|
||||
/// The hash set is initially created with a capacity of 0, so it will not allocate until it
|
||||
@ -261,13 +261,7 @@ pub fn drain(&mut self) -> Drain<'_, T> {
|
||||
pub fn clear(&mut self) {
|
||||
self.map.clear()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, S> HashSet<T, S>
|
||||
where
|
||||
T: Eq + Hash,
|
||||
S: BuildHasher,
|
||||
{
|
||||
/// Creates a new empty hash set which will use the given hasher to hash
|
||||
/// keys.
|
||||
///
|
||||
@ -340,7 +334,13 @@ pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> HashSet<T, S> {
|
||||
pub fn hasher(&self) -> &S {
|
||||
self.map.hasher()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, S> HashSet<T, S>
|
||||
where
|
||||
T: Eq + Hash,
|
||||
S: BuildHasher,
|
||||
{
|
||||
/// Reserves capacity for at least `additional` more elements to be inserted
|
||||
/// in the `HashSet`. The collection may reserve more space to avoid
|
||||
/// frequent reallocations.
|
||||
@ -928,8 +928,7 @@ impl<T, S> Eq for HashSet<T, S>
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T, S> fmt::Debug for HashSet<T, S>
|
||||
where
|
||||
T: Eq + Hash + fmt::Debug,
|
||||
S: BuildHasher,
|
||||
T: fmt::Debug,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_set().entries(self.iter()).finish()
|
||||
@ -977,8 +976,7 @@ fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T, S> Default for HashSet<T, S>
|
||||
where
|
||||
T: Eq + Hash,
|
||||
S: BuildHasher + Default,
|
||||
S: Default,
|
||||
{
|
||||
/// Creates an empty `HashSet<T, S>` with the `Default` value for the hasher.
|
||||
#[inline]
|
||||
|
@ -6,7 +6,6 @@ pub fn no_debug() {
|
||||
pub fn no_hash() {
|
||||
use std::collections::HashSet;
|
||||
let mut set = HashSet::new();
|
||||
//~^ ERROR arrays only have std trait implementations for lengths 0..=32
|
||||
set.insert([0_usize; 33]);
|
||||
//~^ ERROR arrays only have std trait implementations for lengths 0..=32
|
||||
}
|
||||
|
@ -9,24 +9,15 @@ LL | println!("{:?}", [0_usize; 33]);
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0277]: arrays only have std trait implementations for lengths 0..=32
|
||||
--> $DIR/core-traits-no-impls-length-33.rs:10:16
|
||||
--> $DIR/core-traits-no-impls-length-33.rs:9:16
|
||||
|
|
||||
LL | set.insert([0_usize; 33]);
|
||||
| ^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[usize; 33]`
|
||||
|
|
||||
= note: required because of the requirements on the impl of `std::cmp::Eq` for `[usize; 33]`
|
||||
|
||||
error[E0277]: arrays only have std trait implementations for lengths 0..=32
|
||||
--> $DIR/core-traits-no-impls-length-33.rs:8:19
|
||||
|
|
||||
LL | let mut set = HashSet::new();
|
||||
| ^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[usize; 33]`
|
||||
|
|
||||
= note: required because of the requirements on the impl of `std::cmp::Eq` for `[usize; 33]`
|
||||
= note: required by `std::collections::HashSet::<T>::new`
|
||||
|
||||
error[E0369]: binary operation `==` cannot be applied to type `[usize; 33]`
|
||||
--> $DIR/core-traits-no-impls-length-33.rs:15:19
|
||||
--> $DIR/core-traits-no-impls-length-33.rs:14:19
|
||||
|
|
||||
LL | [0_usize; 33] == [1_usize; 33]
|
||||
| ------------- ^^ ------------- [usize; 33]
|
||||
@ -36,7 +27,7 @@ LL | [0_usize; 33] == [1_usize; 33]
|
||||
= note: an implementation of `std::cmp::PartialEq` might be missing for `[usize; 33]`
|
||||
|
||||
error[E0369]: binary operation `<` cannot be applied to type `[usize; 33]`
|
||||
--> $DIR/core-traits-no-impls-length-33.rs:20:19
|
||||
--> $DIR/core-traits-no-impls-length-33.rs:19:19
|
||||
|
|
||||
LL | [0_usize; 33] < [1_usize; 33]
|
||||
| ------------- ^ ------------- [usize; 33]
|
||||
@ -46,7 +37,7 @@ LL | [0_usize; 33] < [1_usize; 33]
|
||||
= note: an implementation of `std::cmp::PartialOrd` might be missing for `[usize; 33]`
|
||||
|
||||
error[E0277]: the trait bound `&[usize; 33]: std::iter::IntoIterator` is not satisfied
|
||||
--> $DIR/core-traits-no-impls-length-33.rs:25:14
|
||||
--> $DIR/core-traits-no-impls-length-33.rs:24:14
|
||||
|
|
||||
LL | for _ in &[0_usize; 33] {
|
||||
| ^^^^^^^^^^^^^^ the trait `std::iter::IntoIterator` is not implemented for `&[usize; 33]`
|
||||
@ -58,7 +49,7 @@ LL | for _ in &[0_usize; 33] {
|
||||
<&'a mut [T] as std::iter::IntoIterator>
|
||||
= note: required by `std::iter::IntoIterator::into_iter`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0277, E0369.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
|
Loading…
Reference in New Issue
Block a user