Pass this type as a parameter?

Hi,
I am stuck with the following type that I need to pass to a function, but it's rejected telling me that my type is not an opaque type, but a closure.

The function:

use itertools::{
        Itertools,
        Permutations
};

type IterFilteredNoConstraint<'a> = Vec<Permutations<Filter<Iter<'a, SubType>, impl FnMut(&&SubType) -> bool>>>;

fn myfunction(filtered : &IterFilteredNoConstraint){

}

and my type are defined with:

let lambda_unconstrained = |x: &&SubType| -> bool {
        // cond1 and cond2 are bools
        x.cond1 && x.cond2 

};
filtered.push(pl
                        .iter()
                        .filter(lambda_unconstrained)
                        .permutations(some_length));

myfunction(&mut filtered)

Apparently impl FnMut(&&SubType) -> bool is the cause of my issue.
I simplified the structures, functions for this question but the issue remains the same.

Still I am stuck and don't know how to workaround that.
Are generics my only hope ? Tried with but I still had an issue with bounds. So I don't know how to deal with that.

Thanks guys

You haven't included enough code to compile this and see the errors. I guessed at some things, but it would be better if you could provide something complete. (This is generally the best thing.) Ideally you can put it in a playground, but please at least provide something that we can try compiling, including the imports. Also please post the error you're getting, so we can make sure we're seeing the same error when we try compiling.

So, you want to take a Vec<..> of these as an argument and push something containing a new closure into it? You almost surely need to type erase the closures.

Try

type IterFilteredNoConstraint<'a> = Vec<
    Permutations<
        Filter<
            Iter<'a, SubType>,
            Box<dyn FnMut(&&SubType) -> bool>,
        >
    >
>;

You'll have to put your lambda_unconstrained in a Box too.


impl Trait in type aliases isn't yet stable, but when it is, it will represent an opaque type -- in your code, an opaque type parameterized by one lifetime ('a). For any given lifetime, every instance of the opaque type has to be the same actual type. The same as -> impl Trait.

Every closure is a unique type, so that won't work for your use case.

2 Likes

I'm not sure if this helps:

as a suggestion, you could just collect the permutations and use &Vec<Vec<YourType>> as the parameter type.

let foo: Vec<Vec<&Foo>> = v.iter().filter(func).permutations(4).collect();

Yes that was it:

I created a function to return my box and it all went fine:

fn return_closure_constrained() -> Box<dyn FnMut(&&SubType) -> bool> {

        Box::new(|x: &&SubType| -> bool {

                x.cond1 && x.cond2
        })
}

The code is quite complex and I was really too tired to recreate a playground.
Sorry about this.

Thanks!

That would avoid heap allocation altogether, right?
Any idea when it may be stabilized (I use the nightly toolchain)?

Thanks

I tried with
#![feature(type_alias_impl_trait)] in the root of my crate, but it still didn't work, btw (with the type of the original post)

Probably in the next edition, maybe a yearish? Just a guess.

But it doesn't solve your use case, you need the type erasure -- dyn FnMut(..) in some form -- so that you can support a different closure per vector element.

2 Likes

This wouldn't help your use-case. Not only different closures have different types, they also, potentially, have different, unlimited, sizes. Because of that putting them into a flat structure is non-trivial task, not possible to do without unsafe.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.