Skip to content
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

HashMap::from_iter doesn't compile without explicitly supplying the hasher #90879

Open
hniksic opened this issue Nov 13, 2021 · 3 comments
Open
Labels
A-inference Area: Type inference A-iterators Area: Iterators C-enhancement Category: An issue proposing an enhancement or a PR with one. T-libs Relevant to the library team, which will review and decide on the PR/issue. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@hniksic
Copy link
Contributor

hniksic commented Nov 13, 2021

Now that FromIterator is in the prelude, I expected to be able to create a HashMap like using HashMap::from_iter():

use std::collections::HashMap;
fn main() {
    let h = HashMap::from_iter([("foo", 1), ("bar", 2)]);
}

However, that doesn't compile, saying "type annotations needed for HashMap<&str, i32, S>":

 --> src/main.rs:3:13
  |
3 |     let h = HashMap::from_iter([("foo", 1), ("bar", 2)]);
  |         -   ^^^^^^^ cannot infer type for type parameter `S` declared on the struct `HashMap`
  |         |
  |         consider giving `h` the explicit type `HashMap<&str, i32, S>`, where the type parameter `S` is specified

Playground

I would expect <HashMap as FromIterator>::from_iter() to pick the default hasher in absence of an explicit request for a different one requested, like Vec::from_iter() compiles and defaults to the global allocator. (HashMap::from() also compiles, but it seems to be limited to the default hasher.)

Note that this is different from #69123 which is about a confusing diagnostic. This issue is about the error itself, in particular as compared to Vec::from_iter().

Tested with Rust 1.56.1 stable.

@hniksic hniksic added the C-bug Category: This is a bug. label Nov 13, 2021
@bragov4ik
Copy link

Also it might be helpful that there is a workaround

use std::collections::HashMap;
fn main() {
    let h = HashMap::<_, _>::from_iter([("foo", 1), ("bar", 2)]);
}

This way the compiler somehow understands to use the default hasher (not sure why it doesn't without ::<_, _>).

@SebastianJL
Copy link
Contributor

SebastianJL commented Dec 6, 2022

Is there any update on this? Just stumbled upon this today with rust 1.65, although with std::collections::HashSet::from_iter().

@fmease fmease added C-enhancement Category: An issue proposing an enhancement or a PR with one. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. A-inference Area: Type inference A-iterators Area: Iterators T-libs Relevant to the library team, which will review and decide on the PR/issue. and removed C-bug Category: This is a bug. needs-triage-legacy labels Jan 24, 2024
@hniksic
Copy link
Contributor Author

hniksic commented May 7, 2024

This is the same issue as the newer #101319. The explanation by @SkiFire13 there nicely explains what's going on:

When just HashSet is used it means to infer HashSet<T, S>, i.e. the S is also inferred. Default generic types are not used when doing inference. If you want to have the T inferred but not anything else then you can specify _ as its type

As summarized by the reporter there:

by doing HashSet::<_> you assert that the unmentioned parameters have their default value, whereas if you do not mention any type parameters at all, then defaults are ignored and so all type parameters must be inferred from other information

I actually wasn't aware of this distinction between omitting the type parameter and providing it as _, even after using Rust professionally for quite a few years now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-inference Area: Type inference A-iterators Area: Iterators C-enhancement Category: An issue proposing an enhancement or a PR with one. T-libs Relevant to the library team, which will review and decide on the PR/issue. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants