diff --git a/ethers-solc/src/compile/project.rs b/ethers-solc/src/compile/project.rs index 2d08c7f7..0a0595c4 100644 --- a/ethers-solc/src/compile/project.rs +++ b/ethers-solc/src/compile/project.rs @@ -543,11 +543,20 @@ fn compile_parallel( } } + // need to get the currently installed reporter before installing the pool, otherwise each new + // thread in the pool will get initialized with the default value of the `thread_local!`'s + // localkey. This way we keep access to the reporter in the rayon pool + let scoped_report = report::get_default(|reporter| reporter.clone()); + // start a rayon threadpool that will execute all `Solc::compile()` processes let pool = rayon::ThreadPoolBuilder::new().num_threads(num_jobs).build().unwrap(); + let outputs = pool.install(move || { jobs.into_par_iter() - .map(|(solc, version, input, actually_dirty)| { + .map(move |(solc, version, input, actually_dirty)| { + // set the reporter on this thread + let _guard = report::set_scoped(&scoped_report); + tracing::trace!( "calling solc `{}` {:?} with {} sources: {:?}", version, diff --git a/ethers-solc/src/report/mod.rs b/ethers-solc/src/report/mod.rs index fd549aab..e87a586c 100644 --- a/ethers-solc/src/report/mod.rs +++ b/ethers-solc/src/report/mod.rs @@ -93,7 +93,7 @@ where /// print custom messages to `stdout`. /// /// A `Reporter` is entirely passive and only listens to incoming "events". -pub trait Reporter: 'static { +pub trait Reporter: 'static + std::fmt::Debug { /// Callback invoked right before [`Solc::compile()`] is called /// /// This contains the [Solc] its [Version] the complete [CompilerInput] and all files that @@ -453,6 +453,7 @@ mod tests { #[test] fn scoped_reporter_works() { + #[derive(Debug)] struct TestReporter; impl Reporter for TestReporter {} @@ -468,6 +469,7 @@ mod tests { }); set_global_reporter(Report::new(BasicStdoutReporter::default())).unwrap(); + #[derive(Debug)] struct TestReporter; impl Reporter for TestReporter {}