Is it possible to call a static dispatch function with a trait object?

One of the issues I'm running into is once I start using a trait object (&dyn Trait), every function below it must also use a trait object. This is leading to dynamic dispatch spreading through most of my codebase. I'm hoping to set up some boundaries where I pay the dynamic dispatch cost once and break out into static dispatch. I've figured out that I can use a method inside a trait to wrap a static dispatch function to accomplish this goal, but that is a bit verbose. Is there a more concise way I can accomplish this?

trait Animal {
    fn wrapped_static_vocalize(&self);
}

#[derive(Debug)]
struct Cat;

impl Animal for Cat {
    fn wrapped_static_vocalize(&self) {
        println!("wrapped_static_vocalize");
        static_vocalize(self);
    }
}

fn dynamic_vocalize(animal: &dyn Animal) {
    animal.wrapped_static_vocalize();
    // How do I make the below line work?
    static_vocalize(animal);
}
fn static_vocalize<A: std::fmt::Debug + Animal>(animal: &A) {
    println!("static_vocalize {:?}", animal);
}

fn main() {
    let c = Cat;
    dynamic_vocalize(&c);
}

The trick is that Rust implicitly adds + Sized to all generics, and that excludes trait objects. To fix this, remove that bound with + ?Sized.

fn static_vocalize<A: Animal + ?Sized>(animal: &A) {
    todo!()
}

Ah that did it! :man_facepalming: Such a simple solution. Thanks!

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.