Apologies if this has been discussed before. But I wasn't able to find an answer so far, and all the other stuff looks a bit different to what I am struggling with.
Assuming I do have a trait like this:
pub trait Search<'a>: Sized {
fn parse(s: &'a str) -> Result<Self, ()>;
}
And a function like this:
fn use_example_1<S>()
where
S: for<'s> Search<'s>,
{
let _ok = match S::parse("") {
Ok(_) => true,
Err(_) => false,
};
}
Using it like this:
struct Test<'a>(&'a str);
impl<'a> Search<'a> for Test<'a> {
fn parse(s: &'a str) -> Result<Self, ()> {
Ok(Test(s))
}
}
#[test]
fn test_lifetimes() {
use_example_1::<Test>();
}
I run into:
error: implementation of `Search` is not general enough
--> tests/lifetime.rs:47:5
|
47 | use_example_2::<Test>();
| ^^^^^^^^^^^^^^^^^^^^^ implementation of `Search` is not general enough
|
= note: `Search<'0>` would have to be implemented for the type `Test<'_>`, for any lifetime `'0`...
= note: ...but `Search<'1>` is actually implemented for the type `Test<'1>`, for some specific lifetime `'1`
Reading to a bunch of topics like this, I came up with a workaround of:
pub trait SearchBorrowed {
type Search<'a>: Search<'a>;
}
fn use_example_2<S>()
where
S: SearchBorrowed,
{
let _ok = match S::Search::parse("") {
Ok(_) => true,
Err(_) => false,
};
}
impl SearchBorrowed for Test<'_>
{
type Search<'a> = Test<'a>;
}
That works. But the downside is that for every T
I have, I also need to implement the SearchBorrowed
trait. A blanket implementation seems to bring back the original error.
Here is a link to the playground: Rust Playground
I am wondering if there is a more elegant solution to this.