(This comes from AoC) Could someone tell me why this compiles:
let instructions: &[(_, fn(r: &mut [usize], a: usize, b: usize) -> usize)] = &[ ("addr", |r, a, b| r[a] + r[b]), ("addi", |r, a, b| r[a] + b), ("mulr", |r, a, b| r[a] * r[b]), ("muli", |r, a, b| r[a] * b), ("banr", |r, a, b| r[a] & r[b]), ("bani", |r, a, b| r[a] & b), ("borr", |r, a, b| r[a] | r[b]), ("bori", |r, a, b| r[a] | b), ("setr", |r, a, _| r[a]), ("seti", |_, a, _| a), ("gtir", |r, a, b| (a > r[b]).into()), ("gtri", |r, a, b| (r[a] > b).into()), ("gtrr", |r, a, b| (r[a] > r[b]).into()), ("eqir", |r, a, b| (a == r[b]).into()), ("eqri", |r, a, b| (r[a] == b).into()), ("eqrr", |r, a, b| (r[a] == r[b]).into())]; let instructions: HashMap<_, _> = instructions.iter().cloned().collect();
And this doesn't?
let instructions2: HashMap<&str, fn(r: &mut [usize], a: usize, b: usize) -> usize> = [ ("addr", |r, a, b| r[a] + r[b]), ("addi", |r, a, b| r[a] + b), ("mulr", |r, a, b| r[a] * r[b]), ("muli", |r, a, b| r[a] * b), ("banr", |r, a, b| r[a] & r[b]), ("bani", |r, a, b| r[a] & b), ("borr", |r, a, b| r[a] | r[b]), ("bori", |r, a, b| r[a] | b), ("setr", |r, a, _| r[a]), ("seti", |_, a, _| a), ("gtir", |r, a, b| (a > r[b]).into()), ("gtri", |r, a, b| (r[a] > b).into()), ("gtrr", |r, a, b| (r[a] > r[b]).into()), ("eqir", |r, a, b| (a == r[b]).into()), ("eqri", |r, a, b| (r[a] == b).into()), ("eqrr", |r, a, b| (r[a] == r[b]).into())] .iter().cloned().collect();
The second gives the errors:
error[E0282]: type annotations needed
--> ...\test.rs:26:19
|
26 | ("addr", |r, a, b| r[a] + r[b]),
| ^ consider giving this closure parameter a type
|
= note: type must be known at this pointerror[E0277]: a collection of type
std::collections::HashMap<&str, for<'r> fn(&'r mut [usize], usize, usize) -> usize>
cannot be built from an iterator over elements of type(&str, [closure@...\test.rs:35:18: 35:29])
--> ...\test.rs:42:26
|
42 | .iter().cloned().collect();
| ^^^^^^^ a collection of typestd::collections::HashMap<&str, for<'r> fn(&'r mut [usize], usize, usize) -> usize>
cannot be built fromstd::iter::Iterator<Item=(&str, [closure@...\test.rs:35:18: 35:29])>
|
= help: the traitstd::iter::FromIterator<(&str, [closure@...\test.rs:35:18: 35:29])>
is not implemented forstd::collections::HashMap<&str, for<'r> fn(&'r mut [usize], usize, usize) -> usize>