Jon Kelley
Jon Kelley

Reputation: 81

How to store generic function pointer as `any` in Rust?

I'm building a crate that takes functions as inputs.

I'd like to hide the type of the function so Scope does not need to be generic.

This should be okay because function pointers are a "copy" type and are static.

use std::any::{Any, TypeId};
struct Scope {
   caller: &'static dyn Any,
   props_id: TypeId
}

impl Scope {
    fn new<T: 'static>(f: fn(T)) -> Self {
        let caller = f as &'static dyn Any;
        let props_id = TypeId::of::<T>();
        Self { caller, props_id }
    }

    fn call<T: 'static>(&self, val: T) {
        let caller = self.caller.downcast_ref::<fn(T)>().unwrap();
        caller(val);
    }
}

However, I cannot take a &'static to the function pointer, and I cannot use the guarantees of any without using a box. I would like to not use a box because the type of fn() is known.

How would I go about solving this problem, perhaps even leveraging some unsafety with function pointers to get this working?

I could transmute the pointer type, but I am looking for something a little less hard to misuse.

Upvotes: 0

Views: 972

Answers (1)

Tavian Barnes
Tavian Barnes

Reputation: 12922

You can take &'static fn(T) instead. I don't think there's a way to cast a function pointer itself to &dyn Any.

Upvotes: 1

Related Questions