Open
Description
I tried this code:
fn shortened_first<'b, 'a: 'b>(first: &'a str, second: &'b str, _: &'b &'a ()) -> &'b str {
first
}
fn call_shortened_first<F>(f: F)
where
F: for<'a, 'b> FnOnce(&'a str, &'b str, &'b &'a ()) -> &'b str
{
let a = "a".to_owned();
let b = "b".to_owned();
let result = f(&a, &b, &&());
println!("{result}");
}
fn main() {
call_shortened_first(shortened_first);
}
I expected to see this happen: I expected this code to compile
Instead, this happened:
Compiling playground v0.0.1 (/playground)
error: implementation of `FnOnce` is not general enough
--> src/main.rs:17:5
|
17 | call_shortened_first(shortened_first);
| ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
= note: `fn(&str, &'3 str, &'3 &()) -> &'3 str {shortened_first::<'3, '_>}` must implement `FnOnce<(&'a str, &'1 str, &'1 &'a ())>`, for any two lifetimes `'1` and `'2`...
= note: ...but it actually implements `FnOnce<(&str, &'3 str, &'3 &())>`, for some specific lifetime `'3`
However, If I remove an explicit 'a: 'b
bound the code compiles.
fn shortened_first<'b, 'a>(first: &'a str, second: &'b str, _: &'b &'a ()) -> &'b str {
first
}
fn call_shortened_first<F>(f: F)
where
F: for<'a, 'b> FnOnce(&'a str, &'b str, &'b &'a ()) -> &'b str
{
let a = "a".to_owned();
let b = "b".to_owned();
let result = f(&a, &b, &&());
println!("{result}");
}
fn main() {
call_shortened_first(shortened_first);
}
Meta
Reproducible on 1.61-stable
, 1.62.0-beta.5(2022-06-13 1bc802e990a3393731b1)
, 1.63.0-nightly(2022-06-20 5750a6aa2777382bf421)
I suspect it has something to do with 'a: 'b
makes 'b
early bound, but when 'a: 'b
is implied from &'b &'a ()
it doesn't make 'b
early bound. The behavior is inconsistent and therefore very confusing.