Rollup merge of #133567 - bjorn3:various_cleanups, r=cjgillot

A bunch of cleanups

These are all extracted from a branch I have to get rid of driver queries. Most of the commits are not directly necessary for this, but were found in the process of implementing the removal of driver queries.

Previous PR: https://github.com/rust-lang/rust/pull/132410
This commit is contained in:
Matthias Krüger 2024-12-09 01:56:32 +01:00 committed by GitHub
commit d2881e4eb5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
36 changed files with 309 additions and 335 deletions

View file

@ -5,9 +5,9 @@ use std::sync::Arc;
use rustc_ast::{LitKind, MetaItemKind, token};
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::jobserver;
use rustc_data_structures::stable_hasher::StableHasher;
use rustc_data_structures::sync::Lrc;
use rustc_data_structures::{defer, jobserver};
use rustc_errors::registry::Registry;
use rustc_errors::{DiagCtxtHandle, ErrorGuaranteed};
use rustc_lint::LintStore;
@ -441,7 +441,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
temps_dir,
},
bundle,
config.registry.clone(),
config.registry,
locale_resources,
config.lint_caps,
target,
@ -492,32 +492,34 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
// There are two paths out of `f`.
// - Normal exit.
// - Panic, e.g. triggered by `abort_if_errors`.
// - Panic, e.g. triggered by `abort_if_errors` or a fatal error.
//
// We must run `finish_diagnostics` in both cases.
let res = {
// If `f` panics, `finish_diagnostics` will run during
// unwinding because of the `defer`.
let sess_abort_guard = defer(|| {
compiler.sess.finish_diagnostics(&config.registry);
});
let res = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| f(&compiler)));
let res = f(&compiler);
compiler.sess.finish_diagnostics();
// If `f` doesn't panic, `finish_diagnostics` will run
// normally when `sess_abort_guard` is dropped.
drop(sess_abort_guard);
// If error diagnostics have been emitted, we can't return an
// error directly, because the return type of this function
// is `R`, not `Result<R, E>`. But we need to communicate the
// errors' existence to the caller, otherwise the caller might
// mistakenly think that no errors occurred and return a zero
// exit code. So we abort (panic) instead, similar to if `f`
// had panicked.
// If error diagnostics have been emitted, we can't return an
// error directly, because the return type of this function
// is `R`, not `Result<R, E>`. But we need to communicate the
// errors' existence to the caller, otherwise the caller might
// mistakenly think that no errors occurred and return a zero
// exit code. So we abort (panic) instead, similar to if `f`
// had panicked.
if res.is_ok() {
compiler.sess.dcx().abort_if_errors();
}
res
// Also make sure to flush delayed bugs as if we panicked, the
// bugs would be flushed by the Drop impl of DiagCtxt while
// unwinding, which would result in an abort with
// "panic in a destructor during cleanup".
compiler.sess.dcx().flush_delayed();
let res = match res {
Ok(res) => res,
// Resume unwinding if a panic happened.
Err(err) => std::panic::resume_unwind(err),
};
let prof = compiler.sess.prof.clone();

View file

@ -33,15 +33,15 @@ use rustc_session::output::{collect_crate_types, filename_for_input, find_crate_
use rustc_session::search_paths::PathKind;
use rustc_session::{Limit, Session};
use rustc_span::symbol::{Symbol, sym};
use rustc_span::{FileName, SourceFileHash, SourceFileHashAlgorithm};
use rustc_span::{ErrorGuaranteed, FileName, SourceFileHash, SourceFileHashAlgorithm};
use rustc_target::spec::PanicStrategy;
use rustc_trait_selection::traits;
use tracing::{info, instrument};
use crate::interface::{Compiler, Result};
use crate::interface::Compiler;
use crate::{errors, proc_macro_decls, util};
pub(crate) fn parse<'a>(sess: &'a Session) -> Result<ast::Crate> {
pub(crate) fn parse<'a>(sess: &'a Session) -> ast::Crate {
let krate = sess
.time("parse_crate", || {
let mut parser = unwrap_or_emit_fatal(match &sess.io.input {
@ -52,13 +52,16 @@ pub(crate) fn parse<'a>(sess: &'a Session) -> Result<ast::Crate> {
});
parser.parse_crate_mod()
})
.map_err(|parse_error| parse_error.emit())?;
.unwrap_or_else(|parse_error| {
let guar: ErrorGuaranteed = parse_error.emit();
guar.raise_fatal();
});
if sess.opts.unstable_opts.input_stats {
input_stats::print_ast_stats(&krate, "PRE EXPANSION AST STATS", "ast-stats-1");
}
Ok(krate)
krate
}
fn pre_expansion_lint<'a>(
@ -712,7 +715,7 @@ pub(crate) fn create_global_ctxt<'tcx>(
gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
arena: &'tcx WorkerLocal<Arena<'tcx>>,
hir_arena: &'tcx WorkerLocal<rustc_hir::Arena<'tcx>>,
) -> Result<&'tcx GlobalCtxt<'tcx>> {
) -> &'tcx GlobalCtxt<'tcx> {
let sess = &compiler.sess;
rustc_builtin_macros::cmdline_attrs::inject(
@ -733,7 +736,7 @@ pub(crate) fn create_global_ctxt<'tcx>(
sess.cfg_version,
);
let outputs = util::build_output_filenames(&pre_configured_attrs, sess);
let dep_graph = setup_dep_graph(sess)?;
let dep_graph = setup_dep_graph(sess);
let cstore =
FreezeLock::new(Box::new(CStore::new(compiler.codegen_backend.metadata_loader())) as _);
@ -796,7 +799,7 @@ pub(crate) fn create_global_ctxt<'tcx>(
feed.crate_for_resolver(tcx.arena.alloc(Steal::new((krate, pre_configured_attrs))));
feed.output_filenames(Arc::new(outputs));
});
Ok(qcx)
qcx
})
}
@ -906,7 +909,7 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
/// Runs the type-checking, region checking and other miscellaneous analysis
/// passes on the crate.
fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
fn analysis(tcx: TyCtxt<'_>, (): ()) {
run_required_analyses(tcx);
let sess = tcx.sess;
@ -920,7 +923,7 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
// But we exclude lint errors from this, because lint errors are typically
// less serious and we're more likely to want to continue (#87337).
if let Some(guar) = sess.dcx().has_errors_excluding_lint_errors() {
return Err(guar);
guar.raise_fatal();
}
sess.time("misc_checking_3", || {
@ -1048,8 +1051,6 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
})
}
}
Ok(())
}
/// Check for the `#[rustc_error]` annotation, which forces an error in codegen. This is used
@ -1091,12 +1092,12 @@ fn check_for_rustc_errors_attr(tcx: TyCtxt<'_>) {
pub(crate) fn start_codegen<'tcx>(
codegen_backend: &dyn CodegenBackend,
tcx: TyCtxt<'tcx>,
) -> Result<Box<dyn Any>> {
) -> Box<dyn Any> {
// Don't do code generation if there were any errors. Likewise if
// there were any delayed bugs, because codegen will likely cause
// more ICEs, obscuring the original problem.
if let Some(guar) = tcx.sess.dcx().has_errors_or_delayed_bugs() {
return Err(guar);
guar.raise_fatal();
}
// Hook for UI tests.
@ -1124,7 +1125,7 @@ pub(crate) fn start_codegen<'tcx>(
}
}
Ok(codegen)
codegen
}
fn get_recursion_limit(krate_attrs: &[ast::Attribute], sess: &Session) -> Limit {

View file

@ -16,7 +16,7 @@ use rustc_session::Session;
use rustc_session::config::{self, OutputFilenames, OutputType};
use crate::errors::FailedWritingFile;
use crate::interface::{Compiler, Result};
use crate::interface::Compiler;
use crate::passes;
/// Represent the result of a query.
@ -27,19 +27,17 @@ use crate::passes;
/// [`compute`]: Self::compute
pub struct Query<T> {
/// `None` means no value has been computed yet.
result: RefCell<Option<Result<Steal<T>>>>,
result: RefCell<Option<Steal<T>>>,
}
impl<T> Query<T> {
fn compute<F: FnOnce() -> Result<T>>(&self, f: F) -> Result<QueryResult<'_, T>> {
RefMut::filter_map(
fn compute<F: FnOnce() -> T>(&self, f: F) -> QueryResult<'_, T> {
QueryResult(RefMut::map(
self.result.borrow_mut(),
|r: &mut Option<Result<Steal<T>>>| -> Option<&mut Steal<T>> {
r.get_or_insert_with(|| f().map(Steal::new)).as_mut().ok()
|r: &mut Option<Steal<T>>| -> &mut Steal<T> {
r.get_or_insert_with(|| Steal::new(f()))
},
)
.map_err(|r| *r.as_ref().unwrap().as_ref().map(|_| ()).unwrap_err())
.map(QueryResult)
))
}
}
@ -95,13 +93,13 @@ impl<'tcx> Queries<'tcx> {
}
}
pub fn parse(&self) -> Result<QueryResult<'_, ast::Crate>> {
pub fn parse(&self) -> QueryResult<'_, ast::Crate> {
self.parse.compute(|| passes::parse(&self.compiler.sess))
}
pub fn global_ctxt(&'tcx self) -> Result<QueryResult<'tcx, &'tcx GlobalCtxt<'tcx>>> {
pub fn global_ctxt(&'tcx self) -> QueryResult<'tcx, &'tcx GlobalCtxt<'tcx>> {
self.gcx.compute(|| {
let krate = self.parse()?.steal();
let krate = self.parse().steal();
passes::create_global_ctxt(
self.compiler,
@ -126,8 +124,8 @@ impl Linker {
pub fn codegen_and_build_linker(
tcx: TyCtxt<'_>,
codegen_backend: &dyn CodegenBackend,
) -> Result<Linker> {
let ongoing_codegen = passes::start_codegen(codegen_backend, tcx)?;
) -> Linker {
let ongoing_codegen = passes::start_codegen(codegen_backend, tcx);
// This must run after monomorphization so that all generic types
// have been instantiated.
@ -141,7 +139,7 @@ impl Linker {
tcx.sess.code_stats.print_vtable_sizes(crate_name);
}
Ok(Linker {
Linker {
dep_graph: tcx.dep_graph.clone(),
output_filenames: Arc::clone(tcx.output_filenames(())),
crate_hash: if tcx.needs_crate_hash() {
@ -150,16 +148,17 @@ impl Linker {
None
},
ongoing_codegen,
})
}
}
pub fn link(self, sess: &Session, codegen_backend: &dyn CodegenBackend) -> Result<()> {
let (codegen_results, work_products) =
codegen_backend.join_codegen(self.ongoing_codegen, sess, &self.output_filenames);
pub fn link(self, sess: &Session, codegen_backend: &dyn CodegenBackend) {
let (codegen_results, work_products) = sess.time("finish_ongoing_codegen", || {
codegen_backend.join_codegen(self.ongoing_codegen, sess, &self.output_filenames)
});
if let Some(guar) = sess.dcx().has_errors() {
return Err(guar);
}
sess.dcx().abort_if_errors();
let _timer = sess.timer("link");
sess.time("serialize_work_products", || {
rustc_incremental::save_work_product_index(sess, &self.dep_graph, work_products)
@ -178,7 +177,7 @@ impl Linker {
.keys()
.any(|&i| i == OutputType::Exe || i == OutputType::Metadata)
{
return Ok(());
return;
}
if sess.opts.unstable_opts.no_link {
@ -189,10 +188,10 @@ impl Linker {
&codegen_results,
&*self.output_filenames,
)
.map_err(|error| {
.unwrap_or_else(|error| {
sess.dcx().emit_fatal(FailedWritingFile { path: &rlink_file, error })
})?;
return Ok(());
});
return;
}
let _timer = sess.prof.verbose_generic_activity("link_crate");