Skip to content

Commit d7948c8

Browse files
committed
Auto merge of #106812 - oli-obk:output_filenames, r=petrochenkov
make `output_filenames` a real query part of #105462 This may be a perf regression and is not obviously the right way forward. We may store this information in the resolver after freezing it for example.
2 parents c62665e + d924a8c commit d7948c8

File tree

16 files changed

+119
-47
lines changed

16 files changed

+119
-47
lines changed

compiler/rustc_ast_lowering/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,7 @@ fn compute_hir_hash(
417417

418418
pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> {
419419
let sess = tcx.sess;
420+
tcx.ensure().output_filenames(());
420421
let (mut resolver, krate) = tcx.resolver_for_lowering(()).steal();
421422

422423
let ast_index = index_crate(&resolver.node_id_to_def_id, &krate);

compiler/rustc_driver/src/lib.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -296,9 +296,8 @@ fn run_compiler(
296296

297297
if let Some(ppm) = &sess.opts.pretty {
298298
if ppm.needs_ast_map() {
299-
let expanded_crate = queries.expansion()?.borrow().0.clone();
300299
queries.global_ctxt()?.enter(|tcx| {
301-
pretty::print_after_hir_lowering(tcx, &*expanded_crate, *ppm);
300+
pretty::print_after_hir_lowering(tcx, *ppm);
302301
Ok(())
303302
})?;
304303
} else {
@@ -328,11 +327,15 @@ fn run_compiler(
328327
}
329328
}
330329

331-
queries.global_ctxt()?;
330+
let mut gctxt = queries.global_ctxt()?;
332331
if callbacks.after_expansion(compiler, queries) == Compilation::Stop {
333332
return early_exit();
334333
}
335334

335+
// Make sure the `output_filenames` query is run for its side
336+
// effects of writing the dep-info and reporting errors.
337+
gctxt.enter(|tcx| tcx.output_filenames(()));
338+
336339
if sess.opts.output_types.contains_key(&OutputType::DepInfo)
337340
&& sess.opts.output_types.len() == 1
338341
{
@@ -343,7 +346,7 @@ fn run_compiler(
343346
return early_exit();
344347
}
345348

346-
queries.global_ctxt()?.enter(|tcx| {
349+
gctxt.enter(|tcx| {
347350
let result = tcx.analysis(());
348351
if sess.opts.unstable_opts.save_analysis {
349352
let crate_name = tcx.crate_name(LOCAL_CRATE);
@@ -360,6 +363,8 @@ fn run_compiler(
360363
result
361364
})?;
362365

366+
drop(gctxt);
367+
363368
if callbacks.after_analysis(compiler, queries) == Compilation::Stop {
364369
return early_exit();
365370
}

compiler/rustc_driver/src/pretty.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ pub fn print_after_parsing(sess: &Session, krate: &ast::Crate, ppm: PpMode) {
403403
write_or_print(&out, sess);
404404
}
405405

406-
pub fn print_after_hir_lowering<'tcx>(tcx: TyCtxt<'tcx>, krate: &ast::Crate, ppm: PpMode) {
406+
pub fn print_after_hir_lowering<'tcx>(tcx: TyCtxt<'tcx>, ppm: PpMode) {
407407
if ppm.needs_analysis() {
408408
abort_on_err(print_with_analysis(tcx, ppm), tcx.sess);
409409
return;
@@ -420,7 +420,7 @@ pub fn print_after_hir_lowering<'tcx>(tcx: TyCtxt<'tcx>, krate: &ast::Crate, ppm
420420
let parse = &sess.parse_sess;
421421
pprust::print_crate(
422422
sess.source_map(),
423-
krate,
423+
&tcx.resolver_for_lowering(()).borrow().1,
424424
src_name,
425425
src,
426426
annotation.pp_ann(),
@@ -433,7 +433,7 @@ pub fn print_after_hir_lowering<'tcx>(tcx: TyCtxt<'tcx>, krate: &ast::Crate, ppm
433433

434434
AstTree(PpAstTreeMode::Expanded) => {
435435
debug!("pretty-printing expanded AST");
436-
format!("{krate:#?}")
436+
format!("{:#?}", tcx.resolver_for_lowering(()).borrow().1)
437437
}
438438

439439
Hir(s) => call_with_pp_support_hir(&s, tcx, move |annotation, hir_map| {

compiler/rustc_interface/src/passes.rs

+27-34
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc_data_structures::parallel;
1616
use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal};
1717
use rustc_errors::{ErrorGuaranteed, PResult};
1818
use rustc_expand::base::{ExtCtxt, LintStoreExpand, ResolverExpand};
19-
use rustc_hir::def_id::StableCrateId;
19+
use rustc_hir::def_id::{StableCrateId, LOCAL_CRATE};
2020
use rustc_lint::{BufferedEarlyLint, EarlyCheckNode, LintStore};
2121
use rustc_metadata::creader::CStore;
2222
use rustc_middle::arena::Arena;
@@ -30,7 +30,7 @@ use rustc_plugin_impl as plugin;
3030
use rustc_query_impl::{OnDiskCache, Queries as TcxQueries};
3131
use rustc_resolve::{Resolver, ResolverArenas};
3232
use rustc_session::config::{CrateType, Input, OutputFilenames, OutputType};
33-
use rustc_session::cstore::{MetadataLoader, MetadataLoaderDyn, Untracked};
33+
use rustc_session::cstore::{CrateStoreDyn, MetadataLoader, MetadataLoaderDyn, Untracked};
3434
use rustc_session::output::filename_for_input;
3535
use rustc_session::search_paths::PathKind;
3636
use rustc_session::{Limit, Session};
@@ -47,7 +47,7 @@ use std::marker::PhantomPinned;
4747
use std::path::{Path, PathBuf};
4848
use std::pin::Pin;
4949
use std::rc::Rc;
50-
use std::sync::LazyLock;
50+
use std::sync::{Arc, LazyLock};
5151
use std::{env, fs, iter};
5252

5353
pub fn parse<'a>(sess: &'a Session) -> PResult<'a, ast::Crate> {
@@ -548,7 +548,7 @@ fn escape_dep_env(symbol: Symbol) -> String {
548548

549549
fn write_out_deps(
550550
sess: &Session,
551-
boxed_resolver: &RefCell<BoxedResolver>,
551+
cstore: &CrateStoreDyn,
552552
outputs: &OutputFilenames,
553553
out_filenames: &[PathBuf],
554554
) {
@@ -600,20 +600,19 @@ fn write_out_deps(
600600
}
601601
}
602602

603-
boxed_resolver.borrow_mut().access(|resolver| {
604-
for cnum in resolver.cstore().crates_untracked() {
605-
let source = resolver.cstore().crate_source_untracked(cnum);
606-
if let Some((path, _)) = &source.dylib {
607-
files.push(escape_dep_filename(&path.display().to_string()));
608-
}
609-
if let Some((path, _)) = &source.rlib {
610-
files.push(escape_dep_filename(&path.display().to_string()));
611-
}
612-
if let Some((path, _)) = &source.rmeta {
613-
files.push(escape_dep_filename(&path.display().to_string()));
614-
}
603+
let cstore = cstore.as_any().downcast_ref::<CStore>().unwrap();
604+
for cnum in cstore.crates_untracked() {
605+
let source = cstore.crate_source_untracked(cnum);
606+
if let Some((path, _)) = &source.dylib {
607+
files.push(escape_dep_filename(&path.display().to_string()));
615608
}
616-
});
609+
if let Some((path, _)) = &source.rlib {
610+
files.push(escape_dep_filename(&path.display().to_string()));
611+
}
612+
if let Some((path, _)) = &source.rmeta {
613+
files.push(escape_dep_filename(&path.display().to_string()));
614+
}
615+
}
617616
}
618617

619618
let mut file = BufWriter::new(fs::File::create(&deps_filename)?);
@@ -661,13 +660,11 @@ fn write_out_deps(
661660
}
662661
}
663662

664-
pub fn prepare_outputs(
665-
sess: &Session,
666-
krate: &ast::Crate,
667-
boxed_resolver: &RefCell<BoxedResolver>,
668-
crate_name: Symbol,
669-
) -> Result<OutputFilenames> {
663+
fn output_filenames(tcx: TyCtxt<'_>, (): ()) -> Arc<OutputFilenames> {
664+
let sess = tcx.sess;
670665
let _timer = sess.timer("prepare_outputs");
666+
let (_, krate) = &*tcx.resolver_for_lowering(()).borrow();
667+
let crate_name = tcx.crate_name(LOCAL_CRATE);
671668

672669
// FIXME: rustdoc passes &[] instead of &krate.attrs here
673670
let outputs = util::build_output_filenames(&krate.attrs, sess);
@@ -679,45 +676,41 @@ pub fn prepare_outputs(
679676
if let Some(ref input_path) = sess.io.input.opt_path() {
680677
if sess.opts.will_create_output_file() {
681678
if output_contains_path(&output_paths, input_path) {
682-
let reported = sess.emit_err(InputFileWouldBeOverWritten { path: input_path });
683-
return Err(reported);
679+
sess.emit_fatal(InputFileWouldBeOverWritten { path: input_path });
684680
}
685681
if let Some(ref dir_path) = output_conflicts_with_dir(&output_paths) {
686-
let reported =
687-
sess.emit_err(GeneratedFileConflictsWithDirectory { input_path, dir_path });
688-
return Err(reported);
682+
sess.emit_fatal(GeneratedFileConflictsWithDirectory { input_path, dir_path });
689683
}
690684
}
691685
}
692686

693687
if let Some(ref dir) = sess.io.temps_dir {
694688
if fs::create_dir_all(dir).is_err() {
695-
let reported = sess.emit_err(TempsDirError);
696-
return Err(reported);
689+
sess.emit_fatal(TempsDirError);
697690
}
698691
}
699692

700-
write_out_deps(sess, boxed_resolver, &outputs, &output_paths);
693+
write_out_deps(sess, tcx.cstore_untracked(), &outputs, &output_paths);
701694

702695
let only_dep_info = sess.opts.output_types.contains_key(&OutputType::DepInfo)
703696
&& sess.opts.output_types.len() == 1;
704697

705698
if !only_dep_info {
706699
if let Some(ref dir) = sess.io.output_dir {
707700
if fs::create_dir_all(dir).is_err() {
708-
let reported = sess.emit_err(OutDirError);
709-
return Err(reported);
701+
sess.emit_fatal(OutDirError);
710702
}
711703
}
712704
}
713705

714-
Ok(outputs)
706+
outputs.into()
715707
}
716708

717709
pub static DEFAULT_QUERY_PROVIDERS: LazyLock<Providers> = LazyLock::new(|| {
718710
let providers = &mut Providers::default();
719711
providers.analysis = analysis;
720712
providers.hir_crate = rustc_ast_lowering::lower_to_hir;
713+
providers.output_filenames = output_filenames;
721714
proc_macro_decls::provide(providers);
722715
rustc_const_eval::provide(providers);
723716
rustc_middle::hir::provide(providers);

compiler/rustc_interface/src/queries.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ impl<'a, T> std::ops::DerefMut for QueryResult<'a, T> {
6565
}
6666

6767
impl<'a, 'tcx> QueryResult<'a, QueryContext<'tcx>> {
68-
pub fn enter<T>(mut self, f: impl FnOnce(TyCtxt<'tcx>) -> T) -> T {
68+
pub fn enter<T>(&mut self, f: impl FnOnce(TyCtxt<'tcx>) -> T) -> T {
6969
(*self.0).get_mut().enter(f)
7070
}
7171
}
@@ -212,8 +212,6 @@ impl<'tcx> Queries<'tcx> {
212212
let crate_name = *self.crate_name()?.borrow();
213213
let (krate, resolver, lint_store) = self.expansion()?.steal();
214214

215-
let outputs = passes::prepare_outputs(self.session(), &krate, &resolver, crate_name)?;
216-
217215
let ty::ResolverOutputs {
218216
untracked,
219217
global_ctxt: untracked_resolutions,
@@ -237,7 +235,6 @@ impl<'tcx> Queries<'tcx> {
237235
tcx.arena.alloc(Steal::new((untracked_resolver_for_lowering, krate))),
238236
);
239237
feed.resolutions(tcx.arena.alloc(untracked_resolutions));
240-
feed.output_filenames(tcx.arena.alloc(std::sync::Arc::new(outputs)));
241238
feed.features_query(tcx.sess.features_untracked());
242239
let feed = tcx.feed_local_crate();
243240
feed.crate_name(crate_name);

compiler/rustc_middle/src/query/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1863,9 +1863,10 @@ rustc_queries! {
18631863
///
18641864
/// This query returns an `&Arc` because codegen backends need the value even after the `TyCtxt`
18651865
/// has been destroyed.
1866-
query output_filenames(_: ()) -> &'tcx Arc<OutputFilenames> {
1866+
query output_filenames(_: ()) -> Arc<OutputFilenames> {
18671867
feedable
18681868
desc { "getting output filenames" }
1869+
arena_cache
18691870
}
18701871

18711872
/// Do not call this query directly: invoke `normalize` instead.

src/librustdoc/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,7 @@ fn main_args(at_args: &[String]) -> MainResult {
815815
sess.fatal("Compilation failed, aborting rustdoc");
816816
}
817817

818-
let global_ctxt = abort_on_err(queries.global_ctxt(), sess);
818+
let mut global_ctxt = abort_on_err(queries.global_ctxt(), sess);
819819

820820
global_ctxt.enter(|tcx| {
821821
let (krate, render_opts, mut cache) = sess.time("run_global_ctxt", || {
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
include ../../run-make-fulldeps/tools.mk
2+
3+
all:
4+
$(RUSTC) main.rs -o main.rs 2> $(TMPDIR)/file.stderr || echo "failed successfully"
5+
$(RUSTC) main.rs -o . 2> $(TMPDIR)/folder.stderr || echo "failed successfully"
6+
7+
ifdef RUSTC_BLESS_TEST
8+
cp "$(TMPDIR)"/file.stderr file.stderr
9+
cp "$(TMPDIR)"/folder.stderr folder.stderr
10+
else
11+
$(DIFF) file.stderr "$(TMPDIR)"/file.stderr
12+
$(DIFF) folder.stderr "$(TMPDIR)"/folder.stderr
13+
endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
warning: ignoring --out-dir flag due to -o flag
2+
3+
error: the input file "main.rs" would be overwritten by the generated executable
4+
5+
error: aborting due to previous error; 1 warning emitted
6+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
warning: ignoring --out-dir flag due to -o flag
2+
3+
error: the generated executable for the input file "main.rs" conflicts with the existing directory "."
4+
5+
error: aborting due to previous error; 1 warning emitted
6+
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
warning: ignoring --out-dir flag due to -o flag
2+
3+
error: the input file "main.rs" would be overwritten by the generated executable
4+
5+
error: aborting due to previous error; 1 warning emitted
6+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Issue #66530: We would ICE if someone compiled with `-o /dev/null`,
2+
// because we would try to generate auxiliary files in `/dev/` (which
3+
// at least the OS X file system rejects).
4+
//
5+
// An attempt to `-o` into a directory we cannot write into should indeed
6+
// be an error; but not an ICE.
7+
//
8+
// However, some folks run tests as root, which can write `/dev/` and end
9+
// up clobbering `/dev/null`. Instead we'll use a non-existent path, which
10+
// also used to ICE, but even root can't magically write there.
11+
12+
// compile-flags: -Z temps-dir=/does-not-exist/output
13+
14+
// The error-pattern check occurs *before* normalization, and the error patterns
15+
// are wildly different between build environments. So this is a cop-out (and we
16+
// rely on the checking of the normalized stderr output as our actual
17+
// "verification" of the diagnostic).
18+
19+
// error-pattern: error
20+
21+
// On Mac OS X, we get an error like the below
22+
// normalize-stderr-test "failed to write bytecode to /does-not-exist/output.non_ice_error_on_worker_io_fail.*" -> "io error modifying /does-not-exist/"
23+
24+
// On Linux, we get an error like the below
25+
// normalize-stderr-test "couldn't create a temp dir.*" -> "io error modifying /does-not-exist/"
26+
27+
// ignore-windows - this is a unix-specific test
28+
// ignore-emscripten - the file-system issues do not replicate here
29+
// ignore-wasm - the file-system issues do not replicate here
30+
// ignore-arm - the file-system issues do not replicate here, at least on armhf-gnu
31+
32+
#![crate_type = "lib"]
33+
#![cfg_attr(not(feature = "std"), no_std)]
34+
pub mod task {
35+
pub mod __internal {
36+
use crate::task::Waker;
37+
}
38+
pub use core::task::Waker;
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
error: failed to find or create the directory specified by `--temps-dir`
2+
3+
error: aborting due to previous error
4+

0 commit comments

Comments
 (0)