rusttypestype-mismatch

AsRef<Path> vs &Path


I have the following struct:

struct Config<'a> {
    path1: &'a dyn AsRef<Path>,
    path2: HashMap<SomeEnum, &'a dyn AsRef<Path>>,
}

Then when I try to create a new instance of this config:

Config {
    path1: &Path::new("path/to/file1"),
    path2: HashMap::from([(SomeEnum::Value, &Path::new("path/to/file2"))
}

I get no errors for the variable of path1, but for path2 I get:

error[E0308]: mismatched types
expected trait object `dyn AsRef`, found `&Path` 
Note: expected struct `HashMap<_, &dyn AsRef<Path>>` 
found struct `HashMap<_, &&Path>`

I don't get why this works for path1, but not for path2.


Solution

  • Type inference isn't quite able to figure out what's supposed to happen here. It isn't able to see that the &&Path reference should be converted to &dyn AsRef<Path>.

    You need to help it figure out that the second tuple slot should be &dyn AsRef<Path>. You could do this with a cast:

    Config {
        path1: &Path::new("path/to/file1"),
        path2: HashMap::from([(SomeEnum::Value, &Path::new("path/to/file2") as &dyn AsRef<Path>)]),
    }
    

    You could also create the tuple first with a type annotation:

    let v: (SomeEnum, &dyn AsRef<Path>) = (SomeEnum::Value, &Path::new("path/to/file2"));
        
    Config {
        path1: &Path::new("path/to/file1"),
        path2: HashMap::from([v]),
    }