Closed
Description
This is the code:
use std::hashmap;
fn main() {
let mut map = hashmap::HashMap::new();
let str = "Hello, world!";
for &char in str.to_ascii().iter() {
let count = map.find(&char);
match count {
Some(&x) => map.insert(char, x + 1),
None => map.insert(char, 1)
}
}
println!("{:?}", map);
}
Error message:
count_chars.rs:11:41: 11:42 error: the type of this value must be known in this context
count_chars.rs:11 Some(&x) => map.insert(char, x + 1),
^
error: aborting due to previous error
Activity
huonw commentedon Aug 4, 2013
Either
or
makes the inference work:
1
in1 + x
defaults toint
and so the second argument (i.e.x
) is inferred to also beint
insert
comes first and so that1
there defaults toint
and the inference succeeds.(There are various ("correct") type errors and mutability issues that stop it compiling from after this.)
It seems like the original code should be legal, given the trivial adjustments (especially reordering the arms).
(cc @nikomatsakis)
huonw commentedon Nov 10, 2013
Triage: I've updated the code for language changes; the inference is still suboptimal (i.e. it fails), the fixes in the comment above still address the inference issue, but also still hit the borrowing errors.
The following code works fine:
nikomatsakis commentedon Nov 11, 2013
Reading this example more closely, I actually don't think inference is expected to succeed here. You haven't told it the type of the values in the map, but you attempting to do
x + 1
. Due to the possibility of overloaded operators, we (at least currently) require that the type ofx
be known at that point. Reordering the arms makes type inference succeed because it forces the type ofx
to beint
. Similarly, usinginsert_or_update_with
also supplies the initial value (1
), giving us the information we needed. I'm going to close.nikomatsakis commentedon Nov 11, 2013
That said -- we currently treat operator overloading as an operator, but it's possible that with the changes in #10337 we could avoid the requirement that we know the type of
x
. I'm going to tentatively re-open as a "sub-bug" of #10337.nikomatsakis commentedon Nov 11, 2013
Update title.
Don't rely on the type of `lhs` when type checking `lhs OP rhs`
lhs
when type checkinglhs OP rhs
#19434Aatch commentedon Jan 20, 2015
Multidispatch should have fixed this, correct?
nikomatsakis commentedon Jan 20, 2015
@Aatch It did not. The distinction has to do with needing to decide between "builtin" operators like
+
on integers and trait-driven operations. Currently we do this at the moment of type-checking the+
(or other operator). It'll take some rearchitecting but we could defer this decision.arielb1 commentedon Jun 21, 2015
This does compile (rather, type-check - of course it won't borrow-check) at 1.0 and above.
wthrowe commentedon Jun 21, 2015
The following does not work, however:
It gives: "error: unable to infer enough type information about
_
; type annotations or generic parameter binding required" (on theinto()
)I'd been assuming that was this issue since it works if you switch the order of the operands, but if this one is solved perhaps it is a new one?
steveklabnik commentedon Jan 3, 2017
Triage: @arielb1 said that this compiles, but it at least needs some massaging due to changes. I tried to do some of them, but it wasn't totally clear to me what should be done, exactly.
It's not clear to me if @wthrowe 's example is the same thing or different.
bstrie commentedon Dec 2, 2017
My own attempt to concoct a modern reproduction no longer exhibits this bug:
In fact, our inference is so good these days that even this works:
Given that this bug was filed so long before 1.0 that the test case no longer works and that nobody seems to have come up with a reproduction of the original behavior, I'm closing this.
arielb1 commentedon Dec 3, 2017
So autoref for operators will make this stop working for the normal reasons. I suppose that would be a regression. I hope it won't be too terribly annoying.
Auto merge of rust-lang#8280 - xFrednet:8276-map-clone-msrv, r=flip1995