I wonder: is it impossible to have a HRTBs with two lifetimes where one lifetime outlives the other? Is there an open issue in the issue tracker? I wasn't able to find anything on that matter.
Note that it's possible to have an implicit bound:
use std::borrow::Cow;
fn works_fine<F: for<'a, 'b> FnMut(&'a Cow<'b, str>)>(mut closure: F) {
let s = "Hello. I'm borrowed.".to_string();
let cow = Cow::Borrowed(&*s);
closure(&cow);
}
fn main() {
works_fine(|cowref| println!("{cowref}"));
}
This is a longstanding limitation of the Rust trait system; it's just hard to implement. One of the major motivations of the ongoing trait solver refactor is to unblock this feature.
Compiling playground v0.0.1 (/playground)
error: implementation of `SomeTrait` is not general enough
--> src/main.rs:15:5
|
15 | meeh(()); // fails to compile
| ^^^^^^^^ implementation of `SomeTrait` is not general enough
|
= note: `()` must implement `SomeTrait<&'0 Cow<'1, str>>`, for any two lifetimes `'0` and `'1`...
= note: ...but it actually implements `SomeTrait<&Cow<'2, str>>`, for some specific lifetime `'2`
error: could not compile `playground` (bin "playground") due to previous error
Why does works_fine work fine while meeh(()) fails to compile?
Minimal example here:
use std::borrow::Cow;
pub trait SomeTrait<T> {}
impl<'a, 'b: 'a> SomeTrait<&'a Cow<'b, str>> for () {}
fn works_fine<T: for<'a, 'b> FnMut(&'a Cow<'b, str>)>(_arg: T) {}
fn meeh<T: for<'a, 'b> SomeTrait<&'a Cow<'b, str>>>(_arg: T) {}
fn main() {
works_fine(|_| ()); // works fine
meeh(()); // fails to compile
}
impl<'a, 'b: 'a> SomeTrait<&'a Cow<'b, str>> for () {}
to
impl<'a, 'b> SomeTrait<&'a Cow<'b, str>> for () {}
makes the example compile. Fixing implied bounds in higher-ranked trait bounds is one of the objectives mentioned in the trait solver refactor blog post.
They should be the same, but are not for now I guess.
I noticed fixing this kind of problem is expected to be done in 2024 as per the roadmap where the linked issue is opened by you (surprising). I think the failed code deserves a new issue