Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make output_filenames a real query #106812

Merged
merged 5 commits into from
Jan 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ fn compute_hir_hash(

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

let ast_index = index_crate(&resolver.node_id_to_def_id, &krate);
Expand Down
13 changes: 9 additions & 4 deletions compiler/rustc_driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,9 +296,8 @@ fn run_compiler(

if let Some(ppm) = &sess.opts.pretty {
if ppm.needs_ast_map() {
let expanded_crate = queries.expansion()?.borrow().0.clone();
queries.global_ctxt()?.enter(|tcx| {
pretty::print_after_hir_lowering(tcx, &*expanded_crate, *ppm);
pretty::print_after_hir_lowering(tcx, *ppm);
Ok(())
})?;
} else {
Expand Down Expand Up @@ -328,11 +327,15 @@ fn run_compiler(
}
}

queries.global_ctxt()?;
let mut gctxt = queries.global_ctxt()?;
if callbacks.after_expansion(compiler, queries) == Compilation::Stop {
return early_exit();
}

// Make sure the `output_filenames` query is run for its side
// effects of writing the dep-info and reporting errors.
gctxt.enter(|tcx| tcx.output_filenames(()));

if sess.opts.output_types.contains_key(&OutputType::DepInfo)
&& sess.opts.output_types.len() == 1
{
Expand All @@ -343,7 +346,7 @@ fn run_compiler(
return early_exit();
}

queries.global_ctxt()?.enter(|tcx| {
gctxt.enter(|tcx| {
let result = tcx.analysis(());
if sess.opts.unstable_opts.save_analysis {
let crate_name = tcx.crate_name(LOCAL_CRATE);
Expand All @@ -360,6 +363,8 @@ fn run_compiler(
result
})?;

drop(gctxt);

if callbacks.after_analysis(compiler, queries) == Compilation::Stop {
return early_exit();
}
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_driver/src/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ pub fn print_after_parsing(sess: &Session, krate: &ast::Crate, ppm: PpMode) {
write_or_print(&out, sess);
}

pub fn print_after_hir_lowering<'tcx>(tcx: TyCtxt<'tcx>, krate: &ast::Crate, ppm: PpMode) {
pub fn print_after_hir_lowering<'tcx>(tcx: TyCtxt<'tcx>, ppm: PpMode) {
if ppm.needs_analysis() {
abort_on_err(print_with_analysis(tcx, ppm), tcx.sess);
return;
Expand All @@ -420,7 +420,7 @@ pub fn print_after_hir_lowering<'tcx>(tcx: TyCtxt<'tcx>, krate: &ast::Crate, ppm
let parse = &sess.parse_sess;
pprust::print_crate(
sess.source_map(),
krate,
&tcx.resolver_for_lowering(()).borrow().1,
src_name,
src,
annotation.pp_ann(),
Expand All @@ -433,7 +433,7 @@ pub fn print_after_hir_lowering<'tcx>(tcx: TyCtxt<'tcx>, krate: &ast::Crate, ppm

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

Hir(s) => call_with_pp_support_hir(&s, tcx, move |annotation, hir_map| {
Expand Down
61 changes: 27 additions & 34 deletions compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -30,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, Untracked};
use rustc_session::cstore::{CrateStoreDyn, MetadataLoader, MetadataLoaderDyn, Untracked};
use rustc_session::output::filename_for_input;
use rustc_session::search_paths::PathKind;
use rustc_session::{Limit, Session};
Expand All @@ -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> {
Expand Down Expand Up @@ -548,7 +548,7 @@ fn escape_dep_env(symbol: Symbol) -> String {

fn write_out_deps(
sess: &Session,
boxed_resolver: &RefCell<BoxedResolver>,
cstore: &CrateStoreDyn,
outputs: &OutputFilenames,
out_filenames: &[PathBuf],
) {
Expand Down Expand Up @@ -600,20 +600,19 @@ fn write_out_deps(
}
}

boxed_resolver.borrow_mut().access(|resolver| {
for cnum in resolver.cstore().crates_untracked() {
let source = resolver.cstore().crate_source_untracked(cnum);
if let Some((path, _)) = &source.dylib {
files.push(escape_dep_filename(&path.display().to_string()));
}
if let Some((path, _)) = &source.rlib {
files.push(escape_dep_filename(&path.display().to_string()));
}
if let Some((path, _)) = &source.rmeta {
files.push(escape_dep_filename(&path.display().to_string()));
}
let cstore = cstore.as_any().downcast_ref::<CStore>().unwrap();
for cnum in cstore.crates_untracked() {
let source = cstore.crate_source_untracked(cnum);
if let Some((path, _)) = &source.dylib {
files.push(escape_dep_filename(&path.display().to_string()));
}
});
if let Some((path, _)) = &source.rlib {
files.push(escape_dep_filename(&path.display().to_string()));
}
if let Some((path, _)) = &source.rmeta {
files.push(escape_dep_filename(&path.display().to_string()));
}
}
}

let mut file = BufWriter::new(fs::File::create(&deps_filename)?);
Expand Down Expand Up @@ -661,13 +660,11 @@ fn write_out_deps(
}
}

pub fn prepare_outputs(
sess: &Session,
krate: &ast::Crate,
boxed_resolver: &RefCell<BoxedResolver>,
crate_name: Symbol,
) -> Result<OutputFilenames> {
fn output_filenames(tcx: TyCtxt<'_>, (): ()) -> Arc<OutputFilenames> {
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);
Expand All @@ -679,45 +676,41 @@ 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, boxed_resolver, &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;

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<Providers> = 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);
Expand Down
5 changes: 1 addition & 4 deletions compiler/rustc_interface/src/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ impl<'a, T> std::ops::DerefMut for QueryResult<'a, T> {
}

impl<'a, 'tcx> QueryResult<'a, QueryContext<'tcx>> {
pub fn enter<T>(mut self, f: impl FnOnce(TyCtxt<'tcx>) -> T) -> T {
pub fn enter<T>(&mut self, f: impl FnOnce(TyCtxt<'tcx>) -> T) -> T {
(*self.0).get_mut().enter(f)
}
}
Expand Down Expand Up @@ -212,8 +212,6 @@ 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(), &krate, &resolver, crate_name)?;

let ty::ResolverOutputs {
untracked,
global_ctxt: untracked_resolutions,
Expand All @@ -237,7 +235,6 @@ impl<'tcx> Queries<'tcx> {
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);
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<OutputFilenames> {
query output_filenames(_: ()) -> Arc<OutputFilenames> {
feedable
desc { "getting output filenames" }
arena_cache
}

/// Do not call this query directly: invoke `normalize` instead.
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -815,7 +815,7 @@ fn main_args(at_args: &[String]) -> MainResult {
sess.fatal("Compilation failed, aborting rustdoc");
}

let global_ctxt = abort_on_err(queries.global_ctxt(), sess);
let mut global_ctxt = abort_on_err(queries.global_ctxt(), sess);

global_ctxt.enter(|tcx| {
let (krate, render_opts, mut cache) = sess.time("run_global_ctxt", || {
Expand Down
13 changes: 13 additions & 0 deletions tests/run-make/overwrite-input/Makefile
Original file line number Diff line number Diff line change
@@ -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
6 changes: 6 additions & 0 deletions tests/run-make/overwrite-input/file.stderr
Original file line number Diff line number Diff line change
@@ -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

6 changes: 6 additions & 0 deletions tests/run-make/overwrite-input/folder.stderr
Original file line number Diff line number Diff line change
@@ -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

1 change: 1 addition & 0 deletions tests/run-make/overwrite-input/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fn main() {}
6 changes: 6 additions & 0 deletions tests/run-make/overwrite-input/main.stderr
Original file line number Diff line number Diff line change
@@ -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

39 changes: 39 additions & 0 deletions tests/ui/io-checks/inaccessbile-temp-dir.rs
Original file line number Diff line number Diff line change
@@ -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;
}
4 changes: 4 additions & 0 deletions tests/ui/io-checks/inaccessbile-temp-dir.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
error: failed to find or create the directory specified by `--temps-dir`

error: aborting due to previous error