-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Implement hash_map
macro
#144070
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement hash_map
macro
#144070
Conversation
This comment has been minimized.
This comment has been minimized.
3d020f6
to
b5692af
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Wouldn't using one of |
I was thinking about
|
All the options i mentioned should be equivalent to let len = 1 $(+ {stringify!($k); 1})*;
let mut map = HashMap::with_capacity(len);
$( map.insert($k, $v); )* HashMap::from([$(($k, $v)),*]) |
I don't think intrinsics make sense here, this is a library type. I think the repeat insert method makes the most sense as it doesn't have the potential stack usage problem of from. Repeat insert is also how extend is implemented under the hood: https://github.com/rust-lang/hashbrown/blob/670213fb32d208759d0331996894e05604de0c18/src/map.rs#L4562. with_capacity definitely makes sense though. You can count the elements like this: https://lukaswirth.dev/tlborm/decl-macros/building-blocks/counting.html |
Oh actually you might be able to use the unstable macro_metavar_expr_count for the counting too, I forgot about that :D |
I would go for the slice length approach, but resolved constantly, which is technically what I'm doing just that instead of making a variable using So probably macro_rules! hash_map {
() => {{
::std::collections::HashMap::new()
}};
( $( $key:expr => $value:expr ),* $(,)? ) => {{
let mut map = ::std::collections::HashMap::with_capacity(
const { [$($crate::hash_map!(@internal count $key)),*].len() }
);
$( map.insert($key, $value); )*
map
}};
(@internal count $i:tt) => {()}
} This would work best if there is some sort of thing inside the standard library so that the last branch is only used internally in an explicit way, which would also filter out the usage inside the second branch. |
You should try this, which I only remembered after posting the first message |
The problem with this is that it would delay stabilization a lot, so I'm not sure, I don't think adding unstable to unstable helps |
You're allowed to use unstable features internally with |
Would it be possible to use EDIT: or rather HashMap::with_capacity_and_hasher(capacity, Default::default()) for specifying capacity. |
Ok, I will check that now |
c8d57d1
to
066023e
Compare
Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!
🤔 I wonder how the implementation would compare to doing:
<
$crate::collections::HashMap<_, _, $crate::hash::RandomState>
as
$crate::convert::From<[(_, _); _]>
>::from([
$(
($key, $value)
),+ // empty case still handled as `new()`.
])
Intuitively, doing a batch of .insert()
s does require the map
to go back to a fully usable-from-the-outside state, whereas a direct batched constructor such as From<[(K, V); N]>
does not, so depending on the impl, there might be more room for optimisation with this more direct approach 🤔
$crate::collections::HashMap::new() | ||
}}; | ||
|
||
( $( $key:expr => $value:expr ),* $(,)? ) => {{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very tiny nit 🙂:
( $( $key:expr => $value:expr ),* $(,)? ) => {{ | |
( $( $key:expr => $value:expr ),+ $(,)? ) => {{ |
would make the intent clearer, and also reject hash_map!(,)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that makes sense, I suggest addressing this in a follow-up PR
let mut map = $crate::collections::HashMap::with_capacity( | ||
const { $crate::repetition_utils!(@count $($key),*) } | ||
); | ||
$( map.insert($key, $value); )* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$( map.insert($key, $value); )* | |
$( map.insert($key, $value); )+ |
I have checked the |
Thanks for looking into these 🙏 |
I was now checking about this you said, which feels weird, I thought that without recursiveness this wouldn't have a problem, so should I add another PR to the tracking issue? Wait for a comment period? |
…Noratrieb Implement `hash_map` macro Implementation of rust-lang#144032 Implements the `hash_map` macro under `std/src/macros.rs`.
Rollup of 14 pull requests Successful merges: - #143857 (Port #[macro_export] to the new attribute parsing infrastructure) - #143900 ([rustdoc] Correctly handle `should_panic` doctest attribute and fix `--no-run` test flag on the 2024 edition) - #144070 (Implement `hash_map` macro ) - #144322 (Add lint against dangling pointers from local variables) - #144443 (Make target pointer width in target json an integer) - #144667 (`AlignmentEnum` should just be `repr(usize)` now) - #144779 (Implement debugging output of the bootstrap Step graph into a DOT file) - #144790 (Multiple bounds checking elision failures) - #144794 (Port `#[coroutine]` to the new attribute system) - #144808 (`Interner` arg to `EarlyBinder` does not affect auto traits) - #144816 (Update E0562 to account for the new impl trait positions) - #144822 (Return a struct with named fields from `hash_owner_nodes`) - #144824 (Updated test links in compiler) - #144829 (Use full flag name in strip command for Darwin) r? `@ghost` `@rustbot` modify labels: rollup
…Noratrieb Implement `hash_map` macro Implementation of rust-lang#144032 Implements the `hash_map` macro under `std/src/macros.rs`.
Rollup of 13 pull requests Successful merges: - #143857 (Port #[macro_export] to the new attribute parsing infrastructure) - #143900 ([rustdoc] Correctly handle `should_panic` doctest attribute and fix `--no-run` test flag on the 2024 edition) - #144070 (Implement `hash_map` macro ) - #144322 (Add lint against dangling pointers from local variables) - #144443 (Make target pointer width in target json an integer) - #144667 (`AlignmentEnum` should just be `repr(usize)` now) - #144790 (Multiple bounds checking elision failures) - #144794 (Port `#[coroutine]` to the new attribute system) - #144808 (`Interner` arg to `EarlyBinder` does not affect auto traits) - #144816 (Update E0562 to account for the new impl trait positions) - #144822 (Return a struct with named fields from `hash_owner_nodes`) - #144824 (Updated test links in compiler) - #144829 (Use full flag name in strip command for Darwin) r? `@ghost` `@rustbot` modify labels: rollup
…Noratrieb Implement `hash_map` macro Implementation of rust-lang#144032 Implements the `hash_map` macro under `std/src/macros.rs`.
Rollup of 13 pull requests Successful merges: - #143857 (Port #[macro_export] to the new attribute parsing infrastructure) - #144070 (Implement `hash_map` macro ) - #144322 (Add lint against dangling pointers from local variables) - #144667 (`AlignmentEnum` should just be `repr(usize)` now) - #144678 (Make no_mangle on foreign items explicit instead of implicit) - #144790 (Multiple bounds checking elision failures) - #144794 (Port `#[coroutine]` to the new attribute system) - #144805 (compiletest: Preliminary cleanup of `ProcRes` printing/unwinding) - #144808 (`Interner` arg to `EarlyBinder` does not affect auto traits) - #144816 (Update E0562 to account for the new impl trait positions) - #144822 (Return a struct with named fields from `hash_owner_nodes`) - #144824 (Updated test links in compiler) - #144829 (Use full flag name in strip command for Darwin) r? `@ghost` `@rustbot` modify labels: rollup
…Noratrieb Implement `hash_map` macro Implementation of rust-lang#144032 Implements the `hash_map` macro under `std/src/macros.rs`.
No what I mean is that if you made the macro expand to |
Perfect. Thanks for everything @Noratrieb & @danielhenrymantilla ! |
Rollup of 13 pull requests Successful merges: - #143857 (Port #[macro_export] to the new attribute parsing infrastructure) - #144070 (Implement `hash_map` macro ) - #144322 (Add lint against dangling pointers from local variables) - #144667 (`AlignmentEnum` should just be `repr(usize)` now) - #144706 (Do not give function allocations alignment in consteval and Miri.) - #144790 (Multiple bounds checking elision failures) - #144794 (Port `#[coroutine]` to the new attribute system) - #144805 (compiletest: Preliminary cleanup of `ProcRes` printing/unwinding) - #144808 (`Interner` arg to `EarlyBinder` does not affect auto traits) - #144816 (Update E0562 to account for the new impl trait positions) - #144822 (Return a struct with named fields from `hash_owner_nodes`) - #144824 (Updated test links in compiler) - #144829 (Use full flag name in strip command for Darwin) r? `@ghost` `@rustbot` modify labels: rollup
…Noratrieb Implement `hash_map` macro Implementation of rust-lang#144032 Implements the `hash_map` macro under `std/src/macros.rs`.
Rollup of 12 pull requests Successful merges: - #142678 (Misc cleanups of `generic_arg_infer` related HIR logic) - #144070 (Implement `hash_map` macro ) - #144738 (Remove the omit_gdb_pretty_printer_section attribute) - #144790 (Multiple bounds checking elision failures) - #144805 (compiletest: Preliminary cleanup of `ProcRes` printing/unwinding) - #144808 (`Interner` arg to `EarlyBinder` does not affect auto traits) - #144816 (Update E0562 to account for the new impl trait positions) - #144822 (Return a struct with named fields from `hash_owner_nodes`) - #144824 (Updated test links in compiler) - #144829 (Use full flag name in strip command for Darwin) - #144843 (Weekly `cargo update`) - #144851 (Forbid tail calling intrinsics) r? `@ghost` `@rustbot` modify labels: rollup
Implementation of #144032
Implements the
hash_map
macro understd/src/macros.rs
.