Skip to content

Commit ac9b308

Browse files
committed
Auto merge of #117584 - bjorn3:eager_output_filenames, r=b-naber
Eagerly compute output_filenames It can be computed before creating TyCtxt. Previously the query would also write the dep info file, which meant that the output filenames couldn't be accessed before macro expansion is done. The dep info file writing is now done as a separate non-query function. The old query was always executed again anyways due to depending on the HIR. Also encode the output_filenames in rlink files to ensure `#![crate_name]` affects the linking stage when doing separate compiling and linking using `-Zno-link`/`-Zlink-only`.
2 parents 6cf0888 + d7e9a30 commit ac9b308

File tree

6 files changed

+46
-53
lines changed

6 files changed

+46
-53
lines changed

compiler/rustc_codegen_ssa/src/lib.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ impl CodegenResults {
216216
sess: &Session,
217217
rlink_file: &Path,
218218
codegen_results: &CodegenResults,
219+
outputs: &OutputFilenames,
219220
) -> Result<usize, io::Error> {
220221
let mut encoder = FileEncoder::new(rlink_file)?;
221222
encoder.emit_raw_bytes(RLINK_MAGIC);
@@ -224,10 +225,14 @@ impl CodegenResults {
224225
encoder.emit_raw_bytes(&RLINK_VERSION.to_be_bytes());
225226
encoder.emit_str(sess.cfg_version);
226227
Encodable::encode(codegen_results, &mut encoder);
228+
Encodable::encode(outputs, &mut encoder);
227229
encoder.finish().map_err(|(_path, err)| err)
228230
}
229231

230-
pub fn deserialize_rlink(sess: &Session, data: Vec<u8>) -> Result<Self, CodegenErrors> {
232+
pub fn deserialize_rlink(
233+
sess: &Session,
234+
data: Vec<u8>,
235+
) -> Result<(Self, OutputFilenames), CodegenErrors> {
231236
// The Decodable machinery is not used here because it panics if the input data is invalid
232237
// and because its internal representation may change.
233238
if !data.starts_with(RLINK_MAGIC) {
@@ -256,6 +261,7 @@ impl CodegenResults {
256261
}
257262

258263
let codegen_results = CodegenResults::decode(&mut decoder);
259-
Ok(codegen_results)
264+
let outputs = OutputFilenames::decode(&mut decoder);
265+
Ok((codegen_results, outputs))
260266
}
261267
}

compiler/rustc_driver_impl/src/lib.rs

+4-9
Original file line numberDiff line numberDiff line change
@@ -401,9 +401,7 @@ fn run_compiler(
401401
Ok(())
402402
})?;
403403

404-
// Make sure the `output_filenames` query is run for its side
405-
// effects of writing the dep-info and reporting errors.
406-
queries.global_ctxt()?.enter(|tcx| tcx.output_filenames(()));
404+
queries.write_dep_info()?;
407405
} else {
408406
let krate = queries.parse()?;
409407
pretty::print(
@@ -431,9 +429,7 @@ fn run_compiler(
431429
return early_exit();
432430
}
433431

434-
// Make sure the `output_filenames` query is run for its side
435-
// effects of writing the dep-info and reporting errors.
436-
queries.global_ctxt()?.enter(|tcx| tcx.output_filenames(()));
432+
queries.write_dep_info()?;
437433

438434
if sess.opts.output_types.contains_key(&OutputType::DepInfo)
439435
&& sess.opts.output_types.len() == 1
@@ -648,12 +644,11 @@ fn show_md_content_with_pager(content: &str, color: ColorConfig) {
648644
fn process_rlink(sess: &Session, compiler: &interface::Compiler) {
649645
assert!(sess.opts.unstable_opts.link_only);
650646
if let Input::File(file) = &sess.io.input {
651-
let outputs = compiler.build_output_filenames(sess, &[]);
652647
let rlink_data = fs::read(file).unwrap_or_else(|err| {
653648
sess.emit_fatal(RlinkUnableToRead { err });
654649
});
655-
let codegen_results = match CodegenResults::deserialize_rlink(sess, rlink_data) {
656-
Ok(codegen) => codegen,
650+
let (codegen_results, outputs) = match CodegenResults::deserialize_rlink(sess, rlink_data) {
651+
Ok((codegen, outputs)) => (codegen, outputs),
657652
Err(err) => {
658653
match err {
659654
CodegenErrors::WrongFileType => sess.emit_fatal(RLinkWrongFileType),

compiler/rustc_interface/src/interface.rs

+2-14
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::util;
22

33
use rustc_ast::token;
4-
use rustc_ast::{self as ast, LitKind, MetaItemKind};
4+
use rustc_ast::{LitKind, MetaItemKind};
55
use rustc_codegen_ssa::traits::CodegenBackend;
66
use rustc_data_structures::defer;
77
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -15,9 +15,7 @@ use rustc_middle::{bug, ty};
1515
use rustc_parse::maybe_new_parser_from_source_str;
1616
use rustc_query_impl::QueryCtxt;
1717
use rustc_query_system::query::print_query_stack;
18-
use rustc_session::config::{
19-
self, Cfg, CheckCfg, ExpectedValues, Input, OutFileName, OutputFilenames,
20-
};
18+
use rustc_session::config::{self, Cfg, CheckCfg, ExpectedValues, Input, OutFileName};
2119
use rustc_session::filesearch::sysroot_candidates;
2220
use rustc_session::parse::ParseSess;
2321
use rustc_session::{lint, CompilerIO, EarlyErrorHandler, Session};
@@ -43,16 +41,6 @@ pub struct Compiler {
4341
pub(crate) override_queries: Option<fn(&Session, &mut Providers)>,
4442
}
4543

46-
impl Compiler {
47-
pub fn build_output_filenames(
48-
&self,
49-
sess: &Session,
50-
attrs: &[ast::Attribute],
51-
) -> OutputFilenames {
52-
util::build_output_filenames(attrs, sess)
53-
}
54-
}
55-
5644
/// Converts strings provided as `--cfg [cfgspec]` into a `Cfg`.
5745
pub(crate) fn parse_cfg(handler: &EarlyErrorHandler, cfgs: Vec<String>) -> Cfg {
5846
cfgs.into_iter()

compiler/rustc_interface/src/passes.rs

+9-8
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ use std::any::Any;
3939
use std::ffi::OsString;
4040
use std::io::{self, BufWriter, Write};
4141
use std::path::{Path, PathBuf};
42-
use std::sync::{Arc, LazyLock};
42+
use std::sync::LazyLock;
4343
use std::{env, fs, iter};
4444

4545
pub fn parse<'a>(sess: &'a Session) -> PResult<'a, ast::Crate> {
@@ -553,13 +553,17 @@ fn resolver_for_lowering<'tcx>(
553553
tcx.arena.alloc(Steal::new((untracked_resolver_for_lowering, Lrc::new(krate))))
554554
}
555555

556-
fn output_filenames(tcx: TyCtxt<'_>, (): ()) -> Arc<OutputFilenames> {
556+
pub(crate) fn write_dep_info(tcx: TyCtxt<'_>) {
557+
// Make sure name resolution and macro expansion is run for
558+
// the side-effect of providing a complete set of all
559+
// accessed files and env vars.
560+
let _ = tcx.resolver_for_lowering(());
561+
557562
let sess = tcx.sess;
558-
let _timer = sess.timer("prepare_outputs");
559-
let (_, krate) = &*tcx.resolver_for_lowering(()).borrow();
563+
let _timer = sess.timer("write_dep_info");
560564
let crate_name = tcx.crate_name(LOCAL_CRATE);
561565

562-
let outputs = util::build_output_filenames(&krate.attrs, sess);
566+
let outputs = tcx.output_filenames(());
563567
let output_paths =
564568
generated_output_paths(tcx, &outputs, sess.io.output_file.is_some(), crate_name);
565569

@@ -596,15 +600,12 @@ fn output_filenames(tcx: TyCtxt<'_>, (): ()) -> Arc<OutputFilenames> {
596600
}
597601
}
598602
}
599-
600-
outputs.into()
601603
}
602604

603605
pub static DEFAULT_QUERY_PROVIDERS: LazyLock<Providers> = LazyLock::new(|| {
604606
let providers = &mut Providers::default();
605607
providers.analysis = analysis;
606608
providers.hir_crate = rustc_ast_lowering::lower_to_hir;
607-
providers.output_filenames = output_filenames;
608609
providers.resolver_for_lowering = resolver_for_lowering;
609610
providers.early_lint_checks = early_lint_checks;
610611
proc_macro_decls::provide(providers);

compiler/rustc_interface/src/queries.rs

+20-17
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ pub struct Queries<'tcx> {
8585
hir_arena: WorkerLocal<rustc_hir::Arena<'tcx>>,
8686

8787
parse: Query<ast::Crate>,
88-
pre_configure: Query<(ast::Crate, ast::AttrVec)>,
8988
// This just points to what's in `gcx_cell`.
9089
gcx: Query<&'tcx GlobalCtxt<'tcx>>,
9190
}
@@ -98,7 +97,6 @@ impl<'tcx> Queries<'tcx> {
9897
arena: WorkerLocal::new(|_| Arena::default()),
9998
hir_arena: WorkerLocal::new(|_| rustc_hir::Arena::default()),
10099
parse: Default::default(),
101-
pre_configure: Default::default(),
102100
gcx: Default::default(),
103101
}
104102
}
@@ -113,12 +111,12 @@ impl<'tcx> Queries<'tcx> {
113111
})
114112
}
115113

116-
#[deprecated = "pre_configure may be made private in the future. If you need it please open an issue with your use case."]
117-
pub fn pre_configure(&self) -> Result<QueryResult<'_, (ast::Crate, ast::AttrVec)>> {
118-
self.pre_configure.compute(|| {
114+
pub fn global_ctxt(&'tcx self) -> Result<QueryResult<'_, &'tcx GlobalCtxt<'tcx>>> {
115+
self.gcx.compute(|| {
116+
let sess = &self.compiler.sess;
117+
119118
let mut krate = self.parse()?.steal();
120119

121-
let sess = &self.compiler.sess;
122120
rustc_builtin_macros::cmdline_attrs::inject(
123121
&mut krate,
124122
&sess.parse_sess,
@@ -127,15 +125,6 @@ impl<'tcx> Queries<'tcx> {
127125

128126
let pre_configured_attrs =
129127
rustc_expand::config::pre_configure_attrs(sess, &krate.attrs);
130-
Ok((krate, pre_configured_attrs))
131-
})
132-
}
133-
134-
pub fn global_ctxt(&'tcx self) -> Result<QueryResult<'_, &'tcx GlobalCtxt<'tcx>>> {
135-
self.gcx.compute(|| {
136-
let sess = &self.compiler.sess;
137-
#[allow(deprecated)]
138-
let (krate, pre_configured_attrs) = self.pre_configure()?.steal();
139128

140129
// parse `#[crate_name]` even if `--crate-name` was passed, to make sure it matches.
141130
let crate_name = find_crate_name(sess, &pre_configured_attrs);
@@ -146,6 +135,7 @@ impl<'tcx> Queries<'tcx> {
146135
sess.opts.cg.metadata.clone(),
147136
sess.cfg_version,
148137
);
138+
let outputs = util::build_output_filenames(&pre_configured_attrs, sess);
149139
let dep_graph = setup_dep_graph(sess, crate_name, stable_crate_id)?;
150140

151141
let cstore = FreezeLock::new(Box::new(CStore::new(
@@ -180,11 +170,19 @@ impl<'tcx> Queries<'tcx> {
180170
crate_name,
181171
)));
182172
feed.crate_for_resolver(tcx.arena.alloc(Steal::new((krate, pre_configured_attrs))));
173+
feed.output_filenames(Arc::new(outputs));
183174
});
184175
Ok(qcx)
185176
})
186177
}
187178

179+
pub fn write_dep_info(&'tcx self) -> Result<()> {
180+
self.global_ctxt()?.enter(|tcx| {
181+
passes::write_dep_info(tcx);
182+
});
183+
Ok(())
184+
}
185+
188186
/// Check for the `#[rustc_error]` annotation, which forces an error in codegen. This is used
189187
/// to write UI tests that actually test that compilation succeeds without reporting
190188
/// an error.
@@ -284,8 +282,13 @@ impl Linker {
284282

285283
if sess.opts.unstable_opts.no_link {
286284
let rlink_file = self.output_filenames.with_extension(config::RLINK_EXT);
287-
CodegenResults::serialize_rlink(sess, &rlink_file, &codegen_results)
288-
.map_err(|error| sess.emit_fatal(FailedWritingFile { path: &rlink_file, error }))?;
285+
CodegenResults::serialize_rlink(
286+
sess,
287+
&rlink_file,
288+
&codegen_results,
289+
&*self.output_filenames,
290+
)
291+
.map_err(|error| sess.emit_fatal(FailedWritingFile { path: &rlink_file, error }))?;
289292
return Ok(());
290293
}
291294

compiler/rustc_session/src/config.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ pub enum ResolveDocLinks {
580580
/// *Do not* switch `BTreeMap` out for an unsorted container type! That would break
581581
/// dependency tracking for command-line arguments. Also only hash keys, since tracking
582582
/// should only depend on the output types, not the paths they're written to.
583-
#[derive(Clone, Debug, Hash, HashStable_Generic)]
583+
#[derive(Clone, Debug, Hash, HashStable_Generic, Encodable, Decodable)]
584584
pub struct OutputTypes(BTreeMap<OutputType, Option<OutFileName>>);
585585

586586
impl OutputTypes {
@@ -818,7 +818,7 @@ impl Input {
818818
}
819819
}
820820

821-
#[derive(Clone, Hash, Debug, HashStable_Generic, PartialEq)]
821+
#[derive(Clone, Hash, Debug, HashStable_Generic, PartialEq, Encodable, Decodable)]
822822
pub enum OutFileName {
823823
Real(PathBuf),
824824
Stdout,
@@ -890,7 +890,7 @@ impl OutFileName {
890890
}
891891
}
892892

893-
#[derive(Clone, Hash, Debug, HashStable_Generic)]
893+
#[derive(Clone, Hash, Debug, HashStable_Generic, Encodable, Decodable)]
894894
pub struct OutputFilenames {
895895
pub out_directory: PathBuf,
896896
/// Crate name. Never contains '-'.

0 commit comments

Comments
 (0)