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 | 315 +++++++++++++++---------------- 1 file changed, 151 insertions(+), 164 deletions(-) diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index ca4e7b5142ee..7eeae66d709e 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,164 +580,159 @@ 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 - } - } - - 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 - } - - 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()); - } - } - 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); - } - } - 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 => {} - } + 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"); + } + } + return Compilation::Stop; + } + + Compilation::Continue +} + +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()); + } + } + 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); + } + } + 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 +} + /// Prints version information pub fn version(binary: &str, matches: &getopts::Matches) { let verbose = matches.opt_present("verbose"); 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 237aef1cf23a..8bd24487b784 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 eebeabbd4527..dcad3036cc24 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 f74cadfebacb..d206f2644e02 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 68028604fa46..c32051650401 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 3c7908fae79b..a18e2d1d6388 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 823a927fd8c7..3ce9f852c3d0 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(_))); // _____________________________________________________________________________