Skip to content

Commit 880fe19

Browse files
Rollup merge of #154322 - m4rch3n1ng:hash-map-macro, r=Mark-Simulacrum
feat: reimplement `hash_map!` macro originally implemented in #144070, this had to be reverted in #148049 due to name ambiguity, as the macro was automatically put into the prelude. now, that #139493 has landed, it is possible to have a top-level macro, that is not exported by default, which should make it possible to reland this again. implements #144032 implementation from #144070, original author has been added as co-author effectively reverts #148049
2 parents db19e88 + 2e65734 commit 880fe19

2 files changed

Lines changed: 78 additions & 0 deletions

File tree

library/std/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,8 @@
337337
#![feature(formatting_options)]
338338
#![feature(funnel_shifts)]
339339
#![feature(generic_atomic)]
340+
#![feature(hash_map_internals)]
341+
#![feature(hash_map_macro)]
340342
#![feature(hasher_prefixfree_extras)]
341343
#![feature(hashmap_internals)]
342344
#![feature(hint_must_use)]

library/std/src/macros.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,3 +418,79 @@ pub macro dbg_internal {
418418
)
419419
},
420420
}
421+
422+
#[doc(hidden)]
423+
#[macro_export]
424+
#[allow_internal_unstable(hash_map_internals)]
425+
#[unstable(feature = "hash_map_internals", issue = "none")]
426+
macro_rules! repetition_utils {
427+
(@count $($tokens:tt),*) => {{
428+
[$($crate::repetition_utils!(@replace $tokens => ())),*].len()
429+
}};
430+
431+
(@replace $x:tt => $y:tt) => { $y }
432+
}
433+
434+
/// Creates a [`HashMap`] containing the arguments.
435+
///
436+
/// `hash_map!` allows specifying the entries that make
437+
/// up the [`HashMap`] where the key and value are separated by a `=>`.
438+
///
439+
/// The entries are separated by commas with a trailing comma being allowed.
440+
///
441+
/// It is semantically equivalent to using repeated [`HashMap::insert`]
442+
/// on a newly created hashmap.
443+
///
444+
/// `hash_map!` will attempt to avoid repeated reallocations by
445+
/// using [`HashMap::with_capacity`].
446+
///
447+
/// # Examples
448+
///
449+
/// ```rust
450+
/// #![feature(hash_map_macro)]
451+
/// use std::hash_map;
452+
///
453+
/// let map = hash_map! {
454+
/// "key" => "value",
455+
/// "key1" => "value1"
456+
/// };
457+
///
458+
/// assert_eq!(map.get("key"), Some(&"value"));
459+
/// assert_eq!(map.get("key1"), Some(&"value1"));
460+
/// assert!(map.get("brrrrrrooooommm").is_none());
461+
/// ```
462+
///
463+
/// And with a trailing comma
464+
///
465+
///```rust
466+
/// #![feature(hash_map_macro)]
467+
/// use std::hash_map;
468+
///
469+
/// let map = hash_map! {
470+
/// "key" => "value", // notice the ,
471+
/// };
472+
///
473+
/// assert_eq!(map.get("key"), Some(&"value"));
474+
/// ```
475+
///
476+
/// The key and value are moved into the HashMap.
477+
///
478+
/// [`HashMap`]: crate::collections::HashMap
479+
/// [`HashMap::insert`]: crate::collections::HashMap::insert
480+
/// [`HashMap::with_capacity`]: crate::collections::HashMap::with_capacity
481+
#[macro_export]
482+
#[allow_internal_unstable(hash_map_internals)]
483+
#[unstable(feature = "hash_map_macro", issue = "144032")]
484+
macro_rules! hash_map {
485+
() => {{
486+
$crate::collections::HashMap::new()
487+
}};
488+
489+
( $( $key:expr => $value:expr ),* $(,)? ) => {{
490+
let mut map = $crate::collections::HashMap::with_capacity(
491+
const { $crate::repetition_utils!(@count $($key),*) }
492+
);
493+
$( map.insert($key, $value); )*
494+
map
495+
}}
496+
}

0 commit comments

Comments
 (0)