Using trait object in a function expecting a concrete type

Hi,

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 (https://github.com/tokio-rs/tracing/blob/master/tracing-core/src/dispatch.rs#L535) expects a concrete type. But the Dispatch struct only uses an actual trait object (here: https://github.com/tokio-rs/tracing/blob/master/tracing-core/src/dispatch.rs#L165)

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.

2 Likes

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.