Skip to content

Commit ecbba47

Browse files
committed
Move metadata generation.
It's currently done within `start_codegen`, which is called from `codegen_and_build_linker`, and it gets included in the codegen timing section. All this is surprising, because it's not part of codegen. This commit moves it into `run_compiler`, just before the call to `codegen_and_build_linker`. This is a more sensible place for it. The commit also adds some extra non-obvious information about the `has_errors_or_delayed_bugs` check, which I learned when I tried moving metadata generation earlier. Likewise, the nearby `rustc_delayed_bug_from_inside_query` code is also moved, because (a) it's not part of codegen, and (b) it needs to be nearby.
1 parent 3776358 commit ecbba47

File tree

5 files changed

+35
-23
lines changed

5 files changed

+35
-23
lines changed

compiler/rustc_driver_impl/src/lib.rs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ use rustc_session::getopts::{self, Matches};
6060
use rustc_session::lint::{Lint, LintId};
6161
use rustc_session::output::{CRATE_TYPES, collect_crate_types, invalid_output_for_target};
6262
use rustc_session::{EarlyDiagCtxt, Session, config};
63-
use rustc_span::FileName;
6463
use rustc_span::def_id::LOCAL_CRATE;
64+
use rustc_span::{FileName, sym};
6565
use rustc_target::json::ToJson;
6666
use rustc_target::spec::{Target, TargetTuple};
6767
use tracing::trace;
@@ -383,7 +383,31 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send))
383383
}
384384
}
385385

386-
Some(Linker::codegen_and_build_linker(tcx, &*compiler.codegen_backend))
386+
// Hook for tests. This must be shortly before the
387+
// `has_errors_or_delayed_bugs` check below for
388+
// `tests/ui/treat-err-as-bug/span_delayed_bug.rs` to work.
389+
if let Some((def_id, _)) = tcx.entry_fn(())
390+
&& tcx.has_attr(def_id, sym::rustc_delayed_bug_from_inside_query)
391+
{
392+
tcx.ensure_ok().trigger_delayed_bug(def_id);
393+
}
394+
395+
// Don't emit metadata or do codegen if there were any errors.
396+
//
397+
// Note: checking for delayed bugs here is aggressive. If we have
398+
// no errors but one or more delayed bugs, the `raise_fatal` call
399+
// will instantly ICE when the DiagCtxt is dropped. I.e. this check
400+
// serves as a kind of barrier, giving no opportunity for a
401+
// subsequent error (e.g. during codegen) to nullify a delayed bug.
402+
// The rationale is that delayed bugs are likely to cause more ICEs
403+
// during codegen, obscuring the original problem.
404+
if let Some(guar) = tcx.sess.dcx().has_errors_or_delayed_bugs() {
405+
guar.raise_fatal();
406+
}
407+
408+
let metadata = rustc_metadata::fs::encode_and_write_metadata(tcx);
409+
410+
Some(Linker::codegen_and_build_linker(tcx, &*compiler.codegen_backend, metadata))
387411
});
388412

389413
// Linking is done outside the `compiler.enter()` so that the

compiler/rustc_interface/src/passes.rs

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ use rustc_hir::def_id::{LOCAL_CRATE, StableCrateId, StableCrateIdMap};
2121
use rustc_hir::definitions::Definitions;
2222
use rustc_incremental::setup_dep_graph;
2323
use rustc_lint::{BufferedEarlyLint, EarlyCheckNode, LintStore, unerased_lint_store};
24-
use rustc_metadata::EncodedMetadata;
2524
use rustc_metadata::creader::CStore;
2625
use rustc_middle::arena::Arena;
2726
use rustc_middle::dep_graph::DepsType;
@@ -1196,33 +1195,17 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) {
11961195
pub(crate) fn start_codegen<'tcx>(
11971196
codegen_backend: &dyn CodegenBackend,
11981197
tcx: TyCtxt<'tcx>,
1199-
) -> (Box<dyn Any>, EncodedMetadata) {
1198+
) -> Box<dyn Any> {
12001199
tcx.sess.timings.start_section(tcx.sess.dcx(), TimingSection::Codegen);
12011200

1202-
// Hook for tests.
1203-
if let Some((def_id, _)) = tcx.entry_fn(())
1204-
&& tcx.has_attr(def_id, sym::rustc_delayed_bug_from_inside_query)
1205-
{
1206-
tcx.ensure_ok().trigger_delayed_bug(def_id);
1207-
}
1208-
12091201
// Don't run this test assertions when not doing codegen. Compiletest tries to build
12101202
// build-fail tests in check mode first and expects it to not give an error in that case.
12111203
if tcx.sess.opts.output_types.should_codegen() {
12121204
rustc_symbol_mangling::test::report_symbol_names(tcx);
12131205
}
12141206

1215-
// Don't do code generation if there were any errors. Likewise if
1216-
// there were any delayed bugs, because codegen will likely cause
1217-
// more ICEs, obscuring the original problem.
1218-
if let Some(guar) = tcx.sess.dcx().has_errors_or_delayed_bugs() {
1219-
guar.raise_fatal();
1220-
}
1221-
12221207
info!("Pre-codegen\n{:?}", tcx.debug_stats());
12231208

1224-
let metadata = rustc_metadata::fs::encode_and_write_metadata(tcx);
1225-
12261209
let codegen = tcx.sess.time("codegen_crate", move || codegen_backend.codegen_crate(tcx));
12271210

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

1236-
(codegen, metadata)
1219+
codegen
12371220
}
12381221

12391222
/// Compute and validate the crate name.

compiler/rustc_interface/src/queries.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ impl Linker {
2828
pub fn codegen_and_build_linker(
2929
tcx: TyCtxt<'_>,
3030
codegen_backend: &dyn CodegenBackend,
31+
metadata: EncodedMetadata,
3132
) -> Linker {
32-
let (ongoing_codegen, metadata) = passes::start_codegen(codegen_backend, tcx);
33+
let ongoing_codegen = passes::start_codegen(codegen_backend, tcx);
3334

3435
Linker {
3536
dep_graph: tcx.dep_graph.clone(),

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2274,6 +2274,8 @@ fn prefetch_mir(tcx: TyCtxt<'_>) {
22742274
// will allow us to slice the metadata to the precise length that we just
22752275
// generated regardless of trailing bytes that end up in it.
22762276

2277+
// The `Default` impl is for tests.
2278+
#[derive(Default)]
22772279
pub struct EncodedMetadata {
22782280
// The declaration order matters because `full_metadata` should be dropped
22792281
// before `_temp_dir`.

tests/ui-fulldeps/run-compiler-twice.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
extern crate rustc_driver;
1414
extern crate rustc_interface;
15+
extern crate rustc_metadata;
1516
extern crate rustc_session;
1617
extern crate rustc_span;
1718

@@ -81,7 +82,8 @@ fn compile(code: String, output: PathBuf, sysroot: Sysroot, linker: Option<&Path
8182
let krate = rustc_interface::passes::parse(&compiler.sess);
8283
let linker = rustc_interface::create_and_enter_global_ctxt(&compiler, krate, |tcx| {
8384
let _ = tcx.analysis(());
84-
Linker::codegen_and_build_linker(tcx, &*compiler.codegen_backend)
85+
let metadata = Default::default();
86+
Linker::codegen_and_build_linker(tcx, &*compiler.codegen_backend, metadata)
8587
});
8688
linker.link(&compiler.sess, &*compiler.codegen_backend);
8789
});

0 commit comments

Comments
 (0)