Sized is not implemented for the type Fn

You should read the official Rust book, especially the chapter on closures. Your function declaration is incorrect; you are specifying that f has a bare trait type, which is impossible; that’s exactly what the error about Sized is about. You should use a generic type parameter instead:

fn split_filter<T: Clone, F>(a: &[T], f: F) -> (Vec<T>, Vec<T>)
where
    F: for<'a> Fn(&'a T) -> bool,

I have also changed the type of a from &Vec<T> to &[T]; there is no situation in which you would prefer the former to the latter. &Vec<T> is automatically coerced to &[T] when necessary. See Why is it discouraged to accept a reference to a String (&String) or Vec (&Vec) as a function argument?

The second error is closely tied to the mistake in the function declaration; your original function declaration specified a bare trait type, but closures do not have this type, they just implement the function trait.

The final program looks like this:

fn split_filter<T: Clone, F>(a: &[T], f: F) -> (Vec<T>, Vec<T>)
where
    F: Fn(&T) -> bool,
{
    let mut i: Vec<T> = vec![];
    let mut e: Vec<T> = vec![];
    for u in a.iter().cloned() {
        if f(&u) {
            i.push(u);
        } else {
            e.push(u);
        }
    }

    return (i, e);
}

fn main() {
    let v = vec![10, 40, 30, 20, 60, 50];
    println!("{:?}", split_filter(&v, |&a| a % 3 == 0));
}

Try it on the playground.

Leave a Comment