Where clause for closure arguments

pub trait SillyTrait<T1> {
    fn silly(self);
}

pub fn silly2<T1, T2>(x : T1, y: T2) where T2 : SillyTrait<T1> {
    <T2 as SillyTrait<T1>>::silly(y);
}

pub fn silly3<T1>(x : T1) {
    let id = |y : i64| y;
    silly2(x, id);
}

silly3 seems quite valid as long as there is an impl defined appropriately. For example:

impl<T2> SillyTrait<i64> for T2 {
    fn silly(self) {}
}

Then silly3(i64) should be valid.

I just wondering, what is the "where" clause I need to define for silly3 to make it compile?

The bound is <type of id> : SillyTrait<T1> but the type of id cannot be named. It is not possible to express this bound. An example without closure may help to understand the issue:

pub fn silly3a<T1>(x: T1) where <LocalStruct but you cannot name it here>: SillyTraiti<T1> {
    struct LocalStruct;
    silly2(x, LocalStruct);
}

However, in this case, you can make silly3 compile without changing semantics by casting the closure to an fn type:

pub fn silly3<T1>(x: T1)
where
    fn(i64) -> i64: SillyTrait<T1>,
{
    let id = |y: i64| y;
    silly2(x, id as fn(i64) -> i64);
}
1 Like