Using trait object in a function expecting a concrete type


I would like to create a tracing Dispatch using a trait object dyn Collector. I want to use a trait object because my Collector (or Subscriber previous versions) has potentially multiple Layers added to it, so I don't know its exact type.

However it looks like this is not possible because the new method here ( expects a concrete type. But the Dispatch struct only uses an actual trait object (here:

Does that mean I could make a PR to tracing so that I can build a Dispatch from a trait object instead of a concrete type?
Or is there anything simpler I could do?

(Not familiar with tracing in particular.)

You probably want to use Box<dyn Subscriber + Send + Sync> (or the Collect equivalent) as your concrete type. Example:

use tracing::{Dispatch, Subscriber, subscriber::NoSubscriber};

fn main() {
    let sub = NoSubscriber::new();
    let bx: Box<dyn Subscriber + Send + Sync> = Box::new(sub);
    let _ = Dispatch::new::<Box<dyn Subscriber + Send + Sync>>(bx);

Note that dyn Trait [ + Send + Sync + ...] is a concrete type, albeit an unsized (not Sized) one you can't pass to Dispatch::new. Box<dyn Trait [ + ...]> is also a concrete type, and Sized, and in this case implements the contained trait like you want it to.


Thank you, that worked!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.