diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs index 8e27c335b1174..c0466a4b5211c 100644 --- a/compiler/rustc_incremental/src/persist/load.rs +++ b/compiler/rustc_incremental/src/persist/load.rs @@ -38,19 +38,8 @@ pub enum LoadResult { impl LoadResult { /// Accesses the data returned in [`LoadResult::Ok`]. pub fn open(self, sess: &Session) -> T { - // Check for errors when using `-Zassert-incremental-state` - match (sess.opts.assert_incr_state, &self) { - (Some(IncrementalStateAssertion::NotLoaded), LoadResult::Ok { .. }) => { - sess.dcx().emit_fatal(errors::AssertNotLoaded); - } - ( - Some(IncrementalStateAssertion::Loaded), - LoadResult::LoadDepGraph(..) | LoadResult::DataOutOfDate, - ) => { - sess.dcx().emit_fatal(errors::AssertLoaded); - } - _ => {} - }; + // Emit a fatal error if `-Zassert-incr-state` is present and unsatisfied. + maybe_assert_incr_state(sess, &self); match self { LoadResult::LoadDepGraph(path, err) => { @@ -188,6 +177,32 @@ pub fn load_query_result_cache(sess: &Session) -> Option { } } +/// Emits a fatal error if the assertion in `-Zassert-incr-state` doesn't match +/// the outcome of trying to load previous-session state. +fn maybe_assert_incr_state(sess: &Session, load_result: &LoadResult) { + // Return immediately if there's nothing to assert. + let Some(assertion) = sess.opts.unstable_opts.assert_incr_state else { return }; + + // Match exhaustively to make sure we don't miss any cases. + let loaded = match load_result { + LoadResult::Ok { .. } => true, + LoadResult::DataOutOfDate | LoadResult::LoadDepGraph(..) => false, + }; + + match assertion { + IncrementalStateAssertion::Loaded => { + if !loaded { + sess.dcx().emit_fatal(errors::AssertLoaded); + } + } + IncrementalStateAssertion::NotLoaded => { + if loaded { + sess.dcx().emit_fatal(errors::AssertNotLoaded) + } + } + } +} + /// Setups the dependency graph by loading an existing graph from disk and set up streaming of a /// new graph to an incremental session directory. pub fn setup_dep_graph( diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index f9d583bdf18c7..417cde119c21f 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -12,12 +12,12 @@ use rustc_hir::attrs::{CollapseMacroDebuginfo, NativeLibKind}; use rustc_session::config::{ AnnotateMoves, AutoDiff, BranchProtection, CFGuard, Cfg, CoverageLevel, CoverageOptions, DebugInfo, DumpMonoStatsFormat, ErrorOutputType, ExternEntry, ExternLocation, Externs, - FmtDebug, FunctionReturn, InliningThreshold, Input, InstrumentCoverage, InstrumentXRay, - LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, MirIncludeSpans, NextSolverConfig, - Offload, Options, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet, Passes, - PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, - SymbolManglingVersion, WasiExecModel, build_configuration, build_session_options, - rustc_optgroups, + FmtDebug, FunctionReturn, IncrementalStateAssertion, InliningThreshold, Input, + InstrumentCoverage, InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, + MirIncludeSpans, NextSolverConfig, Offload, Options, OutFileName, OutputType, OutputTypes, + PAuthKey, PacRet, Passes, PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip, + SwitchWithOptPath, SymbolManglingVersion, WasiExecModel, build_configuration, + build_session_options, rustc_optgroups, }; use rustc_session::lint::Level; use rustc_session::search_paths::SearchPath; @@ -686,7 +686,7 @@ fn test_unstable_options_tracking_hash() { // Make sure that changing an [UNTRACKED] option leaves the hash unchanged. // tidy-alphabetical-start - untracked!(assert_incr_state, Some(String::from("loaded"))); + untracked!(assert_incr_state, Some(IncrementalStateAssertion::Loaded)); untracked!(codegen_source_order, true); untracked!(deduplicate_diagnostics, false); untracked!(dump_dep_graph, true); diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 0677ca0fddbaa..42d5a50df699f 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1405,7 +1405,6 @@ impl Default for Options { }; Options { - assert_incr_state: None, crate_types: Vec::new(), optimize: OptLevel::No, debuginfo: DebugInfo::None, @@ -2287,20 +2286,6 @@ fn select_debuginfo(matches: &getopts::Matches, cg: &CodegenOptions) -> DebugInf if max_g > max_c { DebugInfo::Full } else { cg.debuginfo } } -fn parse_assert_incr_state( - early_dcx: &EarlyDiagCtxt, - opt_assertion: &Option, -) -> Option { - match opt_assertion { - Some(s) if s.as_str() == "loaded" => Some(IncrementalStateAssertion::Loaded), - Some(s) if s.as_str() == "not-loaded" => Some(IncrementalStateAssertion::NotLoaded), - Some(s) => { - early_dcx.early_fatal(format!("unexpected incremental state assertion value: {s}")) - } - None => None, - } -} - pub fn parse_externs( early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches, @@ -2506,8 +2491,6 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M let incremental = cg.incremental.as_ref().map(PathBuf::from); - let assert_incr_state = parse_assert_incr_state(early_dcx, &unstable_opts.assert_incr_state); - if cg.profile_generate.enabled() && cg.profile_use.is_some() { early_dcx.early_fatal("options `-C profile-generate` and `-C profile-use` are exclusive"); } @@ -2759,7 +2742,6 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M let verbose = matches.opt_present("verbose") || unstable_opts.verbose_internals; Options { - assert_incr_state, crate_types, optimize: opt_level, debuginfo, diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 7abaae1c17606..8771dbd05c494 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -419,7 +419,6 @@ top_level_options!( /// If `Some`, enable incremental compilation, using the given /// directory to store intermediate results. incremental: Option [UNTRACKED], - assert_incr_state: Option [UNTRACKED], /// Set based on the result of the `Config::track_state` callback /// for custom drivers to invalidate the incremental cache. #[rustc_lint_opt_deny_field_access("should only be used via `Config::track_state`")] @@ -889,6 +888,7 @@ mod desc { pub(crate) const parse_mir_include_spans: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), or `nll` (default: `nll`)"; pub(crate) const parse_align: &str = "a number that is a power of 2 between 1 and 2^29"; + pub(crate) const parse_assert_incr_state: &str = "one of: `loaded`, `not-loaded`"; } pub mod parse { @@ -2061,6 +2061,18 @@ pub mod parse { true } + + pub(crate) fn parse_assert_incr_state( + slot: &mut Option, + v: Option<&str>, + ) -> bool { + *slot = match v { + Some("loaded") => Some(IncrementalStateAssertion::Loaded), + Some("not-loaded") => Some(IncrementalStateAssertion::NotLoaded), + _ => return false, + }; + true + } } options! { @@ -2230,7 +2242,7 @@ options! { annotate_moves: AnnotateMoves = (AnnotateMoves::Disabled, parse_annotate_moves, [TRACKED], "emit debug info for compiler-generated move and copy operations \ to make them visible in profilers. Can be a boolean or a size limit in bytes (default: disabled)"), - assert_incr_state: Option = (None, parse_opt_string, [UNTRACKED], + assert_incr_state: Option = (None, parse_assert_incr_state, [UNTRACKED], "assert that the incremental cache is in given state: \ either `loaded` or `not-loaded`."), assume_incomplete_release: bool = (false, parse_bool, [TRACKED],