jofas
June 17, 2023, 1:11pm
2
You need to nudge type inference a little here:
use std::collections::HashMap;
enum A {
B,
C,
}
fn donotwork() {
let g: HashMap<u8, fn(A) -> A> = HashMap::from([(0u8, (|x: A| x) as _)]);
let h: HashMap<u8, Box<dyn (Fn(A) -> A) + Sync>> = HashMap::from([(0, Box::new(|x: A| x) as _)]);
}
Playground .
See i.e. this topic for a similar issue I encountered when using collections with elements that need to be coerced:
Recently I found a case where rust's type inference fails for collections of trait objects . Here an example:
use std::fmt::Debug;
#[derive(Debug)]
struct D1;
#[derive(Debug)]
struct D2;
fn debug_vec() -> Vec<Box<dyn Debug>> {
// compiler: hmm, I don't know what type this is. Let's see how this one
// unfolds.
let mut v = Vec::new();
// compiler: got it, v must be Vec<Box<D1>>!
v.push(Box::new(D1));
// compiler: gosh darn it, this is no Box<D1> add…
or this topic:
I'm a little surprised that the compiler cannot automatically convert a between &Arc<closure> and &Arc<dyn Fn>:
fn test(f: &Arc<dyn Fn()>) {}
fn main() {
test(&Arc::new(|| {}))
}
The error is:
error[E0308]: mismatched types
--> src/main.rs:8:10
|
8 | test(&Arc::new(|| {}))
| ---- ^^^^^^^^^^^^^^^^ expected trait object `dyn Fn`, found closure
| |
| arguments to this function are incorrect
|
= note: expected reference `&Arc<(dyn Fn() + 'static)>`
…
BTW, I created a macro that makes it easy for you to create a hashmap with values that need to be coerced to a different type before you can store them: map_macro::hash_map_e
. It uses the same trick with explicit coercion to "something" (the _
placeholder) under the hood.
3 Likes