diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index a0d6e1885c2..bfd0a458884 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -216,6 +216,7 @@ impl CodegenResults { sess: &Session, rlink_file: &Path, codegen_results: &CodegenResults, + outputs: &OutputFilenames, ) -> Result { let mut encoder = FileEncoder::new(rlink_file)?; encoder.emit_raw_bytes(RLINK_MAGIC); @@ -224,10 +225,14 @@ impl CodegenResults { encoder.emit_raw_bytes(&RLINK_VERSION.to_be_bytes()); encoder.emit_str(sess.cfg_version); Encodable::encode(codegen_results, &mut encoder); + Encodable::encode(outputs, &mut encoder); encoder.finish().map_err(|(_path, err)| err) } - pub fn deserialize_rlink(sess: &Session, data: Vec) -> Result { + pub fn deserialize_rlink( + sess: &Session, + data: Vec, + ) -> Result<(Self, OutputFilenames), CodegenErrors> { // The Decodable machinery is not used here because it panics if the input data is invalid // and because its internal representation may change. if !data.starts_with(RLINK_MAGIC) { @@ -256,6 +261,7 @@ impl CodegenResults { } let codegen_results = CodegenResults::decode(&mut decoder); - Ok(codegen_results) + let outputs = OutputFilenames::decode(&mut decoder); + Ok((codegen_results, outputs)) } } diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index e7cc3ae4d55..6af11ce8479 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -401,9 +401,7 @@ fn run_compiler( Ok(()) })?; - // Make sure the `output_filenames` query is run for its side - // effects of writing the dep-info and reporting errors. - queries.global_ctxt()?.enter(|tcx| tcx.output_filenames(())); + queries.write_dep_info()?; } else { let krate = queries.parse()?; pretty::print( @@ -431,9 +429,7 @@ fn run_compiler( return early_exit(); } - // Make sure the `output_filenames` query is run for its side - // effects of writing the dep-info and reporting errors. - queries.global_ctxt()?.enter(|tcx| tcx.output_filenames(())); + queries.write_dep_info()?; if sess.opts.output_types.contains_key(&OutputType::DepInfo) && sess.opts.output_types.len() == 1 @@ -648,12 +644,11 @@ fn show_md_content_with_pager(content: &str, color: ColorConfig) { fn process_rlink(sess: &Session, compiler: &interface::Compiler) { assert!(sess.opts.unstable_opts.link_only); if let Input::File(file) = &sess.io.input { - let outputs = compiler.build_output_filenames(sess, &[]); let rlink_data = fs::read(file).unwrap_or_else(|err| { sess.emit_fatal(RlinkUnableToRead { err }); }); - let codegen_results = match CodegenResults::deserialize_rlink(sess, rlink_data) { - Ok(codegen) => codegen, + let (codegen_results, outputs) = match CodegenResults::deserialize_rlink(sess, rlink_data) { + Ok((codegen, outputs)) => (codegen, outputs), Err(err) => { match err { CodegenErrors::WrongFileType => sess.emit_fatal(RLinkWrongFileType), diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 91fd4b4a1d0..8a6d8d3d42e 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -1,7 +1,7 @@ use crate::util; use rustc_ast::token; -use rustc_ast::{self as ast, LitKind, MetaItemKind}; +use rustc_ast::{LitKind, MetaItemKind}; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_data_structures::defer; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; @@ -15,9 +15,7 @@ use rustc_middle::{bug, ty}; use rustc_parse::maybe_new_parser_from_source_str; use rustc_query_impl::QueryCtxt; use rustc_query_system::query::print_query_stack; -use rustc_session::config::{ - self, Cfg, CheckCfg, ExpectedValues, Input, OutFileName, OutputFilenames, -}; +use rustc_session::config::{self, Cfg, CheckCfg, ExpectedValues, Input, OutFileName}; use rustc_session::filesearch::sysroot_candidates; use rustc_session::parse::ParseSess; use rustc_session::{lint, CompilerIO, EarlyErrorHandler, Session}; @@ -43,16 +41,6 @@ pub struct Compiler { pub(crate) override_queries: Option, } -impl Compiler { - pub fn build_output_filenames( - &self, - sess: &Session, - attrs: &[ast::Attribute], - ) -> OutputFilenames { - util::build_output_filenames(attrs, sess) - } -} - /// Converts strings provided as `--cfg [cfgspec]` into a `Cfg`. pub(crate) fn parse_cfg(handler: &EarlyErrorHandler, cfgs: Vec) -> Cfg { cfgs.into_iter() diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 4648d83a6f3..88212d164bc 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -39,7 +39,7 @@ use std::any::Any; use std::ffi::OsString; use std::io::{self, BufWriter, Write}; use std::path::{Path, PathBuf}; -use std::sync::{Arc, LazyLock}; +use std::sync::LazyLock; use std::{env, fs, iter}; pub fn parse<'a>(sess: &'a Session) -> PResult<'a, ast::Crate> { @@ -553,13 +553,17 @@ fn resolver_for_lowering<'tcx>( tcx.arena.alloc(Steal::new((untracked_resolver_for_lowering, Lrc::new(krate)))) } -fn output_filenames(tcx: TyCtxt<'_>, (): ()) -> Arc { +pub(crate) fn write_dep_info(tcx: TyCtxt<'_>) { + // Make sure name resolution and macro expansion is run for + // the side-effect of providing a complete set of all + // accessed files and env vars. + let _ = tcx.resolver_for_lowering(()); + let sess = tcx.sess; - let _timer = sess.timer("prepare_outputs"); - let (_, krate) = &*tcx.resolver_for_lowering(()).borrow(); + let _timer = sess.timer("write_dep_info"); let crate_name = tcx.crate_name(LOCAL_CRATE); - let outputs = util::build_output_filenames(&krate.attrs, sess); + let outputs = tcx.output_filenames(()); let output_paths = generated_output_paths(tcx, &outputs, sess.io.output_file.is_some(), crate_name); @@ -596,15 +600,12 @@ fn output_filenames(tcx: TyCtxt<'_>, (): ()) -> Arc { } } } - - outputs.into() } pub static DEFAULT_QUERY_PROVIDERS: LazyLock = LazyLock::new(|| { let providers = &mut Providers::default(); providers.analysis = analysis; providers.hir_crate = rustc_ast_lowering::lower_to_hir; - providers.output_filenames = output_filenames; providers.resolver_for_lowering = resolver_for_lowering; providers.early_lint_checks = early_lint_checks; proc_macro_decls::provide(providers); diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index bee27dc2d69..b7cd5468a00 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -85,7 +85,6 @@ pub struct Queries<'tcx> { hir_arena: WorkerLocal>, parse: Query, - pre_configure: Query<(ast::Crate, ast::AttrVec)>, // This just points to what's in `gcx_cell`. gcx: Query<&'tcx GlobalCtxt<'tcx>>, } @@ -98,7 +97,6 @@ impl<'tcx> Queries<'tcx> { arena: WorkerLocal::new(|_| Arena::default()), hir_arena: WorkerLocal::new(|_| rustc_hir::Arena::default()), parse: Default::default(), - pre_configure: Default::default(), gcx: Default::default(), } } @@ -113,12 +111,12 @@ impl<'tcx> Queries<'tcx> { }) } - #[deprecated = "pre_configure may be made private in the future. If you need it please open an issue with your use case."] - pub fn pre_configure(&self) -> Result> { - self.pre_configure.compute(|| { + pub fn global_ctxt(&'tcx self) -> Result>> { + self.gcx.compute(|| { + let sess = &self.compiler.sess; + let mut krate = self.parse()?.steal(); - let sess = &self.compiler.sess; rustc_builtin_macros::cmdline_attrs::inject( &mut krate, &sess.parse_sess, @@ -127,15 +125,6 @@ impl<'tcx> Queries<'tcx> { let pre_configured_attrs = rustc_expand::config::pre_configure_attrs(sess, &krate.attrs); - Ok((krate, pre_configured_attrs)) - }) - } - - pub fn global_ctxt(&'tcx self) -> Result>> { - self.gcx.compute(|| { - let sess = &self.compiler.sess; - #[allow(deprecated)] - let (krate, pre_configured_attrs) = self.pre_configure()?.steal(); // parse `#[crate_name]` even if `--crate-name` was passed, to make sure it matches. let crate_name = find_crate_name(sess, &pre_configured_attrs); @@ -146,6 +135,7 @@ impl<'tcx> Queries<'tcx> { sess.opts.cg.metadata.clone(), sess.cfg_version, ); + let outputs = util::build_output_filenames(&pre_configured_attrs, sess); let dep_graph = setup_dep_graph(sess, crate_name, stable_crate_id)?; let cstore = FreezeLock::new(Box::new(CStore::new( @@ -180,11 +170,19 @@ impl<'tcx> Queries<'tcx> { crate_name, ))); feed.crate_for_resolver(tcx.arena.alloc(Steal::new((krate, pre_configured_attrs)))); + feed.output_filenames(Arc::new(outputs)); }); Ok(qcx) }) } + pub fn write_dep_info(&'tcx self) -> Result<()> { + self.global_ctxt()?.enter(|tcx| { + passes::write_dep_info(tcx); + }); + Ok(()) + } + /// Check for the `#[rustc_error]` annotation, which forces an error in codegen. This is used /// to write UI tests that actually test that compilation succeeds without reporting /// an error. @@ -284,8 +282,13 @@ impl Linker { if sess.opts.unstable_opts.no_link { let rlink_file = self.output_filenames.with_extension(config::RLINK_EXT); - CodegenResults::serialize_rlink(sess, &rlink_file, &codegen_results) - .map_err(|error| sess.emit_fatal(FailedWritingFile { path: &rlink_file, error }))?; + CodegenResults::serialize_rlink( + sess, + &rlink_file, + &codegen_results, + &*self.output_filenames, + ) + .map_err(|error| sess.emit_fatal(FailedWritingFile { path: &rlink_file, error }))?; return Ok(()); } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 2d2a3c3d665..d6e7afb7d09 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -580,7 +580,7 @@ pub enum ResolveDocLinks { /// *Do not* switch `BTreeMap` out for an unsorted container type! That would break /// dependency tracking for command-line arguments. Also only hash keys, since tracking /// should only depend on the output types, not the paths they're written to. -#[derive(Clone, Debug, Hash, HashStable_Generic)] +#[derive(Clone, Debug, Hash, HashStable_Generic, Encodable, Decodable)] pub struct OutputTypes(BTreeMap>); impl OutputTypes { @@ -818,7 +818,7 @@ impl Input { } } -#[derive(Clone, Hash, Debug, HashStable_Generic, PartialEq)] +#[derive(Clone, Hash, Debug, HashStable_Generic, PartialEq, Encodable, Decodable)] pub enum OutFileName { Real(PathBuf), Stdout, @@ -890,7 +890,7 @@ impl OutFileName { } } -#[derive(Clone, Hash, Debug, HashStable_Generic)] +#[derive(Clone, Hash, Debug, HashStable_Generic, Encodable, Decodable)] pub struct OutputFilenames { pub out_directory: PathBuf, /// Crate name. Never contains '-'.