(This is a bit of a long one, since I'm not exactly sure where exactly the error is, sorry!)
I have a trait
trait FilterComponent<'a, F>: Sized {
fn from_option(f: Option<&'a F>) -> Option<Self>;
}
which I am using to get a &F from an external crate and convert it into a type such as Option<&F> or &F, returning a Err(()) in the case where the conversion is not desirable. I then pass the unwrapped value (if it is Some) to a function that takes that implementing type. I'll stick with the implementation for just a &F
impl<'a: 'b, 'b, F> FilterComponent<'a, F> for &'b F {
fn from_option(f: Option<&'a F>) -> Option<Self> {
f
}
}
Since I want to do this for a list of functions, each with potentially different choices of FilterComponent, I create a series of traits to turn a general function into one I can sue, as follows:
//the type that implements GraphFilter and is returned by the IntoGraphFilter trait
struct FunctionFilter<F, G, Func>
where
G: for<'a> FilterComponent<'a, F>,
Func: Fn(G) -> bool,
{
func: Func,
_phantom: PhantomData<(F, G)>,
}
//trait to turn a function into a nameable type we can implement the
//typeless GraphFilter trait for (to avoid unconstrained type parameters)
trait IntoGraphFilter<F, G> {
type Output: GraphFilter;
fn into_filter(self) -> Self::Output;
}
impl<F, G, Func> IntoGraphFilter<F, G> for Func
where
G: for<'a> FilterComponent<'a, F>,
Func: Fn(G) -> bool,
{
type Output = FunctionFilter<F, G, Func>;
fn into_filter(self) -> Self::Output {
FunctionFilter {
func: self,
_phantom: PhantomData,
}
}
}
impl<F, G, Func> GraphFilter for FunctionFilter<F, G, Func>
where
G: for<'a> FilterComponent<'a, F>,
Func: Fn(G) -> bool,
{
}
//The final trait I use to store my generic functions
trait GraphFilter {}
//The storing struct
struct Storer {
filters: Vec<Box<dyn GraphFilter>>,
}
impl Storer {
fn new() -> Self {
Self {
filters: Vec::new(),
}
}
fn add_filter<F, G: for<'a> FilterComponent<'a, F>>(
&mut self,
func: impl IntoGraphFilter<F, G>,
) {
self.filters.push(Box::new(func.into_filter()))
}
}
fn main() {
Storer::new().add_filter(|foo: &()| true);
}
Then, since I want to store these filters dynamically, I have some struct that stores dyn GraphFilters in a Vec within some struct. To add them, I have a function impl'd for this struct with the signature:
fn add_filter<F, G: for<'a> FilterComponent<'a, F>>(&mut self, filter: impl IntoGraphFilter<F, G>)
But when I try to actually use this function like so:
storage.add_filter(|foo: &Foo| {false});
I get the error:
"implementation of FilterComponent is not general enough
FilterComponent<'0, Foo> would have to be implemented for the type &Foo, for any lifetime '0...
...but FilterComponent<'1, Foo> is actually implemented for the type &'1 Foo, for some specific lifetime '1"
Looking at my impl for &F, I only get FilterComponent<'a, F> for 'a longer than my types own lifetime, which in the case of |foo: &Foo| {false} should be any lifetime.
I'm not really sure where to go from here: I've tried modifying everything to remove the for<'a> but I ended up with an error that 'a is trying to outlive 'static
Edit: In editing to make reproducible, the compiler is now also telling me that my associated type won't live long enough in the definition of add_filter, which is a problem I had previously encountered but only seems to show up occasionaly, probably being hidden by other errors - any hints for fixing this would be appreciated too!