Fix for run_in_thread_pool_with_globals being no longer public

This commit is contained in:
Sylvester Hesp 2022-12-01 16:03:18 +01:00
parent f0aace570b
commit 17523e06d7

View File

@ -3,7 +3,8 @@ use crate::codegen_cx::SpirvMetadata;
use pipe::pipe; use pipe::pipe;
use rspirv::dr::{Loader, Module}; use rspirv::dr::{Loader, Module};
use rustc_errors::registry::Registry; use rustc_errors::registry::Registry;
use std::io::Read; use rustc_span::edition::Edition;
use std::{io::Read, thread};
// https://github.com/colin-kiegel/rust-pretty-assertions/issues/24 // https://github.com/colin-kiegel/rust-pretty-assertions/issues/24
#[derive(PartialEq, Eq)] #[derive(PartialEq, Eq)]
@ -54,6 +55,43 @@ fn load(bytes: &[u8]) -> Module {
loader.module() loader.module()
} }
// HACK(shesp) This function was taken from `rustc_interface::util` since it's
// no longer public. It's the non-parallel version since it's simpler and good
// enough for our tests.
fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
edition: Edition,
_threads: usize,
f: F,
) -> R {
// The "thread pool" is a single spawned thread in the non-parallel
// compiler. We run on a spawned thread instead of the main thread (a) to
// provide control over the stack size, and (b) to increase similarity with
// the parallel compiler, in particular to ensure there is no accidental
// sharing of data between the main thread and the compilation thread
// (which might cause problems for the parallel compiler).
let mut builder = thread::Builder::new().name("rustc".to_string());
const STACK_SIZE: usize = 8 * 1024 * 1024;
builder = builder.stack_size(STACK_SIZE);
// We build the session globals and run `f` on the spawned thread, because
// `SessionGlobals` does not impl `Send` in the non-parallel compiler.
thread::scope(|s| {
// `unwrap` is ok here because `spawn_scoped` only panics if the thread
// name contains null bytes.
let r = builder
.spawn_scoped(s, move || {
rustc_span::create_session_globals_then(edition, f)
})
.unwrap()
.join();
match r {
Ok(v) => v,
Err(e) => std::panic::resume_unwind(e),
}
})
}
fn assemble_and_link(binaries: &[&[u8]]) -> Result<Module, PrettyString> { fn assemble_and_link(binaries: &[&[u8]]) -> Result<Module, PrettyString> {
let modules = binaries.iter().cloned().map(load).collect::<Vec<_>>(); let modules = binaries.iter().cloned().map(load).collect::<Vec<_>>();
@ -80,67 +118,62 @@ fn assemble_and_link(binaries: &[&[u8]]) -> Result<Module, PrettyString> {
let matches = rustc_driver::handle_options(&["".to_string(), "x.rs".to_string()]).unwrap(); let matches = rustc_driver::handle_options(&["".to_string(), "x.rs".to_string()]).unwrap();
let sopts = rustc_session::config::build_session_options(&matches); let sopts = rustc_session::config::build_session_options(&matches);
rustc_interface::util::run_in_thread_pool_with_globals( run_in_thread_pool_with_globals(sopts.edition, sopts.unstable_opts.threads, || {
sopts.edition, let mut sess = rustc_session::build_session(
sopts.unstable_opts.threads, sopts,
|| { None,
let mut sess = rustc_session::build_session( None,
sopts, Registry::new(&[]),
None, Default::default(),
None, None,
Registry::new(&[]), None,
rustc_session::DiagnosticOutput::Default, );
Default::default(),
None,
None,
);
// HACK(eddyb) inject `write_diags` into `sess`, to work around // HACK(eddyb) inject `write_diags` into `sess`, to work around
// the removals in https://github.com/rust-lang/rust/pull/102992. // the removals in https://github.com/rust-lang/rust/pull/102992.
sess.parse_sess.span_diagnostic = { sess.parse_sess.span_diagnostic = {
let fallback_bundle = { let fallback_bundle = {
extern crate rustc_error_messages; extern crate rustc_error_messages;
rustc_error_messages::fallback_fluent_bundle( rustc_error_messages::fallback_fluent_bundle(
rustc_errors::DEFAULT_LOCALE_RESOURCES, rustc_errors::DEFAULT_LOCALE_RESOURCES,
sess.opts.unstable_opts.translate_directionality_markers, sess.opts.unstable_opts.translate_directionality_markers,
)
};
let emitter = rustc_errors::emitter::EmitterWriter::new(
Box::new(write_diags),
Some(sess.parse_sess.clone_source_map()),
None,
fallback_bundle,
false,
false,
false,
None,
false,
);
rustc_errors::Handler::with_emitter_and_flags(
Box::new(emitter),
sess.opts.unstable_opts.diagnostic_handler_flags(true),
) )
}; };
let emitter = rustc_errors::emitter::EmitterWriter::new(
let res = link( Box::new(write_diags),
&sess, Some(sess.parse_sess.clone_source_map()),
modules, None,
&Options { fallback_bundle,
compact_ids: true, false,
dce: false, false,
structurize: false, false,
emit_multiple_modules: false, None,
spirv_metadata: SpirvMetadata::None, false,
},
); );
assert_eq!(sess.has_errors(), res.as_ref().err().copied());
res.map(|res| match res { rustc_errors::Handler::with_emitter_and_flags(
LinkResult::SingleModule(m) => *m, Box::new(emitter),
LinkResult::MultipleModules(_) => unreachable!(), sess.opts.unstable_opts.diagnostic_handler_flags(true),
}) )
}, };
)
let res = link(
&sess,
modules,
&Options {
compact_ids: true,
dce: false,
structurize: false,
emit_multiple_modules: false,
spirv_metadata: SpirvMetadata::None,
},
);
assert_eq!(sess.has_errors(), res.as_ref().err().copied());
res.map(|res| match res {
LinkResult::SingleModule(m) => *m,
LinkResult::MultipleModules(_) => unreachable!(),
})
})
}) })
.flatten() .flatten()
.map_err(|_e| read_diags_thread.join().unwrap()) .map_err(|_e| read_diags_thread.join().unwrap())