Open
Description
Given the following code: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=5c03cd34558f9bc8662eac3ff255190e
pub struct Value {
a: String,
}
pub struct Borrowed<'a> {
b: &'a str,
}
pub fn parse(a: &Value) -> Borrowed<'_> {
Borrowed { b: &a.a }
}
pub fn not<T>(predicate: impl Fn(&T) -> bool) -> impl Fn(&T) -> bool {
move |t: &T| !predicate(t)
}
/// Transform a predicate on `Borrowed`s into a predicate for `Value`s
pub fn borrowed(predicate: impl for<'a> Fn(&Borrowed<'_>) -> bool) -> impl Fn(&Value) -> bool {
move |t: &Value| {
let parsed = parse(t);
predicate(&parsed)
}
}
pub fn is_borrowed_cool() -> impl for<'a> Fn(&Borrowed<'a>) -> bool {
|b| true
}
pub fn compose_predicates() {
let a = not(is_borrowed_cool());
let b = borrowed(is_borrowed_cool());
// I would like this to compile. It doesn't though, and it generates
// an incorrect diagnostic.
let c = borrowed(not(is_borrowed_cool()));
}
The current output is:
error[E0308]: mismatched types
--> src/lib.rs:34:13
|
13 | pub fn not<T>(predicate: impl for<'a> Fn(&'a T) -> bool) -> impl for<'a> Fn(&'a T) -> bool {
| ------------------------------
| |
| one of the expected opaque types
| one of the found opaque types
...
25 | pub fn is_borrowed_cool() -> impl for<'a> Fn(&Borrowed<'a>) -> bool {
| --------------------------------------
| |
| one of the expected opaque types
| one of the found opaque types
...
34 | let c = borrowed(not(is_borrowed_cool()));
| ^^^^^^^^ lifetime mismatch
|
= note: expected associated type `<impl for<'a> Fn<(&'a Borrowed<'_>,)> as FnOnce<(&Borrowed<'_>,)>>::Output`
found associated type `<impl for<'a> Fn<(&'a Borrowed<'_>,)> as FnOnce<(&Borrowed<'_>,)>>::Output`
note: the lifetime requirement is introduced here
--> src/lib.rs:18:62
|
18 | pub fn borrowed(predicate: impl for<'a> Fn(&Borrowed<'_>) -> bool) -> impl Fn(&Value) -> bool {
| ^^^^
For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` due to previous error
Note the following lines specially:
= note: expected associated type `<impl for<'a> Fn<(&'a Borrowed<'_>,)> as FnOnce<(&Borrowed<'_>,)>>::Output`
found associated type `<impl for<'a> Fn<(&'a Borrowed<'_>,)> as FnOnce<(&Borrowed<'_>,)>>::Output`
where the expected and the found types are the same. I'm not sure if this is a compiler bug because I'm not very familiar
with HRTBs, but the diagnostic could be better. I can't really propose the better diagnostic because I don't know what's wrong
with my code.
The error is the same on nightly and beta.
(Edit: simplified the code a bit)
Metadata
Metadata
Assignees
Labels
Area: Closures (`|…| { … }`)Area: Messages for errors, warnings, and lintsArea: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs)Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.Area: Lifetimes / regionsDiagnostics: Confusing error or lint that should be reworked.Diagnostics: An error or lint that doesn't give enough information about the problem at hand.Relevant to the compiler team, which will review and decide on the PR/issue.