Skip to content
Open
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
28 changes: 26 additions & 2 deletions compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ use rustc_session::getopts::{self, Matches};
use rustc_session::lint::{Lint, LintId};
use rustc_session::output::{CRATE_TYPES, collect_crate_types, invalid_output_for_target};
use rustc_session::{EarlyDiagCtxt, Session, config};
use rustc_span::FileName;
use rustc_span::def_id::LOCAL_CRATE;
use rustc_span::{FileName, sym};
use rustc_target::json::ToJson;
use rustc_target::spec::{Target, TargetTuple};
use tracing::trace;
Expand Down Expand Up @@ -383,7 +383,31 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send))
}
}

Some(Linker::codegen_and_build_linker(tcx, &*compiler.codegen_backend))
// Hook for tests. This must be shortly before the
// `has_errors_or_delayed_bugs` check below for
// `tests/ui/treat-err-as-bug/span_delayed_bug.rs` to work.
if let Some((def_id, _)) = tcx.entry_fn(())
&& tcx.has_attr(def_id, sym::rustc_delayed_bug_from_inside_query)
{
tcx.ensure_ok().trigger_delayed_bug(def_id);
}

// Don't emit metadata or do codegen if there were any errors.
//
// Note: checking for delayed bugs here is aggressive. If we have
// no errors but one or more delayed bugs, the `raise_fatal` call
// will instantly ICE when the DiagCtxt is dropped. I.e. this check
// serves as a kind of barrier, giving no opportunity for a
// subsequent error (e.g. during codegen) to nullify a delayed bug.
// The rationale is that delayed bugs are likely to cause more ICEs
// during codegen, obscuring the original problem.
if let Some(guar) = tcx.sess.dcx().has_errors_or_delayed_bugs() {
guar.raise_fatal();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This way it is easy to forget to call this function before calling codegen_and_build_linker. rustc_interface is meant to be called directly by custom drivers if rustc_driver doesn't provide enough flexibility. For example for rustdoc. mutest-rs also uses it directly. Also by moving this call before report_symbol_names, errors in the latter no longer block codegen. Maybe instead just move the tcx.sess.timings.start_section(tcx.sess.dcx(), TimingSection::Codegen); later in codegen_and_build_linker?


let metadata = rustc_metadata::fs::encode_and_write_metadata(tcx);

Some(Linker::codegen_and_build_linker(tcx, &*compiler.codegen_backend, metadata))
});

// Linking is done outside the `compiler.enter()` so that the
Expand Down
21 changes: 2 additions & 19 deletions compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ use rustc_hir::def_id::{LOCAL_CRATE, StableCrateId, StableCrateIdMap};
use rustc_hir::definitions::Definitions;
use rustc_incremental::setup_dep_graph;
use rustc_lint::{BufferedEarlyLint, EarlyCheckNode, LintStore, unerased_lint_store};
use rustc_metadata::EncodedMetadata;
use rustc_metadata::creader::CStore;
use rustc_middle::arena::Arena;
use rustc_middle::dep_graph::DepsType;
Expand Down Expand Up @@ -1196,33 +1195,17 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) {
pub(crate) fn start_codegen<'tcx>(
codegen_backend: &dyn CodegenBackend,
tcx: TyCtxt<'tcx>,
) -> (Box<dyn Any>, EncodedMetadata) {
) -> Box<dyn Any> {
tcx.sess.timings.start_section(tcx.sess.dcx(), TimingSection::Codegen);

// Hook for tests.
if let Some((def_id, _)) = tcx.entry_fn(())
&& tcx.has_attr(def_id, sym::rustc_delayed_bug_from_inside_query)
{
tcx.ensure_ok().trigger_delayed_bug(def_id);
}

// Don't run this test assertions when not doing codegen. Compiletest tries to build
// build-fail tests in check mode first and expects it to not give an error in that case.
if tcx.sess.opts.output_types.should_codegen() {
rustc_symbol_mangling::test::report_symbol_names(tcx);
}

// 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() {
guar.raise_fatal();
}

info!("Pre-codegen\n{:?}", tcx.debug_stats());

let metadata = rustc_metadata::fs::encode_and_write_metadata(tcx);

let codegen = tcx.sess.time("codegen_crate", move || codegen_backend.codegen_crate(tcx));

info!("Post-codegen\n{:?}", tcx.debug_stats());
Expand All @@ -1233,7 +1216,7 @@ pub(crate) fn start_codegen<'tcx>(
tcx.sess.code_stats.print_type_sizes();
}

(codegen, metadata)
codegen
}

/// Compute and validate the crate name.
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_interface/src/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ impl Linker {
pub fn codegen_and_build_linker(
tcx: TyCtxt<'_>,
codegen_backend: &dyn CodegenBackend,
metadata: EncodedMetadata,
) -> Linker {
let (ongoing_codegen, metadata) = passes::start_codegen(codegen_backend, tcx);
let ongoing_codegen = passes::start_codegen(codegen_backend, tcx);

Linker {
dep_graph: tcx.dep_graph.clone(),
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2274,6 +2274,8 @@ fn prefetch_mir(tcx: TyCtxt<'_>) {
// will allow us to slice the metadata to the precise length that we just
// generated regardless of trailing bytes that end up in it.

// The `Default` impl is for tests.
#[derive(Default)]
pub struct EncodedMetadata {
// The declaration order matters because `full_metadata` should be dropped
// before `_temp_dir`.
Expand Down
4 changes: 3 additions & 1 deletion tests/ui-fulldeps/run-compiler-twice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

extern crate rustc_driver;
extern crate rustc_interface;
extern crate rustc_metadata;
extern crate rustc_session;
extern crate rustc_span;

Expand Down Expand Up @@ -81,7 +82,8 @@ fn compile(code: String, output: PathBuf, sysroot: Sysroot, linker: Option<&Path
let krate = rustc_interface::passes::parse(&compiler.sess);
let linker = rustc_interface::create_and_enter_global_ctxt(&compiler, krate, |tcx| {
let _ = tcx.analysis(());
Linker::codegen_and_build_linker(tcx, &*compiler.codegen_backend)
let metadata = Default::default();
Linker::codegen_and_build_linker(tcx, &*compiler.codegen_backend, metadata)
});
linker.link(&compiler.sess, &*compiler.codegen_backend);
});
Expand Down
Loading