{closure} to Box<Fn*> Conversion


#1

Hi, I want to this be possible in Rust:

let x: Box<Fn(u32) -> u32> = (|x|x).into();

and I came up with this idea:

impl<U: ?Sized, T: Unsize<U>>From<T> for Box<U> {
    fn from(val: T) -> Box<U> {
        Box::new(val) as Box<U>
    }
}

it works, but conflicts with this:

impl<T> From<T> for T {
    fn from(val: T) -> T { t }
}

and (especially) with this:

impl<T> From<T> for Box<T> {
    fn from(val: T) -> Box<T> { Box::new(t) }
}

it is clear why, but is any workarounds (maybe some other unstable features) for this?


#2

This question is probably better suited for users.rust-lang.org.

That being said, would simply boxing the closure work for your scenario?

let x: Box<Fn(u32) -> u32> = Box::new(|x|x);

#3

I guess his problem is that he wants both |x|x and Box<Fn(u32) -> u32> to be usable as argument for some generic function. So it can just accept impl Into<Box<Fn(u32)->u32>>


#4

The main problem here is impl From<T> for T. This makes many other possible implementation to overlapping. When you write impl From<T> for ?? you have to include T into ?? otherwise rustc can’t check that ?? != T


#5

The fundamental problem is that Box is #[fundamental] (haha). What this means is that it’s not beholden to the orphan rules, like &'a T, allowing me to write

struct MyStruct;
impl YourTrait for Box<MyStruct> { .. }

What this means is that someone down the chain could write something like this: impl From<MyType> for Box<dyn Fn(MyType)> and there is nothing to stop them from doing this. I ran into this blogpost that illustrates some of the complicated problems in the trait system. I suspect that this will get better as work on the trait solver continues.