#Is this a bug or intended behaviour?

23 messages · Page 1 of 1 (latest)

undone thunder
#

Hey I was programming some rust and came across this:

#[allow(dead_code)]
pub fn get_examples() -> HashMap<String, Box<dyn example_manager::Example>> {
    let map = HashMap::new();

    //map.insert(String::from("Example1"), Box::from(SomeExampleImplementation {}));

    map
}

In this case the compiler infers the type of the map correctly (Screenshot 1)

But when I uncomment the map-insertion line it changes the inferred type for the HashMap (For Context SomeExampleImplementation implements example_manager::Example). See Screenshot 2.

Because the compiler changed the inferred type I get an error, that map does not match the functions return type. The compiler could obviously figure out, what type to use for the HashMap. That's why I think that this could be considered a bug. Am I wrong?

old harness
#

that being whatever you put into insert

undone thunder
#

But dyn Example would be satisfying for the SomeExampleImplementation type as well

old harness
#

if you do Box::new(SomeExampleImplementation {}) as _

old harness
#

it's not the same type

#

it has to be coerced

undone thunder
#

Yes it does work I tested it. If I specify map to be HashMap<String, Box<dyn example_manager::Example>> the compiler does not throw any errors

old harness
#

that doesn't mean that it's the same type

#

it means that the compiler coerced the Box when calling insert

#

it did that because the type was known, and not in the process of being deduced

#

?play ```rs
use std::collections::HashMap;
pub fn get_examples() -> HashMap<String, Box<dyn std::fmt::Display>> {
let map = HashMap::new();
map.insert(String::from("Example1"), Box::new("abc"));
map
}

still lynxBOT
#
error[E0308]: mismatched types
 --> src/main.rs:6:5
  |
3 | pub fn get_examples() -> HashMap<String, Box<dyn std::fmt::Display>> {
  |                          ------------------------------------------- expected `HashMap<String, Box<(dyn std::fmt::Display + 'static)>>` because of return type
4 |     let map = HashMap::new();
5 |     map.insert(String::from("Example1"), Box::new("abc"));
  |     ---                                  --------------- this argument has type `Box<&str>`...
  |     |
  |     ... which causes `map` to have type `HashMap<String, Box<&str>>`
6 |     map
  |     ^^^ expected `HashMap<String, Box<dyn Display>>`, found `HashMap<String, Box<&str>>`
  |
  = note: expected struct `HashMap<_, Box<(dyn std::fmt::Display + 'static)>>`
             found struct `HashMap<_, Box<&str>>`

For more information about this error, try `rustc --explain E0308`.```
old harness
#

?play ```rs
use std::collections::HashMap;
pub fn get_examples() -> HashMap<String, Box<dyn std::fmt::Display>> {
let mut map = HashMap::new();
map.insert(String::from("Example1"), Box::new("abc") as _);
map
}

still lynxBOT
old harness
#

additionally Box::from is generic, so the compiler has an even harder time inferring stuff correctly

#

use Box::new

undone thunder
#

Ok so this is intended behavior since this fits the workflow set out for the compiler but from a usability perspective the compiler could have behaved smarter by finding the type that doesn't generate an exception.

old harness
#

yes

#

making that change in the compiler would be extremely difficult