I'm using Rust 1.15 nightly and have some code with an iterator over std::io::Result<std::fs::DirEntry>
named dir_contents_iterator
that I'm trying to partition based on whether each DirEntry
corresponds to a file or a folder (with Err
values sorted into the file list):
let (dir_list, file_list): (Vec<std::io::Result<DirEntry>>, Vec<std::io::Result<DirEntry>>) =
dir_contents_iterator.partition(|entry_result| {
match entry_result {
Ok(entry) => {
entry
.file_type()
.and_then(|file_type| Ok(file_type.is_dir()))
.unwrap_or(false)
},
Err(_) => false
}
});
This code fails to compile with the following two errors:
error[E0308]: mismatched types
--> src/main.rs:179:13
|
179 | Ok(entry) => {
| ^^^^^^^^^ expected reference, found enum `std::result::Result`
|
= note: expected type `&std::result::Result<std::fs::DirEntry, std::io::Error>`
= note: found type `std::result::Result<_, _>`
error[E0308]: mismatched types
--> src/main.rs:185:13
|
185 | Err(_) => false
| ^^^^^^ expected reference, found enum `std::result::Result`
|
= note: expected type `&std::result::Result<std::fs::DirEntry, std::io::Error>`
= note: found type `std::result::Result<_, _>`
I ended up solving my problem by rewriting my code to partition out the Err
values first before partitioning between files and folders. This allows the match to be removed from the shown code and now it compiles. But for the sake of understanding, I'd still like to know why my original match's branch arms expect an &Result
reference rather than accepting a Result
, especially in the case of the second branch arm (Err(_) => false
) which doesn't even use the value!
Here's the problem code in the context of the project I'm working on in case I've left out any details that help explain the problem.