From bcc8b05d5cf792d44b854a0097e9654021ad3177 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 23 Jan 2023 10:25:51 +0000 Subject: [PATCH] Make `output_filenames` a real query --- compiler/rustc_driver/src/lib.rs | 2 + compiler/rustc_interface/src/passes.rs | 32 +++++++-------- compiler/rustc_interface/src/queries.rs | 8 ---- compiler/rustc_middle/src/query/mod.rs | 3 +- tests/run-make/overwrite-input/Makefile | 13 +++++++ tests/run-make/overwrite-input/file.stderr | 6 +++ tests/run-make/overwrite-input/folder.stderr | 6 +++ tests/run-make/overwrite-input/main.rs | 1 + tests/run-make/overwrite-input/main.stderr | 6 +++ tests/ui/io-checks/inaccessbile-temp-dir.rs | 39 +++++++++++++++++++ .../ui/io-checks/inaccessbile-temp-dir.stderr | 4 ++ .../non-ice-error-on-worker-io-fail.rs | 0 .../non-ice-error-on-worker-io-fail.stderr | 0 13 files changed, 92 insertions(+), 28 deletions(-) create mode 100644 tests/run-make/overwrite-input/Makefile create mode 100644 tests/run-make/overwrite-input/file.stderr create mode 100644 tests/run-make/overwrite-input/folder.stderr create mode 100644 tests/run-make/overwrite-input/main.rs create mode 100644 tests/run-make/overwrite-input/main.stderr create mode 100644 tests/ui/io-checks/inaccessbile-temp-dir.rs create mode 100644 tests/ui/io-checks/inaccessbile-temp-dir.stderr rename tests/ui/{ => io-checks}/non-ice-error-on-worker-io-fail.rs (100%) rename tests/ui/{ => io-checks}/non-ice-error-on-worker-io-fail.stderr (100%) diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index f50ad0137b8..d00a68471bb 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -333,6 +333,8 @@ fn run_compiler( return early_exit(); } + queries.global_ctxt()?.enter(|tcx| tcx.output_filenames(())); + if sess.opts.output_types.contains_key(&OutputType::DepInfo) && sess.opts.output_types.len() == 1 { diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 4b3034c4781..37b381c534e 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -16,7 +16,7 @@ use rustc_data_structures::parallel; use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal}; use rustc_errors::{ErrorGuaranteed, PResult}; use rustc_expand::base::{ExtCtxt, LintStoreExpand, ResolverExpand}; -use rustc_hir::def_id::StableCrateId; +use rustc_hir::def_id::{StableCrateId, LOCAL_CRATE}; use rustc_lint::{BufferedEarlyLint, EarlyCheckNode, LintStore}; use rustc_metadata::creader::CStore; use rustc_middle::arena::Arena; @@ -47,7 +47,7 @@ use std::marker::PhantomPinned; use std::path::{Path, PathBuf}; use std::pin::Pin; use std::rc::Rc; -use std::sync::LazyLock; +use std::sync::{Arc, LazyLock}; use std::{env, fs, iter}; pub fn parse<'a>(sess: &'a Session) -> PResult<'a, ast::Crate> { @@ -660,13 +660,11 @@ fn write_out_deps( } } -pub fn prepare_outputs( - sess: &Session, - krate: &ast::Crate, - cstore: &CrateStoreDyn, - crate_name: Symbol, -) -> Result { +fn output_filenames(tcx: TyCtxt<'_>, (): ()) -> Arc { + let sess = tcx.sess; let _timer = sess.timer("prepare_outputs"); + let (_, krate) = &*tcx.resolver_for_lowering(()).borrow(); + let crate_name = tcx.crate_name(LOCAL_CRATE); // FIXME: rustdoc passes &[] instead of &krate.attrs here let outputs = util::build_output_filenames(&krate.attrs, sess); @@ -678,25 +676,21 @@ pub fn prepare_outputs( 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 }); - return Err(reported); + sess.emit_fatal(InputFileWouldBeOverWritten { path: input_path }); } if let Some(ref dir_path) = output_conflicts_with_dir(&output_paths) { - let reported = - sess.emit_err(GeneratedFileConflictsWithDirectory { input_path, dir_path }); - return Err(reported); + sess.emit_fatal(GeneratedFileConflictsWithDirectory { input_path, dir_path }); } } } 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); + sess.emit_fatal(TempsDirError); } } - write_out_deps(sess, cstore, &outputs, &output_paths); + write_out_deps(sess, tcx.cstore_untracked(), &outputs, &output_paths); let only_dep_info = sess.opts.output_types.contains_key(&OutputType::DepInfo) && sess.opts.output_types.len() == 1; @@ -704,19 +698,19 @@ pub fn prepare_outputs( if !only_dep_info { 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); + sess.emit_fatal(OutDirError); } } } - Ok(outputs) + 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; proc_macro_decls::provide(providers); rustc_const_eval::provide(providers); rustc_middle::hir::provide(providers); diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index fe24d41a4de..96cd3b06321 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -235,14 +235,6 @@ impl<'tcx> Queries<'tcx> { tcx.arena.alloc(Steal::new((untracked_resolver_for_lowering, krate))), ); feed.resolutions(tcx.arena.alloc(untracked_resolutions)); - - let outputs = passes::prepare_outputs( - self.session(), - &krate, - &*untracked.cstore, - crate_name, - )?; - 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); diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 6bbf7fa3914..b1da8d634ea 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1862,9 +1862,10 @@ rustc_queries! { /// /// This query returns an `&Arc` because codegen backends need the value even after the `TyCtxt` /// has been destroyed. - query output_filenames(_: ()) -> &'tcx Arc { + query output_filenames(_: ()) -> Arc { feedable desc { "getting output filenames" } + arena_cache } /// Do not call this query directly: invoke `normalize` instead. diff --git a/tests/run-make/overwrite-input/Makefile b/tests/run-make/overwrite-input/Makefile new file mode 100644 index 00000000000..03b03eb147d --- /dev/null +++ b/tests/run-make/overwrite-input/Makefile @@ -0,0 +1,13 @@ +include ../../run-make-fulldeps/tools.mk + +all: + $(RUSTC) main.rs -o main.rs 2> $(TMPDIR)/file.stderr || echo "failed successfully" + $(RUSTC) main.rs -o . 2> $(TMPDIR)/folder.stderr || echo "failed successfully" + +ifdef RUSTC_BLESS_TEST + cp "$(TMPDIR)"/file.stderr file.stderr + cp "$(TMPDIR)"/folder.stderr folder.stderr +else + $(DIFF) file.stderr "$(TMPDIR)"/file.stderr + $(DIFF) folder.stderr "$(TMPDIR)"/folder.stderr +endif diff --git a/tests/run-make/overwrite-input/file.stderr b/tests/run-make/overwrite-input/file.stderr new file mode 100644 index 00000000000..9936962b4ee --- /dev/null +++ b/tests/run-make/overwrite-input/file.stderr @@ -0,0 +1,6 @@ +warning: ignoring --out-dir flag due to -o flag + +error: the input file "main.rs" would be overwritten by the generated executable + +error: aborting due to previous error; 1 warning emitted + diff --git a/tests/run-make/overwrite-input/folder.stderr b/tests/run-make/overwrite-input/folder.stderr new file mode 100644 index 00000000000..81b1e7367c7 --- /dev/null +++ b/tests/run-make/overwrite-input/folder.stderr @@ -0,0 +1,6 @@ +warning: ignoring --out-dir flag due to -o flag + +error: the generated executable for the input file "main.rs" conflicts with the existing directory "." + +error: aborting due to previous error; 1 warning emitted + diff --git a/tests/run-make/overwrite-input/main.rs b/tests/run-make/overwrite-input/main.rs new file mode 100644 index 00000000000..f328e4d9d04 --- /dev/null +++ b/tests/run-make/overwrite-input/main.rs @@ -0,0 +1 @@ +fn main() {} diff --git a/tests/run-make/overwrite-input/main.stderr b/tests/run-make/overwrite-input/main.stderr new file mode 100644 index 00000000000..9936962b4ee --- /dev/null +++ b/tests/run-make/overwrite-input/main.stderr @@ -0,0 +1,6 @@ +warning: ignoring --out-dir flag due to -o flag + +error: the input file "main.rs" would be overwritten by the generated executable + +error: aborting due to previous error; 1 warning emitted + diff --git a/tests/ui/io-checks/inaccessbile-temp-dir.rs b/tests/ui/io-checks/inaccessbile-temp-dir.rs new file mode 100644 index 00000000000..9c0aa013572 --- /dev/null +++ b/tests/ui/io-checks/inaccessbile-temp-dir.rs @@ -0,0 +1,39 @@ +// Issue #66530: We would ICE if someone compiled with `-o /dev/null`, +// because we would try to generate auxiliary files in `/dev/` (which +// at least the OS X file system rejects). +// +// An attempt to `-o` into a directory we cannot write into should indeed +// be an error; but not an ICE. +// +// However, some folks run tests as root, which can write `/dev/` and end +// up clobbering `/dev/null`. Instead we'll use a non-existent path, which +// also used to ICE, but even root can't magically write there. + +// compile-flags: -Z temps-dir=/does-not-exist/output + +// The error-pattern check occurs *before* normalization, and the error patterns +// are wildly different between build environments. So this is a cop-out (and we +// rely on the checking of the normalized stderr output as our actual +// "verification" of the diagnostic). + +// error-pattern: error + +// On Mac OS X, we get an error like the below +// 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/" + +// On Linux, we get an error like the below +// normalize-stderr-test "couldn't create a temp dir.*" -> "io error modifying /does-not-exist/" + +// ignore-windows - this is a unix-specific test +// ignore-emscripten - the file-system issues do not replicate here +// ignore-wasm - the file-system issues do not replicate here +// ignore-arm - the file-system issues do not replicate here, at least on armhf-gnu + +#![crate_type = "lib"] +#![cfg_attr(not(feature = "std"), no_std)] +pub mod task { + pub mod __internal { + use crate::task::Waker; + } + pub use core::task::Waker; +} diff --git a/tests/ui/io-checks/inaccessbile-temp-dir.stderr b/tests/ui/io-checks/inaccessbile-temp-dir.stderr new file mode 100644 index 00000000000..2fc5f93ef79 --- /dev/null +++ b/tests/ui/io-checks/inaccessbile-temp-dir.stderr @@ -0,0 +1,4 @@ +error: failed to find or create the directory specified by `--temps-dir` + +error: aborting due to previous error + diff --git a/tests/ui/non-ice-error-on-worker-io-fail.rs b/tests/ui/io-checks/non-ice-error-on-worker-io-fail.rs similarity index 100% rename from tests/ui/non-ice-error-on-worker-io-fail.rs rename to tests/ui/io-checks/non-ice-error-on-worker-io-fail.rs diff --git a/tests/ui/non-ice-error-on-worker-io-fail.stderr b/tests/ui/io-checks/non-ice-error-on-worker-io-fail.stderr similarity index 100% rename from tests/ui/non-ice-error-on-worker-io-fail.stderr rename to tests/ui/io-checks/non-ice-error-on-worker-io-fail.stderr