Skip to content

diagnostics: "one type is more general" for two identical types? #75791

Closed
@matthiaskrgr

Description

@matthiaskrgr

While looking through some clippy lint warnings in rust-lang/rust-clippy#5939 I found this very confusing error message:

use std::io::{self};
use std::path::{Path, PathBuf};

pub fn main() {
    let path = &PathBuf::from("a");
    do_op(path, "remove file", std::fs::remove_file); // redundant closure
}

fn do_op<F>(path: &Path, _desc: &str, mut f: F)
where
    F: FnMut(&Path) -> io::Result<()>,
{
    match f(path) {
        Ok(()) => {}
        Err(ref _e) => {}
        Err(_e) => {}
    }
}
error[E0308]: mismatched types
 --> src/main.rs:6:5
  |
6 |     do_op(path, "remove file", std::fs::remove_file); // redundant closure
  |     ^^^^^ one type is more general than the other
  |
  = note: expected type `std::ops::FnOnce<(&std::path::Path,)>`
             found type `std::ops::FnOnce<(&std::path::Path,)>`

note that expected type and found type are identical which is not helpful 😅

This happens on

rustc 1.47.0-nightly (e15510ca3 2020-08-20)
binary: rustc
commit-hash: e15510ca33ea15c893b78710101c962b11459963
commit-date: 2020-08-20
host: x86_64-unknown-linux-gnu
release: 1.47.0-nightly
LLVM version: 10.0

and also on 1.46.0-beta.4.

On stable 1.45.2, the message looks different though:

error[E0631]: type mismatch in function arguments
  --> src/main.rs:6:32
   |
6  |     do_op(path, "remove file", std::fs::remove_file); // redundant closure
   |                                ^^^^^^^^^^^^^^^^^^^^
   |                                |
   |                                expected signature of `for<'r> fn(&'r std::path::Path) -> _`
   |                                found signature of `fn(_) -> _`
...
9  | fn do_op<F>(path: &Path, _desc: &str, mut f: F)
   |    ----- required by a bound in this
10 | where
11 |     F: FnMut(&Path) -> io::Result<()>,
   |        ------------------------------ required by this bound in `do_op`

error[E0271]: type mismatch resolving `for<'r> <fn(_) -> std::result::Result<(), std::io::Error> {std::fs::remove_file::<_>} as std::ops::FnOnce<(&'r std::path::Path,)>>::Output == std::result::Result<(), std::io::Error>`
  --> src/main.rs:6:5
   |
6  |     do_op(path, "remove file", std::fs::remove_file); // redundant closure
   |     ^^^^^ expected bound lifetime parameter, found concrete lifetime
...
9  | fn do_op<F>(path: &Path, _desc: &str, mut f: F)
   |    ----- required by a bound in this
10 | where
11 |     F: FnMut(&Path) -> io::Result<()>,
   |                        -------------- required by this bound in `do_op`

Metadata

Metadata

Assignees

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsA-lifetimesArea: Lifetimes / regionsC-bugCategory: This is a bug.P-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions