From 9e9c871a7842bed0ed566d0ee0726658036d1c1e Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 6 Dec 2022 15:07:00 +0000 Subject: [PATCH 1/9] Remove `prepare_outputs` --- compiler/rustc_driver/src/lib.rs | 4 +--- compiler/rustc_interface/src/queries.rs | 28 ++++++++----------------- 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index a62e5dec4b864..c56443512f4d2 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -362,7 +362,7 @@ fn run_compiler( return early_exit(); } - queries.prepare_outputs()?; + queries.global_ctxt()?; if sess.opts.output_types.contains_key(&OutputType::DepInfo) && sess.opts.output_types.len() == 1 @@ -370,8 +370,6 @@ fn run_compiler( return early_exit(); } - queries.global_ctxt()?; - if sess.opts.unstable_opts.no_analysis { return early_exit(); } diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 041bb9eb7a1cb..cb07688e2f508 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -90,7 +90,6 @@ pub struct Queries<'tcx> { register_plugins: Query<(ast::Crate, Lrc)>, expansion: Query<(Lrc, Rc>, Lrc)>, dep_graph: Query, - prepare_outputs: Query, global_ctxt: Query>, ongoing_codegen: Query>, } @@ -109,7 +108,6 @@ impl<'tcx> Queries<'tcx> { register_plugins: Default::default(), expansion: Default::default(), dep_graph: Default::default(), - prepare_outputs: Default::default(), global_ctxt: Default::default(), ongoing_codegen: Default::default(), } @@ -211,32 +209,24 @@ impl<'tcx> Queries<'tcx> { }) } - pub fn prepare_outputs(&self) -> Result> { - self.prepare_outputs.compute(|| { - let expansion = self.expansion()?; - let (krate, boxed_resolver, _) = &*expansion.borrow(); + pub fn global_ctxt(&'tcx self) -> Result>> { + self.global_ctxt.compute(|| { let crate_name = *self.crate_name()?.borrow(); - passes::prepare_outputs( + let (krate, resolver, lint_store) = self.expansion()?.steal(); + + let outputs = passes::prepare_outputs( self.session(), self.compiler, - krate, - &*boxed_resolver, + &krate, + &resolver, crate_name, - ) - }) - } + )?; - pub fn global_ctxt(&'tcx self) -> Result>> { - self.global_ctxt.compute(|| { - let crate_name = *self.crate_name()?.borrow(); - let outputs = self.prepare_outputs()?.steal(); - let dep_graph = self.dep_graph()?.borrow().clone(); - let (krate, resolver, lint_store) = self.expansion()?.steal(); Ok(passes::create_global_ctxt( self.compiler, lint_store, krate, - dep_graph, + self.dep_graph()?.steal(), resolver, outputs, crate_name, From 6b1a789fb69f832d2b3df53b9e42c08c919c7487 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 6 Dec 2022 15:43:52 +0000 Subject: [PATCH 2/9] remove some arguments that can also be fed at the caller side --- compiler/rustc_interface/src/passes.rs | 30 +++---------------------- compiler/rustc_interface/src/queries.rs | 30 +++++++++++++++++++------ 2 files changed, 26 insertions(+), 34 deletions(-) diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 50c40206d8026..5dd758c94512f 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -13,7 +13,6 @@ use rustc_ast::{self as ast, visit}; use rustc_borrowck as mir_borrowck; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_data_structures::parallel; -use rustc_data_structures::steal::Steal; use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal}; use rustc_errors::{ErrorGuaranteed, PResult}; use rustc_expand::base::{ExtCtxt, LintStoreExpand, ResolverExpand}; @@ -31,7 +30,7 @@ use rustc_plugin_impl as plugin; use rustc_query_impl::{OnDiskCache, Queries as TcxQueries}; use rustc_resolve::{Resolver, ResolverArenas}; use rustc_session::config::{CrateType, Input, OutputFilenames, OutputType}; -use rustc_session::cstore::{MetadataLoader, MetadataLoaderDyn}; +use rustc_session::cstore::{MetadataLoader, MetadataLoaderDyn, Untracked}; use rustc_session::output::filename_for_input; use rustc_session::search_paths::PathKind; use rustc_session::{Limit, Session}; @@ -775,11 +774,8 @@ impl<'tcx> QueryContext<'tcx> { pub fn create_global_ctxt<'tcx>( compiler: &'tcx Compiler, lint_store: Lrc, - krate: Lrc, dep_graph: DepGraph, - resolver: Rc>, - outputs: OutputFilenames, - crate_name: Symbol, + untracked: Untracked, queries: &'tcx OnceCell>, global_ctxt: &'tcx OnceCell>, arena: &'tcx WorkerLocal>, @@ -790,8 +786,6 @@ pub fn create_global_ctxt<'tcx>( // incr. comp. yet. dep_graph.assert_ignored(); - let resolver_outputs = BoxedResolver::to_resolver_outputs(resolver); - let sess = &compiler.session(); let query_result_on_disk_cache = rustc_incremental::load_query_result_cache(sess); @@ -810,12 +804,6 @@ pub fn create_global_ctxt<'tcx>( TcxQueries::new(local_providers, extern_providers, query_result_on_disk_cache) }); - let ty::ResolverOutputs { - global_ctxt: untracked_resolutions, - ast_lowering: untracked_resolver_for_lowering, - untracked, - } = resolver_outputs; - let gcx = sess.time("setup_global_ctxt", || { global_ctxt.get_or_init(move || { TyCtxt::create_global_ctxt( @@ -832,19 +820,7 @@ pub fn create_global_ctxt<'tcx>( }) }); - let mut qcx = QueryContext { gcx }; - qcx.enter(|tcx| { - let feed = tcx.feed_unit_query(); - feed.resolver_for_lowering( - tcx.arena.alloc(Steal::new((untracked_resolver_for_lowering, krate))), - ); - feed.resolutions(tcx.arena.alloc(untracked_resolutions)); - feed.output_filenames(tcx.arena.alloc(std::sync::Arc::new(outputs))); - feed.features_query(sess.features_untracked()); - let feed = tcx.feed_local_crate(); - feed.crate_name(crate_name); - }); - qcx + QueryContext { gcx } } /// Runs the resolution, type-checking, region checking and other diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index cb07688e2f508..6f791c8893ce3 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -13,7 +13,7 @@ use rustc_incremental::DepGraphFuture; use rustc_lint::LintStore; use rustc_middle::arena::Arena; use rustc_middle::dep_graph::DepGraph; -use rustc_middle::ty::{GlobalCtxt, TyCtxt}; +use rustc_middle::ty::{self, GlobalCtxt, TyCtxt}; use rustc_query_impl::Queries as TcxQueries; use rustc_session::config::{self, OutputFilenames, OutputType}; use rustc_session::{output::find_crate_name, Session}; @@ -222,19 +222,35 @@ impl<'tcx> Queries<'tcx> { crate_name, )?; - Ok(passes::create_global_ctxt( + let ty::ResolverOutputs { + untracked, + global_ctxt: untracked_resolutions, + ast_lowering: untracked_resolver_for_lowering, + } = BoxedResolver::to_resolver_outputs(resolver); + + let mut qcx = passes::create_global_ctxt( self.compiler, lint_store, - krate, self.dep_graph()?.steal(), - resolver, - outputs, - crate_name, + untracked, &self.queries, &self.gcx, &self.arena, &self.hir_arena, - )) + ); + + qcx.enter(|tcx| { + let feed = tcx.feed_unit_query(); + feed.resolver_for_lowering( + tcx.arena.alloc(Steal::new((untracked_resolver_for_lowering, krate))), + ); + feed.resolutions(tcx.arena.alloc(untracked_resolutions)); + feed.output_filenames(tcx.arena.alloc(std::sync::Arc::new(outputs))); + feed.features_query(tcx.sess.features_untracked()); + let feed = tcx.feed_local_crate(); + feed.crate_name(crate_name); + }); + Ok(qcx) }) } From f5c601492ee520d2ee4f6c133f7f4dfa7b0c13e2 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 6 Dec 2022 18:56:28 +0000 Subject: [PATCH 3/9] Remove redundant `input_path` field from `Config` --- compiler/rustc_driver/src/lib.rs | 12 +++++------- compiler/rustc_interface/src/interface.rs | 5 +---- compiler/rustc_interface/src/passes.rs | 2 +- compiler/rustc_session/src/config.rs | 18 ++++++++++++++++++ src/librustdoc/core.rs | 2 -- src/librustdoc/doctest.rs | 1 - 6 files changed, 25 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index c56443512f4d2..ec46fc8999a17 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -219,7 +219,6 @@ fn run_compiler( crate_cfg: cfg, crate_check_cfg: check_cfg, input: Input::File(PathBuf::new()), - input_path: None, output_file: ofile, output_dir: odir, file_loader, @@ -237,9 +236,8 @@ fn run_compiler( match make_input(config.opts.error_format, &matches.free) { Err(reported) => return Err(reported), - Ok(Some((input, input_file_path))) => { + Ok(Some(input)) => { config.input = input; - config.input_path = input_file_path; callbacks.config(&mut config); } @@ -437,7 +435,7 @@ fn make_output(matches: &getopts::Matches) -> (Option, Option) fn make_input( error_format: ErrorOutputType, free_matches: &[String], -) -> Result)>, ErrorGuaranteed> { +) -> Result, ErrorGuaranteed> { if free_matches.len() == 1 { let ifile = &free_matches[0]; if ifile == "-" { @@ -459,12 +457,12 @@ fn make_input( let line = isize::from_str_radix(&line, 10) .expect("UNSTABLE_RUSTDOC_TEST_LINE needs to be an number"); let file_name = FileName::doc_test_source_code(PathBuf::from(path), line); - Ok(Some((Input::Str { name: file_name, input: src }, None))) + Ok(Some(Input::Str { name: file_name, input: src })) } else { - Ok(Some((Input::Str { name: FileName::anon_source_code(&src), input: src }, None))) + Ok(Some(Input::Str { name: FileName::anon_source_code(&src), input: src })) } } else { - Ok(Some((Input::File(PathBuf::from(ifile)), Some(PathBuf::from(ifile))))) + Ok(Some(Input::File(PathBuf::from(ifile)))) } } else { Ok(None) diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 7f761b005edd0..22a01db5e7573 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -36,7 +36,6 @@ pub struct Compiler { pub(crate) sess: Lrc, codegen_backend: Lrc>, pub(crate) input: Input, - pub(crate) input_path: Option, pub(crate) output_dir: Option, pub(crate) output_file: Option, pub(crate) temps_dir: Option, @@ -244,7 +243,6 @@ pub struct Config { pub crate_check_cfg: CheckCfg, pub input: Input, - pub input_path: Option, pub output_dir: Option, pub output_file: Option, pub file_loader: Option>, @@ -292,7 +290,7 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se config.crate_cfg, config.crate_check_cfg, config.file_loader, - config.input_path.clone(), + config.input.opt_path(), config.lint_caps, config.make_codegen_backend, registry.clone(), @@ -308,7 +306,6 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se sess: Lrc::new(sess), codegen_backend: Lrc::new(codegen_backend), input: config.input, - input_path: config.input_path, output_dir: config.output_dir, output_file: config.output_file, temps_dir, diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 5dd758c94512f..bba0a50a93fae 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -686,7 +686,7 @@ pub fn prepare_outputs( generated_output_paths(sess, &outputs, compiler.output_file.is_some(), crate_name); // Ensure the source file isn't accidentally overwritten during compilation. - if let Some(ref input_path) = compiler.input_path { + if let Some(ref input_path) = compiler.input.opt_path() { if sess.opts.will_create_output_file() { if output_contains_path(&output_paths, input_path) { let reported = sess.emit_err(InputFileWouldBeOverWritten { path: input_path }); diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 55576b4e0d19d..2679164b927e5 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -591,6 +591,24 @@ impl Input { Input::Str { ref name, .. } => name.clone(), } } + + pub fn opt_path(&self) -> Option { + match self { + Input::File(file) => Some(file.clone()), + Input::Str { name, .. } => match name { + FileName::Real(real) => real.local_path().map(|p| p.to_owned()), + FileName::QuoteExpansion(_) => None, + FileName::Anon(_) => None, + FileName::MacroExpansion(_) => None, + FileName::ProcMacroSourceCode(_) => None, + FileName::CfgSpec(_) => None, + FileName::CliCrateAttr(_) => None, + FileName::Custom(_) => None, + FileName::DocTest(path, _) => Some(path.to_owned()), + FileName::InlineAsm(_) => None, + }, + } + } } #[derive(Clone, Hash, Debug, HashStable_Generic)] diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index da0df596c41e3..2153e7d8c9ad9 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -225,7 +225,6 @@ pub(crate) fn create_config( // Add the doc cfg into the doc build. cfgs.push("doc".to_string()); - let cpath = Some(input.clone()); let input = Input::File(input); // By default, rustdoc ignores all lints. @@ -277,7 +276,6 @@ pub(crate) fn create_config( crate_cfg: interface::parse_cfgspecs(cfgs), crate_check_cfg: interface::parse_check_cfg(check_cfgs), input, - input_path: cpath, output_file: None, output_dir: None, file_loader: None, diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index d1b6d470e86ce..c1a652c75f4a1 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -95,7 +95,6 @@ pub(crate) fn run(options: RustdocOptions) -> Result<(), ErrorGuaranteed> { crate_cfg: interface::parse_cfgspecs(cfgs), crate_check_cfg: interface::parse_check_cfg(options.check_cfgs.clone()), input, - input_path: None, output_file: None, output_dir: None, file_loader: None, From 42f75f1e462f90bfe20f458690113c3cb2a26271 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 7 Dec 2022 08:42:21 +0000 Subject: [PATCH 4/9] Group some commonly passed together values into a struct --- compiler/rustc_driver/src/lib.rs | 80 +++++++++-------------- compiler/rustc_driver/src/pretty.rs | 28 ++++---- compiler/rustc_interface/src/interface.rs | 44 +++++-------- compiler/rustc_interface/src/passes.rs | 17 ++--- compiler/rustc_interface/src/queries.rs | 4 +- compiler/rustc_interface/src/util.rs | 21 +++--- src/tools/miri/src/bin/miri.rs | 2 +- 7 files changed, 77 insertions(+), 119 deletions(-) diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index ec46fc8999a17..feb78cb0984e8 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -26,6 +26,7 @@ use rustc_errors::registry::{InvalidErrorCode, Registry}; use rustc_errors::{ErrorGuaranteed, PResult}; use rustc_feature::find_gated_cfg; use rustc_hir::def_id::LOCAL_CRATE; +use rustc_interface::interface::CompilerIO; use rustc_interface::util::{self, collect_crate_types, get_codegen_backend}; use rustc_interface::{interface, Queries}; use rustc_lint::LintStore; @@ -262,10 +263,8 @@ fn run_compiler( let should_stop = print_crate_info( &***compiler.codegen_backend(), compiler.session(), - None, - compiler.output_dir(), - compiler.output_file(), - compiler.temps_dir(), + false, + compiler.io(), ); if should_stop == Compilation::Stop { @@ -288,18 +287,16 @@ fn run_compiler( interface::run_compiler(config, |compiler| { let sess = compiler.session(); - let should_stop = print_crate_info( - &***compiler.codegen_backend(), - sess, - Some(compiler.input()), - compiler.output_dir(), - compiler.output_file(), - compiler.temps_dir(), - ) - .and_then(|| { - list_metadata(sess, &*compiler.codegen_backend().metadata_loader(), compiler.input()) - }) - .and_then(|| try_process_rlink(sess, compiler)); + let should_stop = + print_crate_info(&***compiler.codegen_backend(), sess, true, compiler.io()) + .and_then(|| { + list_metadata( + sess, + &*compiler.codegen_backend().metadata_loader(), + &compiler.io().input, + ) + }) + .and_then(|| try_process_rlink(sess, compiler)); if should_stop == Compilation::Stop { return sess.compile_status(); @@ -315,22 +312,15 @@ fn run_compiler( queries.global_ctxt()?.enter(|tcx| { pretty::print_after_hir_lowering( tcx, - compiler.input(), + compiler.io(), &*expanded_crate, *ppm, - compiler.output_file().as_deref(), ); Ok(()) })?; } else { let krate = queries.parse()?.steal(); - pretty::print_after_parsing( - sess, - compiler.input(), - &krate, - *ppm, - compiler.output_file().as_deref(), - ); + pretty::print_after_parsing(sess, compiler.io(), &krate, *ppm); } trace!("finished pretty-printing"); return early_exit(); @@ -380,9 +370,9 @@ fn run_compiler( save::process_crate( tcx, crate_name, - compiler.input(), + &compiler.io().input, None, - DumpHandler::new(compiler.output_dir().as_deref(), crate_name), + DumpHandler::new(compiler.io().output_dir.as_deref(), crate_name), ) }); } @@ -556,7 +546,7 @@ fn show_content_with_pager(content: &str) { pub fn try_process_rlink(sess: &Session, compiler: &interface::Compiler) -> Compilation { if sess.opts.unstable_opts.link_only { - if let Input::File(file) = compiler.input() { + if let Input::File(file) = &compiler.io().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, &[]); @@ -623,10 +613,8 @@ pub fn list_metadata( fn print_crate_info( codegen_backend: &dyn CodegenBackend, sess: &Session, - input: Option<&Input>, - odir: &Option, - ofile: &Option, - temps_dir: &Option, + parse_attrs: bool, + io: &CompilerIO, ) -> Compilation { use rustc_session::config::PrintRequest::*; // NativeStaticLibs and LinkArgs are special - printed during linking @@ -635,18 +623,17 @@ fn print_crate_info( 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; - } + let attrs = if parse_attrs { + let result = parse_crate_attrs(sess, &io.input); + match result { + Ok(attrs) => Some(attrs), + Err(mut parse_error) => { + parse_error.emit(); + return Compilation::Stop; } } + } else { + None }; for req in &sess.opts.prints { match *req { @@ -661,14 +648,9 @@ fn print_crate_info( println!("{}", serde_json::to_string_pretty(&sess.target.to_json()).unwrap()); } 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); + let t_outputs = rustc_interface::util::build_output_filenames(io, attrs, sess); + let id = rustc_session::output::find_crate_name(sess, attrs, &io.input); if *req == PrintRequest::CrateName { println!("{id}"); continue; diff --git a/compiler/rustc_driver/src/pretty.rs b/compiler/rustc_driver/src/pretty.rs index b2451bc730f79..dd24f0bc98f10 100644 --- a/compiler/rustc_driver/src/pretty.rs +++ b/compiler/rustc_driver/src/pretty.rs @@ -6,6 +6,7 @@ use rustc_ast_pretty::pprust; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir_pretty as pprust_hir; +use rustc_interface::interface::CompilerIO; use rustc_middle::hir::map as hir_map; use rustc_middle::mir::{write_mir_graphviz, write_mir_pretty}; use rustc_middle::ty::{self, TyCtxt}; @@ -16,7 +17,7 @@ use rustc_span::FileName; use std::cell::Cell; use std::fmt::Write; -use std::path::Path; +use std::path::PathBuf; pub use self::PpMode::*; pub use self::PpSourceMode::*; @@ -358,7 +359,7 @@ fn get_source(input: &Input, sess: &Session) -> (String, FileName) { (src, src_name) } -fn write_or_print(out: &str, ofile: Option<&Path>, sess: &Session) { +fn write_or_print(out: &str, ofile: &Option, sess: &Session) { match ofile { None => print!("{out}"), Some(p) => { @@ -372,14 +373,8 @@ fn write_or_print(out: &str, ofile: Option<&Path>, sess: &Session) { } } -pub fn print_after_parsing( - sess: &Session, - input: &Input, - krate: &ast::Crate, - ppm: PpMode, - ofile: Option<&Path>, -) { - let (src, src_name) = get_source(input, sess); +pub fn print_after_parsing(sess: &Session, io: &CompilerIO, krate: &ast::Crate, ppm: PpMode) { + let (src, src_name) = get_source(&io.input, sess); let out = match ppm { Source(s) => { @@ -407,22 +402,21 @@ pub fn print_after_parsing( _ => unreachable!(), }; - write_or_print(&out, ofile, sess); + write_or_print(&out, &io.output_file, sess); } pub fn print_after_hir_lowering<'tcx>( tcx: TyCtxt<'tcx>, - input: &Input, + io: &CompilerIO, krate: &ast::Crate, ppm: PpMode, - ofile: Option<&Path>, ) { if ppm.needs_analysis() { - abort_on_err(print_with_analysis(tcx, ppm, ofile), tcx.sess); + abort_on_err(print_with_analysis(tcx, ppm, &io.output_file), tcx.sess); return; } - let (src, src_name) = get_source(input, tcx.sess); + let (src, src_name) = get_source(&io.input, tcx.sess); let out = match ppm { Source(s) => { @@ -474,7 +468,7 @@ pub fn print_after_hir_lowering<'tcx>( _ => unreachable!(), }; - write_or_print(&out, ofile, tcx.sess); + write_or_print(&out, &io.output_file, tcx.sess); } // In an ideal world, this would be a public function called by the driver after @@ -484,7 +478,7 @@ pub fn print_after_hir_lowering<'tcx>( fn print_with_analysis( tcx: TyCtxt<'_>, ppm: PpMode, - ofile: Option<&Path>, + ofile: &Option, ) -> Result<(), ErrorGuaranteed> { tcx.analysis(())?; let out = match ppm { diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 22a01db5e7573..e3c4f9052cebe 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -35,15 +35,19 @@ pub type Result = result::Result; pub struct Compiler { pub(crate) sess: Lrc, codegen_backend: Lrc>, - pub(crate) input: Input, - pub(crate) output_dir: Option, - pub(crate) output_file: Option, - pub(crate) temps_dir: Option, + pub(crate) io: CompilerIO, pub(crate) register_lints: Option>, pub(crate) override_queries: Option, } +pub struct CompilerIO { + pub input: Input, + pub output_dir: Option, + pub output_file: Option, + pub temps_dir: Option, +} + impl Compiler { pub fn session(&self) -> &Lrc { &self.sess @@ -51,17 +55,8 @@ impl Compiler { pub fn codegen_backend(&self) -> &Lrc> { &self.codegen_backend } - pub fn input(&self) -> &Input { - &self.input - } - pub fn output_dir(&self) -> &Option { - &self.output_dir - } - pub fn output_file(&self) -> &Option { - &self.output_file - } - pub fn temps_dir(&self) -> &Option { - &self.temps_dir + pub fn io(&self) -> &CompilerIO { + &self.io } pub fn register_lints(&self) -> &Option> { &self.register_lints @@ -71,14 +66,7 @@ impl Compiler { sess: &Session, attrs: &[ast::Attribute], ) -> OutputFilenames { - util::build_output_filenames( - &self.input, - &self.output_dir, - &self.output_file, - &self.temps_dir, - attrs, - sess, - ) + util::build_output_filenames(&self.io, attrs, sess) } } @@ -305,10 +293,12 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se let compiler = Compiler { sess: Lrc::new(sess), codegen_backend: Lrc::new(codegen_backend), - input: config.input, - output_dir: config.output_dir, - output_file: config.output_file, - temps_dir, + io: CompilerIO { + input: config.input, + output_dir: config.output_dir, + output_file: config.output_file, + temps_dir, + }, register_lints: config.register_lints, override_queries: config.override_queries, }; diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index bba0a50a93fae..8545cbefa262f 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -673,20 +673,13 @@ pub fn prepare_outputs( let _timer = sess.timer("prepare_outputs"); // FIXME: rustdoc passes &[] instead of &krate.attrs here - let outputs = util::build_output_filenames( - &compiler.input, - &compiler.output_dir, - &compiler.output_file, - &compiler.temps_dir, - &krate.attrs, - sess, - ); + let outputs = util::build_output_filenames(&compiler.io, &krate.attrs, sess); let output_paths = - generated_output_paths(sess, &outputs, compiler.output_file.is_some(), crate_name); + generated_output_paths(sess, &outputs, compiler.io.output_file.is_some(), crate_name); // Ensure the source file isn't accidentally overwritten during compilation. - if let Some(ref input_path) = compiler.input.opt_path() { + if let Some(ref input_path) = compiler.io.input.opt_path() { if sess.opts.will_create_output_file() { if output_contains_path(&output_paths, input_path) { let reported = sess.emit_err(InputFileWouldBeOverWritten { path: input_path }); @@ -700,7 +693,7 @@ pub fn prepare_outputs( } } - if let Some(ref dir) = compiler.temps_dir { + if let Some(ref dir) = compiler.io.temps_dir { if fs::create_dir_all(dir).is_err() { let reported = sess.emit_err(TempsDirError); return Err(reported); @@ -713,7 +706,7 @@ pub fn prepare_outputs( && sess.opts.output_types.len() == 1; if !only_dep_info { - if let Some(ref dir) = compiler.output_dir { + if let Some(ref dir) = compiler.io.output_dir { if fs::create_dir_all(dir).is_err() { let reported = sess.emit_err(OutDirError); return Err(reported); diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 6f791c8893ce3..32348fd72edd3 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -129,7 +129,7 @@ impl<'tcx> Queries<'tcx> { pub fn parse(&self) -> Result> { self.parse.compute(|| { - passes::parse(self.session(), &self.compiler.input) + passes::parse(self.session(), &self.compiler.io.input) .map_err(|mut parse_error| parse_error.emit()) }) } @@ -165,7 +165,7 @@ impl<'tcx> Queries<'tcx> { let parse_result = self.parse()?; let krate = parse_result.borrow(); // parse `#[crate_name]` even if `--crate-name` was passed, to make sure it matches. - find_crate_name(self.session(), &krate.attrs, &self.compiler.input) + find_crate_name(self.session(), &krate.attrs, &self.compiler.io.input) }) }) } diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 02a7756c8d453..f19b03c75ebfd 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -8,7 +8,7 @@ use rustc_parse::validate_attr; use rustc_session as session; use rustc_session::config::CheckCfg; use rustc_session::config::{self, CrateType}; -use rustc_session::config::{ErrorOutputType, Input, OutputFilenames}; +use rustc_session::config::{ErrorOutputType, OutputFilenames}; use rustc_session::filesearch::sysroot_candidates; use rustc_session::lint::{self, BuiltinLintDiagnostics, LintBuffer}; use rustc_session::parse::CrateConfig; @@ -25,6 +25,8 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::OnceLock; use std::thread; +use crate::interface::CompilerIO; + /// Function pointer type that constructs a new CodegenBackend. pub type MakeBackendFn = fn() -> Box; @@ -487,19 +489,16 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec, - ofile: &Option, - temps_dir: &Option, + io: &CompilerIO, attrs: &[ast::Attribute], sess: &Session, ) -> OutputFilenames { - match *ofile { + match io.output_file { None => { // "-" as input file will cause the parser to read from stdin so we // have to make up a name // We want to toss everything after the final '.' - let dirpath = (*odir).as_ref().cloned().unwrap_or_default(); + let dirpath = io.output_dir.clone().unwrap_or_default(); // If a crate name is present, we use it as the link name let stem = sess @@ -507,13 +506,13 @@ pub fn build_output_filenames( .crate_name .clone() .or_else(|| rustc_attr::find_crate_name(sess, attrs).map(|n| n.to_string())) - .unwrap_or_else(|| input.filestem().to_owned()); + .unwrap_or_else(|| io.input.filestem().to_owned()); OutputFilenames::new( dirpath, stem, None, - temps_dir.clone(), + io.temps_dir.clone(), sess.opts.cg.extra_filename.clone(), sess.opts.output_types.clone(), ) @@ -534,7 +533,7 @@ pub fn build_output_filenames( } Some(out_file.clone()) }; - if *odir != None { + if io.output_dir != None { sess.warn("ignoring --out-dir flag due to -o flag"); } @@ -542,7 +541,7 @@ pub fn build_output_filenames( out_file.parent().unwrap_or_else(|| Path::new("")).to_path_buf(), out_file.file_stem().unwrap_or_default().to_str().unwrap().to_string(), ofile, - temps_dir.clone(), + io.temps_dir.clone(), sess.opts.cg.extra_filename.clone(), sess.opts.output_types.clone(), ) diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 6a147de3be2ea..d52c7819c567a 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -75,7 +75,7 @@ impl rustc_driver::Callbacks for MiriCompilerCalls { let mut config = self.miri_config.clone(); // Add filename to `miri` arguments. - config.args.insert(0, compiler.input().filestem().to_string()); + config.args.insert(0, compiler.io().input.filestem().to_string()); // Adjust working directory for interpretation. if let Some(cwd) = env::var_os("MIRI_CWD") { From 9f5cd0315386e761beae8afd07df94e42a4db154 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 7 Dec 2022 09:24:00 +0000 Subject: [PATCH 5/9] Move compiler input and ouput paths into session --- .../src/debuginfo/mod.rs | 2 +- .../src/debuginfo/metadata.rs | 8 +-- compiler/rustc_driver/src/lib.rs | 56 ++++++------------- compiler/rustc_driver/src/pretty.rs | 39 +++++-------- compiler/rustc_interface/src/interface.rs | 32 ++++------- compiler/rustc_interface/src/passes.rs | 15 +++-- compiler/rustc_interface/src/queries.rs | 16 ++---- compiler/rustc_interface/src/tests.rs | 12 +++- compiler/rustc_interface/src/util.rs | 25 ++++----- compiler/rustc_passes/src/entry.rs | 2 +- .../rustc_save_analysis/src/dump_visitor.rs | 16 +++--- compiler/rustc_session/src/output.rs | 4 +- compiler/rustc_session/src/session.rs | 27 +++++---- src/librustdoc/html/render/mod.rs | 2 +- src/tools/miri/src/bin/miri.rs | 11 ++-- 15 files changed, 113 insertions(+), 154 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs index 2ba012a77b0a9..28fbcb15b2b58 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs @@ -68,7 +68,7 @@ impl DebugContext { .working_dir .to_string_lossy(FileNameDisplayPreference::Remapped) .into_owned(); - let (name, file_info) = match tcx.sess.local_crate_source_file.clone() { + let (name, file_info) = match tcx.sess.local_crate_source_file() { Some(path) => { let name = path.to_string_lossy().into_owned(); (name, None) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 48e3a812e4f20..b6eb5ee183fa3 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -782,10 +782,10 @@ pub fn build_compile_unit_di_node<'ll, 'tcx>( codegen_unit_name: &str, debug_context: &CodegenUnitDebugContext<'ll, 'tcx>, ) -> &'ll DIDescriptor { - let mut name_in_debuginfo = match tcx.sess.local_crate_source_file { - Some(ref path) => path.clone(), - None => PathBuf::from(tcx.crate_name(LOCAL_CRATE).as_str()), - }; + let mut name_in_debuginfo = tcx + .sess + .local_crate_source_file() + .unwrap_or_else(|| PathBuf::from(tcx.crate_name(LOCAL_CRATE).as_str())); // To avoid breaking split DWARF, we need to ensure that each codegen unit // has a unique `DW_AT_name`. This is because there's a remote chance that diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index feb78cb0984e8..66dadf97b1987 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -26,7 +26,6 @@ use rustc_errors::registry::{InvalidErrorCode, Registry}; use rustc_errors::{ErrorGuaranteed, PResult}; use rustc_feature::find_gated_cfg; use rustc_hir::def_id::LOCAL_CRATE; -use rustc_interface::interface::CompilerIO; use rustc_interface::util::{self, collect_crate_types, get_codegen_backend}; use rustc_interface::{interface, Queries}; use rustc_lint::LintStore; @@ -260,12 +259,8 @@ fn run_compiler( describe_lints(compiler.session(), &lint_store, registered_lints); return; } - let should_stop = print_crate_info( - &***compiler.codegen_backend(), - compiler.session(), - false, - compiler.io(), - ); + let should_stop = + print_crate_info(&***compiler.codegen_backend(), compiler.session(), false); if should_stop == Compilation::Stop { return; @@ -287,16 +282,9 @@ fn run_compiler( interface::run_compiler(config, |compiler| { let sess = compiler.session(); - let should_stop = - print_crate_info(&***compiler.codegen_backend(), sess, true, compiler.io()) - .and_then(|| { - list_metadata( - sess, - &*compiler.codegen_backend().metadata_loader(), - &compiler.io().input, - ) - }) - .and_then(|| try_process_rlink(sess, compiler)); + let should_stop = print_crate_info(&***compiler.codegen_backend(), sess, true) + .and_then(|| list_metadata(sess, &*compiler.codegen_backend().metadata_loader())) + .and_then(|| try_process_rlink(sess, compiler)); if should_stop == Compilation::Stop { return sess.compile_status(); @@ -310,17 +298,12 @@ fn run_compiler( if ppm.needs_ast_map() { let expanded_crate = queries.expansion()?.borrow().0.clone(); queries.global_ctxt()?.enter(|tcx| { - pretty::print_after_hir_lowering( - tcx, - compiler.io(), - &*expanded_crate, - *ppm, - ); + pretty::print_after_hir_lowering(tcx, &*expanded_crate, *ppm); Ok(()) })?; } else { let krate = queries.parse()?.steal(); - pretty::print_after_parsing(sess, compiler.io(), &krate, *ppm); + pretty::print_after_parsing(sess, &krate, *ppm); } trace!("finished pretty-printing"); return early_exit(); @@ -370,9 +353,9 @@ fn run_compiler( save::process_crate( tcx, crate_name, - &compiler.io().input, + &sess.io.input, None, - DumpHandler::new(compiler.io().output_dir.as_deref(), crate_name), + DumpHandler::new(sess.io.output_dir.as_deref(), crate_name), ) }); } @@ -546,7 +529,7 @@ fn show_content_with_pager(content: &str) { pub fn try_process_rlink(sess: &Session, compiler: &interface::Compiler) -> Compilation { if sess.opts.unstable_opts.link_only { - if let Input::File(file) = &compiler.io().input { + if let Input::File(file) = &sess.io.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, &[]); @@ -587,13 +570,9 @@ pub fn try_process_rlink(sess: &Session, compiler: &interface::Compiler) -> Comp } } -pub fn list_metadata( - sess: &Session, - metadata_loader: &dyn MetadataLoader, - input: &Input, -) -> Compilation { +pub fn list_metadata(sess: &Session, metadata_loader: &dyn MetadataLoader) -> Compilation { if sess.opts.unstable_opts.ls { - match *input { + match sess.io.input { Input::File(ref ifile) => { let path = &(*ifile); let mut v = Vec::new(); @@ -614,7 +593,6 @@ fn print_crate_info( codegen_backend: &dyn CodegenBackend, sess: &Session, parse_attrs: bool, - io: &CompilerIO, ) -> Compilation { use rustc_session::config::PrintRequest::*; // NativeStaticLibs and LinkArgs are special - printed during linking @@ -624,7 +602,7 @@ fn print_crate_info( } let attrs = if parse_attrs { - let result = parse_crate_attrs(sess, &io.input); + let result = parse_crate_attrs(sess); match result { Ok(attrs) => Some(attrs), Err(mut parse_error) => { @@ -649,8 +627,8 @@ fn print_crate_info( } FileNames | CrateName => { let attrs = attrs.as_ref().unwrap(); - let t_outputs = rustc_interface::util::build_output_filenames(io, attrs, sess); - let id = rustc_session::output::find_crate_name(sess, attrs, &io.input); + let t_outputs = rustc_interface::util::build_output_filenames(attrs, sess); + let id = rustc_session::output::find_crate_name(sess, attrs); if *req == PrintRequest::CrateName { println!("{id}"); continue; @@ -1086,8 +1064,8 @@ pub fn handle_options(args: &[String]) -> Option { Some(matches) } -fn parse_crate_attrs<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::AttrVec> { - match input { +fn parse_crate_attrs<'a>(sess: &'a Session) -> PResult<'a, ast::AttrVec> { + match &sess.io.input { Input::File(ifile) => rustc_parse::parse_crate_attrs_from_file(ifile, &sess.parse_sess), Input::Str { name, input } => rustc_parse::parse_crate_attrs_from_source_str( name.clone(), diff --git a/compiler/rustc_driver/src/pretty.rs b/compiler/rustc_driver/src/pretty.rs index dd24f0bc98f10..ae3ac8625b186 100644 --- a/compiler/rustc_driver/src/pretty.rs +++ b/compiler/rustc_driver/src/pretty.rs @@ -6,18 +6,16 @@ use rustc_ast_pretty::pprust; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir_pretty as pprust_hir; -use rustc_interface::interface::CompilerIO; use rustc_middle::hir::map as hir_map; use rustc_middle::mir::{write_mir_graphviz, write_mir_pretty}; use rustc_middle::ty::{self, TyCtxt}; -use rustc_session::config::{Input, PpAstTreeMode, PpHirMode, PpMode, PpSourceMode}; +use rustc_session::config::{PpAstTreeMode, PpHirMode, PpMode, PpSourceMode}; use rustc_session::Session; use rustc_span::symbol::Ident; use rustc_span::FileName; use std::cell::Cell; use std::fmt::Write; -use std::path::PathBuf; pub use self::PpMode::*; pub use self::PpSourceMode::*; @@ -346,8 +344,8 @@ impl<'tcx> pprust_hir::PpAnn for TypedAnnotation<'tcx> { } } -fn get_source(input: &Input, sess: &Session) -> (String, FileName) { - let src_name = input.source_name(); +fn get_source(sess: &Session) -> (String, FileName) { + let src_name = sess.io.input.source_name(); let src = String::clone( sess.source_map() .get_source_file(&src_name) @@ -359,8 +357,8 @@ fn get_source(input: &Input, sess: &Session) -> (String, FileName) { (src, src_name) } -fn write_or_print(out: &str, ofile: &Option, sess: &Session) { - match ofile { +fn write_or_print(out: &str, sess: &Session) { + match &sess.io.output_file { None => print!("{out}"), Some(p) => { if let Err(e) = std::fs::write(p, out) { @@ -373,8 +371,8 @@ fn write_or_print(out: &str, ofile: &Option, sess: &Session) { } } -pub fn print_after_parsing(sess: &Session, io: &CompilerIO, krate: &ast::Crate, ppm: PpMode) { - let (src, src_name) = get_source(&io.input, sess); +pub fn print_after_parsing(sess: &Session, krate: &ast::Crate, ppm: PpMode) { + let (src, src_name) = get_source(sess); let out = match ppm { Source(s) => { @@ -402,21 +400,16 @@ pub fn print_after_parsing(sess: &Session, io: &CompilerIO, krate: &ast::Crate, _ => unreachable!(), }; - write_or_print(&out, &io.output_file, sess); + write_or_print(&out, sess); } -pub fn print_after_hir_lowering<'tcx>( - tcx: TyCtxt<'tcx>, - io: &CompilerIO, - krate: &ast::Crate, - ppm: PpMode, -) { +pub fn print_after_hir_lowering<'tcx>(tcx: TyCtxt<'tcx>, krate: &ast::Crate, ppm: PpMode) { if ppm.needs_analysis() { - abort_on_err(print_with_analysis(tcx, ppm, &io.output_file), tcx.sess); + abort_on_err(print_with_analysis(tcx, ppm), tcx.sess); return; } - let (src, src_name) = get_source(&io.input, tcx.sess); + let (src, src_name) = get_source(tcx.sess); let out = match ppm { Source(s) => { @@ -468,18 +461,14 @@ pub fn print_after_hir_lowering<'tcx>( _ => unreachable!(), }; - write_or_print(&out, &io.output_file, tcx.sess); + write_or_print(&out, tcx.sess); } // In an ideal world, this would be a public function called by the driver after // analysis is performed. However, we want to call `phase_3_run_analysis_passes` // with a different callback than the standard driver, so that isn't easy. // Instead, we call that function ourselves. -fn print_with_analysis( - tcx: TyCtxt<'_>, - ppm: PpMode, - ofile: &Option, -) -> Result<(), ErrorGuaranteed> { +fn print_with_analysis(tcx: TyCtxt<'_>, ppm: PpMode) -> Result<(), ErrorGuaranteed> { tcx.analysis(())?; let out = match ppm { Mir => { @@ -512,7 +501,7 @@ fn print_with_analysis( _ => unreachable!(), }; - write_or_print(&out, ofile, tcx.sess); + write_or_print(&out, tcx.sess); Ok(()) } diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index e3c4f9052cebe..7a5e45ada3f6a 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -14,10 +14,10 @@ use rustc_middle::ty; use rustc_parse::maybe_new_parser_from_source_str; use rustc_query_impl::QueryCtxt; use rustc_session::config::{self, CheckCfg, ErrorOutputType, Input, OutputFilenames}; -use rustc_session::early_error; use rustc_session::lint; use rustc_session::parse::{CrateConfig, ParseSess}; use rustc_session::Session; +use rustc_session::{early_error, CompilerIO}; use rustc_span::source_map::{FileLoader, FileName}; use rustc_span::symbol::sym; use std::path::PathBuf; @@ -35,19 +35,11 @@ pub type Result = result::Result; pub struct Compiler { pub(crate) sess: Lrc, codegen_backend: Lrc>, - pub(crate) io: CompilerIO, pub(crate) register_lints: Option>, pub(crate) override_queries: Option, } -pub struct CompilerIO { - pub input: Input, - pub output_dir: Option, - pub output_file: Option, - pub temps_dir: Option, -} - impl Compiler { pub fn session(&self) -> &Lrc { &self.sess @@ -55,9 +47,6 @@ impl Compiler { pub fn codegen_backend(&self) -> &Lrc> { &self.codegen_backend } - pub fn io(&self) -> &CompilerIO { - &self.io - } pub fn register_lints(&self) -> &Option> { &self.register_lints } @@ -66,7 +55,7 @@ impl Compiler { sess: &Session, attrs: &[ast::Attribute], ) -> OutputFilenames { - util::build_output_filenames(&self.io, attrs, sess) + util::build_output_filenames(attrs, sess) } } @@ -273,12 +262,19 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se crate::callbacks::setup_callbacks(); let registry = &config.registry; + + let temps_dir = config.opts.unstable_opts.temps_dir.as_deref().map(PathBuf::from); let (mut sess, codegen_backend) = util::create_session( config.opts, config.crate_cfg, config.crate_check_cfg, config.file_loader, - config.input.opt_path(), + CompilerIO { + input: config.input, + output_dir: config.output_dir, + output_file: config.output_file, + temps_dir, + }, config.lint_caps, config.make_codegen_backend, registry.clone(), @@ -288,17 +284,9 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se parse_sess_created(&mut sess.parse_sess); } - let temps_dir = sess.opts.unstable_opts.temps_dir.as_deref().map(PathBuf::from); - let compiler = Compiler { sess: Lrc::new(sess), codegen_backend: Lrc::new(codegen_backend), - io: CompilerIO { - input: config.input, - output_dir: config.output_dir, - output_file: config.output_file, - temps_dir, - }, register_lints: config.register_lints, override_queries: config.override_queries, }; diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 8545cbefa262f..2fa846b7e4bfc 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -50,8 +50,8 @@ use std::rc::Rc; use std::sync::LazyLock; use std::{env, fs, iter}; -pub fn parse<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> { - let krate = sess.time("parse_crate", || match input { +pub fn parse<'a>(sess: &'a Session) -> PResult<'a, ast::Crate> { + let krate = sess.time("parse_crate", || match &sess.io.input { Input::File(file) => parse_crate_from_file(file, &sess.parse_sess), Input::Str { input, name } => { parse_crate_from_source_str(name.clone(), input.clone(), &sess.parse_sess) @@ -665,7 +665,6 @@ fn write_out_deps( pub fn prepare_outputs( sess: &Session, - compiler: &Compiler, krate: &ast::Crate, boxed_resolver: &RefCell, crate_name: Symbol, @@ -673,13 +672,13 @@ pub fn prepare_outputs( let _timer = sess.timer("prepare_outputs"); // FIXME: rustdoc passes &[] instead of &krate.attrs here - let outputs = util::build_output_filenames(&compiler.io, &krate.attrs, sess); + let outputs = util::build_output_filenames(&krate.attrs, sess); let output_paths = - generated_output_paths(sess, &outputs, compiler.io.output_file.is_some(), crate_name); + generated_output_paths(sess, &outputs, sess.io.output_file.is_some(), crate_name); // Ensure the source file isn't accidentally overwritten during compilation. - if let Some(ref input_path) = compiler.io.input.opt_path() { + if let Some(ref input_path) = sess.io.input.opt_path() { if sess.opts.will_create_output_file() { if output_contains_path(&output_paths, input_path) { let reported = sess.emit_err(InputFileWouldBeOverWritten { path: input_path }); @@ -693,7 +692,7 @@ pub fn prepare_outputs( } } - if let Some(ref dir) = compiler.io.temps_dir { + if let Some(ref dir) = sess.io.temps_dir { if fs::create_dir_all(dir).is_err() { let reported = sess.emit_err(TempsDirError); return Err(reported); @@ -706,7 +705,7 @@ pub fn prepare_outputs( && sess.opts.output_types.len() == 1; if !only_dep_info { - if let Some(ref dir) = compiler.io.output_dir { + if let Some(ref dir) = sess.io.output_dir { if fs::create_dir_all(dir).is_err() { let reported = sess.emit_err(OutDirError); return Err(reported); diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 32348fd72edd3..dcfb4f43bd018 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -128,10 +128,8 @@ impl<'tcx> Queries<'tcx> { } pub fn parse(&self) -> Result> { - self.parse.compute(|| { - passes::parse(self.session(), &self.compiler.io.input) - .map_err(|mut parse_error| parse_error.emit()) - }) + self.parse + .compute(|| passes::parse(self.session()).map_err(|mut parse_error| parse_error.emit())) } pub fn register_plugins(&self) -> Result)>> { @@ -165,7 +163,7 @@ impl<'tcx> Queries<'tcx> { let parse_result = self.parse()?; let krate = parse_result.borrow(); // parse `#[crate_name]` even if `--crate-name` was passed, to make sure it matches. - find_crate_name(self.session(), &krate.attrs, &self.compiler.io.input) + find_crate_name(self.session(), &krate.attrs) }) }) } @@ -214,13 +212,7 @@ impl<'tcx> Queries<'tcx> { let crate_name = *self.crate_name()?.borrow(); let (krate, resolver, lint_store) = self.expansion()?.steal(); - let outputs = passes::prepare_outputs( - self.session(), - self.compiler, - &krate, - &resolver, - crate_name, - )?; + let outputs = passes::prepare_outputs(self.session(), &krate, &resolver, crate_name)?; let ty::ResolverOutputs { untracked, diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 07b28cc86cee1..f94bc4d4c66ac 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -4,6 +4,7 @@ use crate::interface::parse_cfgspecs; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig}; use rustc_session::config::rustc_optgroups; +use rustc_session::config::Input; use rustc_session::config::TraitSolver; use rustc_session::config::{build_configuration, build_session_options, to_crate_config}; use rustc_session::config::{ @@ -17,9 +18,11 @@ use rustc_session::config::{InstrumentCoverage, Passes}; use rustc_session::lint::Level; use rustc_session::search_paths::SearchPath; use rustc_session::utils::{CanonicalizedPath, NativeLib, NativeLibKind}; +use rustc_session::CompilerIO; use rustc_session::{build_session, getopts, Session}; use rustc_span::edition::{Edition, DEFAULT_EDITION}; use rustc_span::symbol::sym; +use rustc_span::FileName; use rustc_span::SourceFileHashAlgorithm; use rustc_target::spec::{CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, RelocModel}; use rustc_target::spec::{RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel}; @@ -39,7 +42,14 @@ fn build_session_options_and_crate_config(matches: getopts::Matches) -> (Options fn mk_session(matches: getopts::Matches) -> (Session, CfgSpecs) { let registry = registry::Registry::new(&[]); let (sessopts, cfg) = build_session_options_and_crate_config(matches); - let sess = build_session(sessopts, None, None, registry, Default::default(), None, None); + let temps_dir = sessopts.unstable_opts.temps_dir.as_deref().map(PathBuf::from); + let io = CompilerIO { + input: Input::Str { name: FileName::Custom(String::new()), input: String::new() }, + output_dir: None, + output_file: None, + temps_dir, + }; + let sess = build_session(sessopts, io, None, registry, Default::default(), None, None); (sess, cfg) } diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index f19b03c75ebfd..54363e07b971a 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -17,6 +17,7 @@ use rustc_span::edition::Edition; use rustc_span::lev_distance::find_best_match_for_name; use rustc_span::source_map::FileLoader; use rustc_span::symbol::{sym, Symbol}; +use session::CompilerIO; use std::env; use std::env::consts::{DLL_PREFIX, DLL_SUFFIX}; use std::mem; @@ -25,8 +26,6 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::OnceLock; use std::thread; -use crate::interface::CompilerIO; - /// Function pointer type that constructs a new CodegenBackend. pub type MakeBackendFn = fn() -> Box; @@ -60,7 +59,7 @@ pub fn create_session( cfg: FxHashSet<(String, Option)>, check_cfg: CheckCfg, file_loader: Option>, - input_path: Option, + io: CompilerIO, lint_caps: FxHashMap, make_codegen_backend: Option< Box Box + Send>, @@ -91,7 +90,7 @@ pub fn create_session( let mut sess = session::build_session( sopts, - input_path, + io, bundle, descriptions, lint_caps, @@ -488,17 +487,13 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec OutputFilenames { - match io.output_file { +pub fn build_output_filenames(attrs: &[ast::Attribute], sess: &Session) -> OutputFilenames { + match sess.io.output_file { None => { // "-" as input file will cause the parser to read from stdin so we // have to make up a name // We want to toss everything after the final '.' - let dirpath = io.output_dir.clone().unwrap_or_default(); + let dirpath = sess.io.output_dir.clone().unwrap_or_default(); // If a crate name is present, we use it as the link name let stem = sess @@ -506,13 +501,13 @@ pub fn build_output_filenames( .crate_name .clone() .or_else(|| rustc_attr::find_crate_name(sess, attrs).map(|n| n.to_string())) - .unwrap_or_else(|| io.input.filestem().to_owned()); + .unwrap_or_else(|| sess.io.input.filestem().to_owned()); OutputFilenames::new( dirpath, stem, None, - io.temps_dir.clone(), + sess.io.temps_dir.clone(), sess.opts.cg.extra_filename.clone(), sess.opts.output_types.clone(), ) @@ -533,7 +528,7 @@ pub fn build_output_filenames( } Some(out_file.clone()) }; - if io.output_dir != None { + if sess.io.output_dir != None { sess.warn("ignoring --out-dir flag due to -o flag"); } @@ -541,7 +536,7 @@ pub fn build_output_filenames( out_file.parent().unwrap_or_else(|| Path::new("")).to_path_buf(), out_file.file_stem().unwrap_or_default().to_str().unwrap().to_string(), ofile, - io.temps_dir.clone(), + sess.io.temps_dir.clone(), sess.opts.cg.extra_filename.clone(), sess.opts.output_types.clone(), ) diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs index 5885f45ae45db..b327ba63330ba 100644 --- a/compiler/rustc_passes/src/entry.rs +++ b/compiler/rustc_passes/src/entry.rs @@ -195,7 +195,7 @@ fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) { // There is no main function. let mut has_filename = true; - let filename = tcx.sess.local_crate_source_file.clone().unwrap_or_else(|| { + let filename = tcx.sess.local_crate_source_file().unwrap_or_else(|| { has_filename = false; Default::default() }); diff --git a/compiler/rustc_save_analysis/src/dump_visitor.rs b/compiler/rustc_save_analysis/src/dump_visitor.rs index 9ae07cb005bd4..a5f09de1c401b 100644 --- a/compiler/rustc_save_analysis/src/dump_visitor.rs +++ b/compiler/rustc_save_analysis/src/dump_visitor.rs @@ -112,9 +112,7 @@ impl<'tcx> DumpVisitor<'tcx> { } pub fn dump_crate_info(&mut self, name: Symbol) { - let source_file = self.tcx.sess.local_crate_source_file.as_ref(); - let crate_root = source_file.map(|source_file| { - let source_file = Path::new(source_file); + let crate_root = self.tcx.sess.local_crate_source_file().map(|source_file| { match source_file.file_name() { Some(_) => source_file.parent().unwrap().display(), None => source_file.display(), @@ -157,10 +155,14 @@ impl<'tcx> DumpVisitor<'tcx> { .enumerate() .filter(|(i, _)| !remap_arg_indices.contains(i)) .map(|(_, arg)| match input { - Input::File(ref path) if path == Path::new(&arg) => { - let mapped = &self.tcx.sess.local_crate_source_file; - mapped.as_ref().unwrap().to_string_lossy().into() - } + Input::File(ref path) if path == Path::new(&arg) => self + .tcx + .sess + .local_crate_source_file() + .as_ref() + .unwrap() + .to_string_lossy() + .into(), _ => arg, }); diff --git a/compiler/rustc_session/src/output.rs b/compiler/rustc_session/src/output.rs index 8ee3057de625e..2badccbf60344 100644 --- a/compiler/rustc_session/src/output.rs +++ b/compiler/rustc_session/src/output.rs @@ -45,7 +45,7 @@ fn is_writeable(p: &Path) -> bool { } } -pub fn find_crate_name(sess: &Session, attrs: &[ast::Attribute], input: &Input) -> Symbol { +pub fn find_crate_name(sess: &Session, attrs: &[ast::Attribute]) -> Symbol { let validate = |s: Symbol, span: Option| { validate_crate_name(sess, s, span); s @@ -71,7 +71,7 @@ pub fn find_crate_name(sess: &Session, attrs: &[ast::Attribute], input: &Input) if let Some((attr, s)) = attr_crate_name { return validate(s, Some(attr.span)); } - if let Input::File(ref path) = *input { + if let Input::File(ref path) = sess.io.input { if let Some(s) = path.file_stem().and_then(|s| s.to_str()) { if s.starts_with('-') { sess.emit_err(CrateNameInvalid { s }); diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 1b2e8d9dc707b..fe992b915613b 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1,6 +1,7 @@ use crate::cgu_reuse_tracker::CguReuseTracker; use crate::code_stats::CodeStats; pub use crate::code_stats::{DataTypeKind, FieldInfo, SizeKind, VariantInfo}; +use crate::config::Input; use crate::config::{self, CrateType, InstrumentCoverage, OptLevel, OutputType, SwitchWithOptPath}; use crate::errors::{ BranchProtectionRequiresAArch64, CannotEnableCrtStaticLinux, CannotMixAndMatchSanitizers, @@ -137,6 +138,13 @@ pub struct Limits { pub const_eval_limit: Limit, } +pub struct CompilerIO { + pub input: Input, + pub output_dir: Option, + pub output_file: Option, + pub temps_dir: Option, +} + /// Represents the data associated with a compilation /// session for a single crate. pub struct Session { @@ -147,9 +155,8 @@ pub struct Session { pub target_tlib_path: Lrc, pub parse_sess: ParseSess, pub sysroot: PathBuf, - /// The name of the root source file of the crate, in the local file system. - /// `None` means that there is no source file. - pub local_crate_source_file: Option, + /// Input, input file path and output file path to this compilation process. + pub io: CompilerIO, crate_types: OnceCell>, /// The `stable_crate_id` is constructed out of the crate name and all the @@ -228,6 +235,11 @@ impl Session { self.miri_unleashed_features.lock().push((span, feature_gate)); } + pub fn local_crate_source_file(&self) -> Option { + let path = self.io.input.opt_path()?; + Some(self.opts.file_path_mapping().map_prefix(path).0) + } + fn check_miri_unleashed_features(&self) { let unleashed_features = self.miri_unleashed_features.lock(); if !unleashed_features.is_empty() { @@ -1298,7 +1310,7 @@ fn default_emitter( #[allow(rustc::bad_opt_access)] pub fn build_session( sopts: config::Options, - local_crate_source_file: Option, + io: CompilerIO, bundle: Option>, registry: rustc_errors::registry::Registry, driver_lint_caps: FxHashMap, @@ -1391,11 +1403,6 @@ pub fn build_session( Lrc::new(SearchPath::from_sysroot_and_triple(&sysroot, target_triple)) }; - let file_path_mapping = sopts.file_path_mapping(); - - let local_crate_source_file = - local_crate_source_file.map(|path| file_path_mapping.map_prefix(path).0); - let optimization_fuel = Lock::new(OptimizationFuel { remaining: sopts.unstable_opts.fuel.as_ref().map_or(0, |&(_, i)| i), out_of_fuel: false, @@ -1427,7 +1434,7 @@ pub fn build_session( target_tlib_path, parse_sess, sysroot, - local_crate_source_file, + io, crate_types: OnceCell::new(), stable_crate_id: OnceCell::new(), features: OnceCell::new(), diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index f95d8e4303594..4fa33e8907d08 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -2921,7 +2921,7 @@ fn render_call_locations(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Ite // Look for the example file in the source map if it exists, otherwise return a dummy span let file_span = (|| { let source_map = tcx.sess.source_map(); - let crate_src = tcx.sess.local_crate_source_file.as_ref()?; + let crate_src = tcx.sess.local_crate_source_file()?; let abs_crate_src = crate_src.canonicalize().ok()?; let crate_root = abs_crate_src.parent()?.parent()?; let rel_path = path.strip_prefix(crate_root).ok()?; diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index d52c7819c567a..c0267956aab4a 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -56,12 +56,12 @@ impl rustc_driver::Callbacks for MiriCompilerCalls { fn after_analysis<'tcx>( &mut self, - compiler: &rustc_interface::interface::Compiler, + _: &rustc_interface::interface::Compiler, queries: &'tcx rustc_interface::Queries<'tcx>, ) -> Compilation { - compiler.session().abort_if_errors(); - queries.global_ctxt().unwrap().enter(|tcx| { + tcx.sess.abort_if_errors(); + init_late_loggers(tcx); if !tcx.sess.crate_types().contains(&CrateType::Executable) { tcx.sess.fatal("miri only makes sense on bin crates"); @@ -75,7 +75,7 @@ impl rustc_driver::Callbacks for MiriCompilerCalls { let mut config = self.miri_config.clone(); // Add filename to `miri` arguments. - config.args.insert(0, compiler.io().input.filestem().to_string()); + config.args.insert(0, tcx.sess.io.input.filestem().to_string()); // Adjust working directory for interpretation. if let Some(cwd) = env::var_os("MIRI_CWD") { @@ -87,10 +87,9 @@ impl rustc_driver::Callbacks for MiriCompilerCalls { i32::try_from(return_code).expect("Return value was too large!"), ); } + tcx.sess.abort_if_errors(); }); - compiler.session().abort_if_errors(); - Compilation::Stop } } From c8a056132144b60f81cd74d062f8f4ba32dfa785 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 7 Dec 2022 12:14:06 +0000 Subject: [PATCH 6/9] Avoid one more call site to `Compiler::expansion` --- compiler/rustc_driver/src/lib.rs | 2 +- compiler/rustc_interface/src/queries.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 66dadf97b1987..98c4383b62ea3 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -328,7 +328,7 @@ fn run_compiler( } } - queries.expansion()?; + queries.global_ctxt()?; if callbacks.after_expansion(compiler, queries) == Compilation::Stop { return early_exit(); } diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index dcfb4f43bd018..d5a49dd75be6a 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -157,7 +157,7 @@ impl<'tcx> Queries<'tcx> { }) } - pub fn crate_name(&self) -> Result> { + fn crate_name(&self) -> Result> { self.crate_name.compute(|| { Ok({ let parse_result = self.parse()?; From e5273a98d301e7ce8214183dff34d25597527d23 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 13 Jan 2023 15:19:25 +0000 Subject: [PATCH 7/9] Fix run-make-fulldeps test --- tests/run-make-fulldeps/issue-19371/foo.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/tests/run-make-fulldeps/issue-19371/foo.rs b/tests/run-make-fulldeps/issue-19371/foo.rs index 7e1b6aeb31558..5bb38fc02af91 100644 --- a/tests/run-make-fulldeps/issue-19371/foo.rs +++ b/tests/run-make-fulldeps/issue-19371/foo.rs @@ -1,12 +1,12 @@ #![feature(rustc_private)] -extern crate rustc_interface; extern crate rustc_driver; +extern crate rustc_interface; extern crate rustc_session; extern crate rustc_span; -use rustc_session::config::{Input, Options, OutputType, OutputTypes}; use rustc_interface::interface; +use rustc_session::config::{Input, Options, OutputType, OutputTypes}; use rustc_span::source_map::FileName; use std::path::PathBuf; @@ -50,7 +50,6 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf) { crate_cfg: Default::default(), crate_check_cfg: Default::default(), input, - input_path: None, output_file: Some(output), output_dir: None, file_loader: None, @@ -64,9 +63,7 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf) { interface::run_compiler(config, |compiler| { // This runs all the passes prior to linking, too. - let linker = compiler.enter(|queries| { - queries.linker() - }); + let linker = compiler.enter(|queries| queries.linker()); if let Ok(linker) = linker { linker.link(); } From 44ef075aeb308422ac513ddc8f18978d9b92eea4 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 16 Jan 2023 14:04:28 +0000 Subject: [PATCH 8/9] Remove a now-useless function call --- compiler/rustc_driver/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 98c4383b62ea3..f50ad0137b88a 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -333,8 +333,6 @@ fn run_compiler( return early_exit(); } - queries.global_ctxt()?; - if sess.opts.output_types.contains_key(&OutputType::DepInfo) && sess.opts.output_types.len() == 1 { From 13555593672b49b5306990d63d0e61a49e17d9f0 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 16 Jan 2023 14:27:33 +0000 Subject: [PATCH 9/9] Avoid an unnecessary allocation --- .../rustc_save_analysis/src/span_utils.rs | 8 +----- compiler/rustc_session/src/config.rs | 16 +++++------ compiler/rustc_session/src/session.rs | 2 +- compiler/rustc_span/src/source_map.rs | 27 ++++++++++++------- compiler/rustc_span/src/source_map/tests.rs | 2 +- 5 files changed, 28 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_save_analysis/src/span_utils.rs b/compiler/rustc_save_analysis/src/span_utils.rs index 8d6758f40f965..e65d57bb3db3e 100644 --- a/compiler/rustc_save_analysis/src/span_utils.rs +++ b/compiler/rustc_save_analysis/src/span_utils.rs @@ -18,13 +18,7 @@ impl<'a> SpanUtils<'a> { match &file.name { FileName::Real(RealFileName::LocalPath(path)) => { if path.is_absolute() { - self.sess - .source_map() - .path_mapping() - .map_prefix(path.into()) - .0 - .display() - .to_string() + self.sess.source_map().path_mapping().map_prefix(path).0.display().to_string() } else { self.sess .opts diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 2679164b927e5..df6b30bfee9e4 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -592,11 +592,11 @@ impl Input { } } - pub fn opt_path(&self) -> Option { + pub fn opt_path(&self) -> Option<&Path> { match self { - Input::File(file) => Some(file.clone()), + Input::File(file) => Some(file), Input::Str { name, .. } => match name { - FileName::Real(real) => real.local_path().map(|p| p.to_owned()), + FileName::Real(real) => real.local_path(), FileName::QuoteExpansion(_) => None, FileName::Anon(_) => None, FileName::MacroExpansion(_) => None, @@ -604,7 +604,7 @@ impl Input { FileName::CfgSpec(_) => None, FileName::CliCrateAttr(_) => None, FileName::Custom(_) => None, - FileName::DocTest(path, _) => Some(path.to_owned()), + FileName::DocTest(path, _) => Some(path), FileName::InlineAsm(_) => None, }, } @@ -2509,12 +2509,12 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { early_error(error_format, &format!("Current directory is invalid: {e}")); }); - let (path, remapped) = - FilePathMapping::new(remap_path_prefix.clone()).map_prefix(working_dir.clone()); + let remap = FilePathMapping::new(remap_path_prefix.clone()); + let (path, remapped) = remap.map_prefix(&working_dir); let working_dir = if remapped { - RealFileName::Remapped { local_path: Some(working_dir), virtual_name: path } + RealFileName::Remapped { virtual_name: path.into_owned(), local_path: Some(working_dir) } } else { - RealFileName::LocalPath(path) + RealFileName::LocalPath(path.into_owned()) }; Options { diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index fe992b915613b..d4a1e849b2a09 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -237,7 +237,7 @@ impl Session { pub fn local_crate_source_file(&self) -> Option { let path = self.io.input.opt_path()?; - Some(self.opts.file_path_mapping().map_prefix(path).0) + Some(self.opts.file_path_mapping().map_prefix(path).0.into_owned()) } fn check_miri_unleashed_features(&self) { diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index fa09b4faa441f..5bfe247c58d8d 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -1138,7 +1138,8 @@ impl FilePathMapping { /// Applies any path prefix substitution as defined by the mapping. /// The return value is the remapped path and a boolean indicating whether /// the path was affected by the mapping. - pub fn map_prefix(&self, path: PathBuf) -> (PathBuf, bool) { + pub fn map_prefix<'a>(&'a self, path: impl Into>) -> (Cow<'a, Path>, bool) { + let path = path.into(); if path.as_os_str().is_empty() { // Exit early if the path is empty and therefore there's nothing to remap. // This is mostly to reduce spam for `RUSTC_LOG=[remap_path_prefix]`. @@ -1148,7 +1149,10 @@ impl FilePathMapping { return remap_path_prefix(&self.mapping, path); #[instrument(level = "debug", skip(mapping), ret)] - fn remap_path_prefix(mapping: &[(PathBuf, PathBuf)], path: PathBuf) -> (PathBuf, bool) { + fn remap_path_prefix<'a>( + mapping: &'a [(PathBuf, PathBuf)], + path: Cow<'a, Path>, + ) -> (Cow<'a, Path>, bool) { // NOTE: We are iterating over the mapping entries from last to first // because entries specified later on the command line should // take precedence. @@ -1163,9 +1167,9 @@ impl FilePathMapping { // in remapped paths down the line. // So, if we have an exact match, we just return that without a call // to `Path::join()`. - to.clone() + to.into() } else { - to.join(rest) + to.join(rest).into() }; debug!("Match - remapped"); @@ -1183,11 +1187,11 @@ impl FilePathMapping { fn map_filename_prefix(&self, file: &FileName) -> (FileName, bool) { match file { FileName::Real(realfile) if let RealFileName::LocalPath(local_path) = realfile => { - let (mapped_path, mapped) = self.map_prefix(local_path.to_path_buf()); + let (mapped_path, mapped) = self.map_prefix(local_path); let realfile = if mapped { RealFileName::Remapped { local_path: Some(local_path.clone()), - virtual_name: mapped_path, + virtual_name: mapped_path.into_owned(), } } else { realfile.clone() @@ -1228,14 +1232,17 @@ impl FilePathMapping { let (new_path, was_remapped) = self.map_prefix(unmapped_file_path); if was_remapped { // It was remapped, so don't modify further - return RealFileName::Remapped { local_path: None, virtual_name: new_path }; + return RealFileName::Remapped { + local_path: None, + virtual_name: new_path.into_owned(), + }; } if new_path.is_absolute() { // No remapping has applied to this path and it is absolute, // so the working directory cannot influence it either, so // we are done. - return RealFileName::LocalPath(new_path); + return RealFileName::LocalPath(new_path.into_owned()); } debug_assert!(new_path.is_relative()); @@ -1253,12 +1260,12 @@ impl FilePathMapping { RealFileName::Remapped { // Erase the actual path local_path: None, - virtual_name: file_path_abs, + virtual_name: file_path_abs.into_owned(), } } else { // No kind of remapping applied to this path, so // we leave it as it is. - RealFileName::LocalPath(file_path_abs) + RealFileName::LocalPath(file_path_abs.into_owned()) } } RealFileName::Remapped { diff --git a/compiler/rustc_span/src/source_map/tests.rs b/compiler/rustc_span/src/source_map/tests.rs index 3cab59e8dbe6c..8671267725230 100644 --- a/compiler/rustc_span/src/source_map/tests.rs +++ b/compiler/rustc_span/src/source_map/tests.rs @@ -387,7 +387,7 @@ fn path_prefix_remapping_expand_to_absolute() { let working_directory = path("/foo"); let working_directory = RealFileName::Remapped { local_path: Some(working_directory.clone()), - virtual_name: mapping.map_prefix(working_directory).0, + virtual_name: mapping.map_prefix(working_directory).0.into_owned(), }; assert_eq!(working_directory.remapped_path_if_available(), path("FOO"));