functionrusttrait-objects

Store function returning impl Trait as trait object


As per the below example, I am trying to store functions as trait objects. I have worked out how to do this for functions which return a concrete type, by using as to cast from a function item to a function pointer. However, I would also like to store functions that return impl Element in the Vector, which as far as I understand requires using a generic parameter in the HasChildren implementation, but then I don't know how or what I should cast it to so it can be used as a trait object.

trait Element {}
trait HasChildren {}

struct Foo {}
impl Element for Foo {}
impl HasChildren for Foo {}

impl HasChildren for fn(String) -> Foo {}
impl<E: Element> HasChildren for fn(i32) -> E {}

fn get_concrete_element(val: String) -> Foo {
    Foo {}
}

fn get_impl_element(val: i32) -> impl Element {
    Foo {}
}

fn main() {
    // Store various trait objects in Vec
    let mut data: Vec<Box<dyn HasChildren>> = Vec::new();
    data.push(Box::new(Foo {})); // works
    data.push(Box::new(get_concrete_element as fn(String) -> Foo)); // works
    data.push(Box::new(get_impl_element as fn(i32) -> impl Element)); // doesn't work
}

Solution

  • You cannot name the return type, but you can let the compiler infer it:

    data.push(Box::new(get_impl_element as fn(i32) -> _));