#Hash map of Fn objects

3 messages · Page 1 of 1 (latest)

trim shard
#

I'm trying to create a hash map of function objects but I can't get the compiler to accept my code. This is what I have:

fn plugin_dir(p: &PluginContext, c: &Config) -> String {
    p.plugin_dir.to_string()
}

fn variable_mapping() -> HashMap<String, Box<dyn Fn(&PluginContext, &Config) -> String>> {
    let mut result = HashMap::new();

    result.insert("PLUGIN_DIR".to_string(), Box::new(plugin_dir));

    result
}

which I assumed would be correct, but the compiler does not accept it and gives me this error message:

error[E0308]: mismatched types
  --> src/plugin/variables.rs:22:5
   |
17 | fn variable_mapping() -> HashMap<String, Box<dyn Fn(&PluginContext, &Config) -> String>> {
   |                          --------------------------------------------------------------- expected `HashMap<std::string::String, Box<(dyn for<'r, 's> Fn(&'r PluginContext, &'s Config) -> std::string::String + 'static)>>` because of return type
...
22 |     result
   |     ^^^^^^ expected trait object `dyn Fn`, found fn item
   |
   = note: expected struct `HashMap<_, Box<(dyn for<'r, 's> Fn(&'r PluginContext, &'s Config) -> std::string::String + 'static)>>`
              found struct `HashMap<_, Box<for<'r, 's> fn(&'r PluginContext, &'s Config) -> std::string::String {plugin_dir}>>

What am I missing here?

worldly bloom
# trim shard I'm trying to create a hash map of function objects but I can't get the compile...

Add an as Box<dyn Fn(&PluginContext, &Config) -> String> cast after Box::new. Alternatively, type-annotate the HashMap's value type.

If you take a look at the types in the error message, you'll notice the second one ends in {plugin_dir} and is listed as a fn (not dyn Fn) This is a fn item: an unnameable ZST unique to the function plugin_dir. The reason they exist is that Rust tries to not "forget" the actual function you take a function pointer from, which can be useful for optimizations. The downside is that once inference decided you have a HashMap of fn items, it won't relent and coerce them to dyn Fn

trim shard
#

Ah yeah, that seems to have fixed it. Looks like just doing as Box<_> works too, which I find kind of odd 🤔