From bb45f5db78f00cbacf90d880eabf2def0a625048 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 25 Jun 2021 12:49:29 +0200 Subject: [PATCH 1/3] Remove the RustcDefaultCalls struct It is a leftover from before the introduction of rustc_interface --- compiler/rustc_driver/src/lib.rs | 289 +++++++++++++++---------------- 1 file changed, 138 insertions(+), 151 deletions(-) diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index ca4e7b5142ee7..7eeae66d709e9 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -263,7 +263,7 @@ fn run_compiler( describe_lints(compiler.session(), &lint_store, registered_lints); return; } - let should_stop = RustcDefaultCalls::print_crate_info( + let should_stop = print_crate_info( &***compiler.codegen_backend(), compiler.session(), None, @@ -292,7 +292,7 @@ fn run_compiler( interface::run_compiler(config, |compiler| { let sess = compiler.session(); - let should_stop = RustcDefaultCalls::print_crate_info( + let should_stop = print_crate_info( &***compiler.codegen_backend(), sess, Some(compiler.input()), @@ -301,13 +301,9 @@ fn run_compiler( compiler.temps_dir(), ) .and_then(|| { - RustcDefaultCalls::list_metadata( - sess, - &*compiler.codegen_backend().metadata_loader(), - compiler.input(), - ) + list_metadata(sess, &*compiler.codegen_backend().metadata_loader(), compiler.input()) }) - .and_then(|| RustcDefaultCalls::try_process_rlink(sess, compiler)); + .and_then(|| try_process_rlink(sess, compiler)); if should_stop == Compilation::Stop { return sess.compile_status(); @@ -512,10 +508,6 @@ impl Compilation { } } -/// CompilerCalls instance for a regular rustc build. -#[derive(Copy, Clone)] -pub struct RustcDefaultCalls; - fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) { let upper_cased_code = code.to_ascii_uppercase(); let normalised = if upper_cased_code.starts_with('E') { @@ -588,162 +580,157 @@ fn show_content_with_pager(content: &str) { } } -impl RustcDefaultCalls { - pub fn try_process_rlink(sess: &Session, compiler: &interface::Compiler) -> Compilation { - if sess.opts.debugging_opts.link_only { - if let Input::File(file) = compiler.input() { - // FIXME: #![crate_type] and #![crate_name] support not implemented yet - sess.init_crate_types(collect_crate_types(sess, &[])); - let outputs = compiler.build_output_filenames(sess, &[]); - let rlink_data = fs::read(file).unwrap_or_else(|err| { - sess.fatal(&format!("failed to read rlink file: {}", err)); - }); - let mut decoder = rustc_serialize::opaque::Decoder::new(&rlink_data, 0); - let codegen_results: CodegenResults = - rustc_serialize::Decodable::decode(&mut decoder); - let result = compiler.codegen_backend().link(sess, codegen_results, &outputs); - abort_on_err(result, sess); - } else { - sess.fatal("rlink must be a file") - } - Compilation::Stop +pub fn try_process_rlink(sess: &Session, compiler: &interface::Compiler) -> Compilation { + if sess.opts.debugging_opts.link_only { + if let Input::File(file) = compiler.input() { + // FIXME: #![crate_type] and #![crate_name] support not implemented yet + sess.init_crate_types(collect_crate_types(sess, &[])); + let outputs = compiler.build_output_filenames(sess, &[]); + let rlink_data = fs::read(file).unwrap_or_else(|err| { + sess.fatal(&format!("failed to read rlink file: {}", err)); + }); + let mut decoder = rustc_serialize::opaque::Decoder::new(&rlink_data, 0); + let codegen_results: CodegenResults = rustc_serialize::Decodable::decode(&mut decoder); + let result = compiler.codegen_backend().link(sess, codegen_results, &outputs); + abort_on_err(result, sess); } else { - Compilation::Continue + sess.fatal("rlink must be a file") } + Compilation::Stop + } else { + Compilation::Continue } +} - pub fn list_metadata( - sess: &Session, - metadata_loader: &dyn MetadataLoader, - input: &Input, - ) -> Compilation { - if sess.opts.debugging_opts.ls { - match *input { - Input::File(ref ifile) => { - let path = &(*ifile); - let mut v = Vec::new(); - locator::list_file_metadata(&sess.target, path, metadata_loader, &mut v) - .unwrap(); - println!("{}", String::from_utf8(v).unwrap()); - } - Input::Str { .. } => { - early_error(ErrorOutputType::default(), "cannot list metadata for stdin"); - } +pub fn list_metadata( + sess: &Session, + metadata_loader: &dyn MetadataLoader, + input: &Input, +) -> Compilation { + if sess.opts.debugging_opts.ls { + match *input { + Input::File(ref ifile) => { + let path = &(*ifile); + let mut v = Vec::new(); + locator::list_file_metadata(&sess.target, path, metadata_loader, &mut v).unwrap(); + println!("{}", String::from_utf8(v).unwrap()); + } + Input::Str { .. } => { + early_error(ErrorOutputType::default(), "cannot list metadata for stdin"); } - return Compilation::Stop; } - - Compilation::Continue + return Compilation::Stop; } - fn print_crate_info( - codegen_backend: &dyn CodegenBackend, - sess: &Session, - input: Option<&Input>, - odir: &Option, - ofile: &Option, - temps_dir: &Option, - ) -> Compilation { - use rustc_session::config::PrintRequest::*; - // NativeStaticLibs and LinkArgs are special - printed during linking - // (empty iterator returns true) - if sess.opts.prints.iter().all(|&p| p == NativeStaticLibs || p == LinkArgs) { - return Compilation::Continue; - } + Compilation::Continue +} - let attrs = match input { - None => None, - Some(input) => { - let result = parse_crate_attrs(sess, input); - match result { - Ok(attrs) => Some(attrs), - Err(mut parse_error) => { - parse_error.emit(); - return Compilation::Stop; - } +fn print_crate_info( + codegen_backend: &dyn CodegenBackend, + sess: &Session, + input: Option<&Input>, + odir: &Option, + ofile: &Option, + temps_dir: &Option, +) -> Compilation { + use rustc_session::config::PrintRequest::*; + // NativeStaticLibs and LinkArgs are special - printed during linking + // (empty iterator returns true) + if sess.opts.prints.iter().all(|&p| p == NativeStaticLibs || p == LinkArgs) { + return Compilation::Continue; + } + + let attrs = match input { + None => None, + Some(input) => { + let result = parse_crate_attrs(sess, input); + match result { + Ok(attrs) => Some(attrs), + Err(mut parse_error) => { + parse_error.emit(); + return Compilation::Stop; } } - }; - for req in &sess.opts.prints { - match *req { - TargetList => { - let mut targets = - rustc_target::spec::TARGETS.iter().copied().collect::>(); - targets.sort_unstable(); - println!("{}", targets.join("\n")); - } - Sysroot => println!("{}", sess.sysroot.display()), - TargetLibdir => println!("{}", sess.target_tlib_path.dir.display()), - TargetSpec => println!("{}", sess.target.to_json().pretty()), - FileNames | CrateName => { - let input = input.unwrap_or_else(|| { - early_error(ErrorOutputType::default(), "no input file provided") - }); - let attrs = attrs.as_ref().unwrap(); - let t_outputs = rustc_interface::util::build_output_filenames( - input, odir, ofile, temps_dir, attrs, sess, - ); - let id = rustc_session::output::find_crate_name(sess, attrs, input); - if *req == PrintRequest::CrateName { - println!("{}", id); - continue; - } - let crate_types = collect_crate_types(sess, attrs); - for &style in &crate_types { - let fname = - rustc_session::output::filename_for_input(sess, style, &id, &t_outputs); - println!("{}", fname.file_name().unwrap().to_string_lossy()); - } + } + }; + for req in &sess.opts.prints { + match *req { + TargetList => { + let mut targets = rustc_target::spec::TARGETS.iter().copied().collect::>(); + targets.sort_unstable(); + println!("{}", targets.join("\n")); + } + Sysroot => println!("{}", sess.sysroot.display()), + TargetLibdir => println!("{}", sess.target_tlib_path.dir.display()), + TargetSpec => println!("{}", sess.target.to_json().pretty()), + FileNames | CrateName => { + let input = input.unwrap_or_else(|| { + early_error(ErrorOutputType::default(), "no input file provided") + }); + let attrs = attrs.as_ref().unwrap(); + let t_outputs = rustc_interface::util::build_output_filenames( + input, odir, ofile, temps_dir, attrs, sess, + ); + let id = rustc_session::output::find_crate_name(sess, attrs, input); + if *req == PrintRequest::CrateName { + println!("{}", id); + continue; } - Cfg => { - let mut cfgs = sess - .parse_sess - .config - .iter() - .filter_map(|&(name, value)| { - // Note that crt-static is a specially recognized cfg - // directive that's printed out here as part of - // rust-lang/rust#37406, but in general the - // `target_feature` cfg is gated under - // rust-lang/rust#29717. For now this is just - // specifically allowing the crt-static cfg and that's - // it, this is intended to get into Cargo and then go - // through to build scripts. - if (name != sym::target_feature || value != Some(sym::crt_dash_static)) - && !sess.is_nightly_build() - && find_gated_cfg(|cfg_sym| cfg_sym == name).is_some() - { - return None; - } - - if let Some(value) = value { - Some(format!("{}=\"{}\"", name, value)) - } else { - Some(name.to_string()) - } - }) - .collect::>(); - - cfgs.sort(); - for cfg in cfgs { - println!("{}", cfg); - } + let crate_types = collect_crate_types(sess, attrs); + for &style in &crate_types { + let fname = + rustc_session::output::filename_for_input(sess, style, &id, &t_outputs); + println!("{}", fname.file_name().unwrap().to_string_lossy()); } - RelocationModels - | CodeModels - | TlsModels - | TargetCPUs - | StackProtectorStrategies - | TargetFeatures => { - codegen_backend.print(*req, sess); + } + Cfg => { + let mut cfgs = sess + .parse_sess + .config + .iter() + .filter_map(|&(name, value)| { + // Note that crt-static is a specially recognized cfg + // directive that's printed out here as part of + // rust-lang/rust#37406, but in general the + // `target_feature` cfg is gated under + // rust-lang/rust#29717. For now this is just + // specifically allowing the crt-static cfg and that's + // it, this is intended to get into Cargo and then go + // through to build scripts. + if (name != sym::target_feature || value != Some(sym::crt_dash_static)) + && !sess.is_nightly_build() + && find_gated_cfg(|cfg_sym| cfg_sym == name).is_some() + { + return None; + } + + if let Some(value) = value { + Some(format!("{}=\"{}\"", name, value)) + } else { + Some(name.to_string()) + } + }) + .collect::>(); + + cfgs.sort(); + for cfg in cfgs { + println!("{}", cfg); } - // Any output here interferes with Cargo's parsing of other printed output - NativeStaticLibs => {} - LinkArgs => {} } + RelocationModels + | CodeModels + | TlsModels + | TargetCPUs + | StackProtectorStrategies + | TargetFeatures => { + codegen_backend.print(*req, sess); + } + // Any output here interferes with Cargo's parsing of other printed output + NativeStaticLibs => {} + LinkArgs => {} } - Compilation::Stop } + Compilation::Stop } /// Prints version information From 5730173763b32ada60d7653ca987562ba0dc66f6 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 25 Jun 2021 13:03:39 +0200 Subject: [PATCH 2/3] Move setup_callbacks call to create_compiler_and_run This ensures that it is called even when run_in_thread_pool_with_globals is avoided and reduces code duplication between the parallel and non-parallel version of run_in_thread_pool_with_globals --- compiler/rustc_interface/src/interface.rs | 4 +++- compiler/rustc_interface/src/lib.rs | 1 + compiler/rustc_interface/src/util.rs | 8 ++------ src/librustdoc/lib.rs | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 237aef1cf23aa..8bd24487b7843 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -186,6 +186,8 @@ pub struct Config { } pub fn create_compiler_and_run(config: Config, f: impl FnOnce(&Compiler) -> R) -> R { + crate::callbacks::setup_callbacks(); + let registry = &config.registry; let (mut sess, codegen_backend) = util::create_session( config.opts, @@ -238,7 +240,7 @@ pub fn create_compiler_and_run(config: Config, f: impl FnOnce(&Compiler) -> R pub fn run_compiler(mut config: Config, f: impl FnOnce(&Compiler) -> R + Send) -> R { tracing::trace!("run_compiler"); let stderr = config.stderr.take(); - util::setup_callbacks_and_run_in_thread_pool_with_globals( + util::run_in_thread_pool_with_globals( config.opts.edition, config.opts.debugging_opts.threads, &stderr, diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs index eebeabbd45272..dcad3036cc24d 100644 --- a/compiler/rustc_interface/src/lib.rs +++ b/compiler/rustc_interface/src/lib.rs @@ -15,6 +15,7 @@ mod proc_macro_decls; mod queries; pub mod util; +pub use callbacks::setup_callbacks; pub use interface::{run_compiler, Config}; pub use passes::{DEFAULT_EXTERN_QUERY_PROVIDERS, DEFAULT_QUERY_PROVIDERS}; pub use queries::Queries; diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index f74cadfebacba..d206f2644e02a 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -128,7 +128,7 @@ fn scoped_thread R + Send, R: Send>(cfg: thread::Builder, f: F) - } #[cfg(not(parallel_compiler))] -pub fn setup_callbacks_and_run_in_thread_pool_with_globals R + Send, R: Send>( +pub fn run_in_thread_pool_with_globals R + Send, R: Send>( edition: Edition, _threads: usize, stderr: &Option>>>, @@ -140,8 +140,6 @@ pub fn setup_callbacks_and_run_in_thread_pool_with_globals R + Se cfg = cfg.stack_size(size); } - crate::callbacks::setup_callbacks(); - let main_handler = move || { rustc_span::create_session_globals_then(edition, || { io::set_output_capture(stderr.clone()); @@ -176,14 +174,12 @@ unsafe fn handle_deadlock() { } #[cfg(parallel_compiler)] -pub fn setup_callbacks_and_run_in_thread_pool_with_globals R + Send, R: Send>( +pub fn run_in_thread_pool_with_globals R + Send, R: Send>( edition: Edition, threads: usize, stderr: &Option>>>, f: F, ) -> R { - crate::callbacks::setup_callbacks(); - let mut config = rayon::ThreadPoolBuilder::new() .thread_name(|_| "rustc".to_string()) .acquire_thread_handler(jobserver::acquire_thread) diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 68028604fa463..c320516504017 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -688,7 +688,7 @@ fn main_args(at_args: &[String]) -> MainResult { Ok(opts) => opts, Err(code) => return if code == 0 { Ok(()) } else { Err(ErrorReported) }, }; - rustc_interface::util::setup_callbacks_and_run_in_thread_pool_with_globals( + rustc_interface::util::run_in_thread_pool_with_globals( options.edition, 1, // this runs single-threaded, even in a parallel compiler &None, From f45ba82370f580fba0f1486f745607d7d30ef330 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 14 Jan 2022 19:34:01 +0100 Subject: [PATCH 3/3] Remove SPAN_DEBUG global The only difference between the default and rustc_interface set version is that the default accesses the source map from SESSION_GLOBALS while the rustc_interface version accesses the source map from the global TyCtxt. SESSION_GLOBALS is always set while running the compiler while the global TyCtxt is not always set. If the global TyCtxt is set, it's source map is identical to the one in SESSION_GLOBALS --- compiler/rustc_interface/src/callbacks.rs | 15 +-------- compiler/rustc_span/src/lib.rs | 38 +++++++---------------- 2 files changed, 13 insertions(+), 40 deletions(-) diff --git a/compiler/rustc_interface/src/callbacks.rs b/compiler/rustc_interface/src/callbacks.rs index 3c7908fae79be..a18e2d1d63887 100644 --- a/compiler/rustc_interface/src/callbacks.rs +++ b/compiler/rustc_interface/src/callbacks.rs @@ -4,7 +4,7 @@ //! `rustc_data_structures::AtomicRef` type, which allows us to setup a global //! static which can then be set in this file at program startup. //! -//! See `SPAN_DEBUG` for an example of how to set things up. +//! See `SPAN_TRACK` for an example of how to set things up. //! //! The functions in this file should fall back to the default set in their //! origin crate when the `TyCtxt` is not present in TLS. @@ -13,18 +13,6 @@ use rustc_errors::{Diagnostic, TRACK_DIAGNOSTICS}; use rustc_middle::ty::tls; use std::fmt; -/// This is a callback from `rustc_ast` as it cannot access the implicit state -/// in `rustc_middle` otherwise. -fn span_debug(span: rustc_span::Span, f: &mut fmt::Formatter<'_>) -> fmt::Result { - tls::with_opt(|tcx| { - if let Some(tcx) = tcx { - rustc_span::debug_with_source_map(span, f, tcx.sess.source_map()) - } else { - rustc_span::default_span_debug(span, f) - } - }) -} - fn track_span_parent(def_id: rustc_span::def_id::LocalDefId) { tls::with_opt(|tcx| { if let Some(tcx) = tcx { @@ -65,7 +53,6 @@ fn def_id_debug(def_id: rustc_hir::def_id::DefId, f: &mut fmt::Formatter<'_>) -> /// Sets up the callbacks in prior crates which we want to refer to the /// TyCtxt in. pub fn setup_callbacks() { - rustc_span::SPAN_DEBUG.swap(&(span_debug as fn(_, &mut fmt::Formatter<'_>) -> _)); rustc_span::SPAN_TRACK.swap(&(track_span_parent as fn(_))); rustc_hir::def_id::DEF_ID_DEBUG.swap(&(def_id_debug as fn(_, &mut fmt::Formatter<'_>) -> _)); TRACK_DIAGNOSTICS.swap(&(track_diagnostic as fn(&_))); diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 823a927fd8c74..3ce9f852c3d0f 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -1013,37 +1013,25 @@ pub fn with_source_map T>(source_map: Lrc, f: F) -> f() } -pub fn debug_with_source_map( - span: Span, - f: &mut fmt::Formatter<'_>, - source_map: &SourceMap, -) -> fmt::Result { - write!(f, "{} ({:?})", source_map.span_to_diagnostic_string(span), span.ctxt()) -} - -pub fn default_span_debug(span: Span, f: &mut fmt::Formatter<'_>) -> fmt::Result { - with_session_globals(|session_globals| { - if let Some(source_map) = &*session_globals.source_map.borrow() { - debug_with_source_map(span, f, source_map) - } else { - f.debug_struct("Span") - .field("lo", &span.lo()) - .field("hi", &span.hi()) - .field("ctxt", &span.ctxt()) - .finish() - } - }) -} - impl fmt::Debug for Span { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - (*SPAN_DEBUG)(*self, f) + with_session_globals(|session_globals| { + if let Some(source_map) = &*session_globals.source_map.borrow() { + write!(f, "{} ({:?})", source_map.span_to_diagnostic_string(*self), self.ctxt()) + } else { + f.debug_struct("Span") + .field("lo", &self.lo()) + .field("hi", &self.hi()) + .field("ctxt", &self.ctxt()) + .finish() + } + }) } } impl fmt::Debug for SpanData { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - (*SPAN_DEBUG)(Span::new(self.lo, self.hi, self.ctxt, self.parent), f) + fmt::Debug::fmt(&Span::new(self.lo, self.hi, self.ctxt, self.parent), f) } } @@ -2003,8 +1991,6 @@ pub struct FileLines { pub lines: Vec, } -pub static SPAN_DEBUG: AtomicRef) -> fmt::Result> = - AtomicRef::new(&(default_span_debug as fn(_, &mut fmt::Formatter<'_>) -> _)); pub static SPAN_TRACK: AtomicRef = AtomicRef::new(&((|_| {}) as fn(_))); // _____________________________________________________________________________