From 3f919c09216074541aaa3e4d6cfd31fc1c381e3e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 4 Feb 2026 13:00:50 +0000 Subject: [PATCH 1/4] Pass Session to make_codegen_backend callback --- compiler/rustc_interface/src/interface.rs | 31 ++++++++++------------- src/tools/miri/src/bin/miri.rs | 22 ++++++++-------- 2 files changed, 25 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 91b7f234d5f64..ed08e4916436b 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -22,7 +22,6 @@ use rustc_session::parse::ParseSess; use rustc_session::{CompilerIO, EarlyDiagCtxt, Session, lint}; use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMapInputs}; use rustc_span::{FileName, sym}; -use rustc_target::spec::Target; use tracing::trace; use crate::util; @@ -364,8 +363,7 @@ pub struct Config { /// hotswapping branch of cg_clif" for "setting the codegen backend from a /// custom driver where the custom codegen backend has arbitrary data." /// (See #102759.) - pub make_codegen_backend: - Option Box + Send>>, + pub make_codegen_backend: Option Box + Send>>, /// The inner atomic value is set to true when a feature marked as `internal` is /// enabled. Makes it so that "please report a bug" is hidden, as ICEs with @@ -419,20 +417,6 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se // impl `Send`. Creating a new one is fine. let early_dcx = EarlyDiagCtxt::new(config.opts.error_format); - let codegen_backend = match config.make_codegen_backend { - None => util::get_codegen_backend( - &early_dcx, - &config.opts.sysroot, - config.opts.unstable_opts.codegen_backend.as_deref(), - &target, - ), - Some(make_codegen_backend) => { - // N.B. `make_codegen_backend` takes precedence over - // `target.default_codegen_backend`, which is ignored in this case. - make_codegen_backend(&config.opts, &target) - } - }; - let temps_dir = config.opts.unstable_opts.temps_dir.as_deref().map(PathBuf::from); let mut sess = rustc_session::build_session( @@ -450,6 +434,19 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se config.using_internal_features, ); + let codegen_backend = match config.make_codegen_backend { + None => util::get_codegen_backend( + &early_dcx, + &sess.opts.sysroot, + sess.opts.unstable_opts.codegen_backend.as_deref(), + &sess.target, + ), + Some(make_codegen_backend) => { + // N.B. `make_codegen_backend` takes precedence over + // `target.default_codegen_backend`, which is ignored in this case. + make_codegen_backend(&sess) + } + }; codegen_backend.init(&sess); sess.replaced_intrinsics = FxHashSet::from_iter(codegen_backend.replaced_intrinsics()); sess.thin_lto_supported = codegen_backend.thin_lto_supported(); diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 3766debb159d0..d20ae911d0194 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -18,7 +18,6 @@ extern crate rustc_log; extern crate rustc_middle; extern crate rustc_session; extern crate rustc_span; -extern crate rustc_target; /// See docs in https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc/src/main.rs /// and https://github.com/rust-lang/rust/pull/146627 for why we need this. @@ -42,7 +41,6 @@ use std::ops::Range; use std::process::ExitCode; use std::rc::Rc; use std::str::FromStr; -use std::sync::Once; use std::sync::atomic::{AtomicU32, Ordering}; use miri::{ @@ -66,10 +64,9 @@ use rustc_middle::middle::exported_symbols::{ use rustc_middle::query::LocalCrate; use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_session::EarlyDiagCtxt; -use rustc_session::config::{CrateType, ErrorOutputType, OptLevel, Options}; +use rustc_session::config::{CrateType, ErrorOutputType, OptLevel}; +use rustc_session::{EarlyDiagCtxt, Session}; use rustc_span::def_id::DefId; -use rustc_target::spec::Target; use crate::log::setup::{deinit_loggers, init_early_loggers, init_late_loggers}; @@ -174,18 +171,21 @@ fn run_many_seeds( /// Generates the codegen backend for code that Miri will interpret: we basically /// use the dummy backend, except that we put the LLVM backend in charge of /// target features. -fn make_miri_codegen_backend(opts: &Options, target: &Target) -> Box { - let early_dcx = EarlyDiagCtxt::new(opts.error_format); +fn make_miri_codegen_backend(sess: &Session) -> Box { + let early_dcx = EarlyDiagCtxt::new(sess.opts.error_format); // Use the target_config method of the default codegen backend (eg LLVM) to ensure the // calculated target features match said backend by respecting eg -Ctarget-cpu. - let target_config_backend = - rustc_interface::util::get_codegen_backend(&early_dcx, &opts.sysroot, None, target); - let target_config_backend_init = Once::new(); + let target_config_backend = rustc_interface::util::get_codegen_backend( + &early_dcx, + &sess.opts.sysroot, + None, + &sess.target, + ); + target_config_backend.init(sess); Box::new(DummyCodegenBackend { target_config_override: Some(Box::new(move |sess| { - target_config_backend_init.call_once(|| target_config_backend.init(sess)); target_config_backend.target_config(sess) })), }) From 2199d07e2bff538c4636a01a07ac0b31850af648 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 2 Feb 2025 15:51:14 +0000 Subject: [PATCH 2/4] Move env/file_depinfo from ParseSess to Session --- compiler/rustc_builtin_macros/src/env.rs | 4 +-- .../rustc_builtin_macros/src/source_util.rs | 1 - compiler/rustc_driver_impl/src/lib.rs | 2 +- .../rustc_expand/src/proc_macro_server.rs | 5 ++-- compiler/rustc_interface/src/interface.rs | 15 ++++++----- compiler/rustc_interface/src/passes.rs | 6 ++--- compiler/rustc_session/src/options.rs | 6 ++--- compiler/rustc_session/src/parse.rs | 8 +----- compiler/rustc_session/src/session.rs | 8 ++++++ src/librustdoc/core.rs | 2 +- src/librustdoc/doctest.rs | 2 +- src/tools/clippy/src/driver.rs | 26 +++++++++---------- tests/ui-fulldeps/run-compiler-twice.rs | 2 +- 13 files changed, 45 insertions(+), 42 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs index 12f59467ffd16..f60113dbfc9bc 100644 --- a/compiler/rustc_builtin_macros/src/env.rs +++ b/compiler/rustc_builtin_macros/src/env.rs @@ -51,7 +51,7 @@ pub(crate) fn expand_option_env<'cx>( let sp = cx.with_def_site_ctxt(sp); let value = lookup_env(cx, var); - cx.sess.psess.env_depinfo.borrow_mut().insert((var, value.as_ref().ok().copied())); + cx.sess.env_depinfo.borrow_mut().insert((var, value.as_ref().ok().copied())); let e = match value { Err(VarError::NotPresent) => { let lt = cx.lifetime(sp, Ident::new(kw::StaticLifetime, sp)); @@ -130,7 +130,7 @@ pub(crate) fn expand_env<'cx>( let span = cx.with_def_site_ctxt(sp); let value = lookup_env(cx, var); - cx.sess.psess.env_depinfo.borrow_mut().insert((var, value.as_ref().ok().copied())); + cx.sess.env_depinfo.borrow_mut().insert((var, value.as_ref().ok().copied())); let e = match value { Err(err) => { let ExprKind::Lit(token::Lit { diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs index 16003c8ba135a..ab7a9c3bccb38 100644 --- a/compiler/rustc_builtin_macros/src/source_util.rs +++ b/compiler/rustc_builtin_macros/src/source_util.rs @@ -277,7 +277,6 @@ fn load_binary_file( match cx.source_map().load_binary_file(&resolved_path) { Ok(data) => { cx.sess - .psess .file_depinfo .borrow_mut() .insert(Symbol::intern(&resolved_path.to_string_lossy())); diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 8fec629161eac..ea69d9d078151 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -214,7 +214,7 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send)) file_loader: None, lint_caps: Default::default(), psess_created: None, - hash_untracked_state: None, + track_state: None, register_lints: None, override_queries: None, extra_symbols: Vec::new(), diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 839e68d0bb433..037afbb9f550b 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -475,14 +475,15 @@ impl server::Server for Rustc<'_, '_> { } fn track_env_var(&mut self, var: &str, value: Option<&str>) { - self.psess() + self.ecx + .sess .env_depinfo .borrow_mut() .insert((Symbol::intern(var), value.map(Symbol::intern))); } fn track_path(&mut self, path: &str) { - self.psess().file_depinfo.borrow_mut().insert(Symbol::intern(path)); + self.ecx.sess.file_depinfo.borrow_mut().insert(Symbol::intern(path)); } fn literal_from_str(&mut self, s: &str) -> Result, String> { diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index ed08e4916436b..fa4d4588caab4 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -336,11 +336,14 @@ pub struct Config { /// This is a callback from the driver that is called when [`ParseSess`] is created. pub psess_created: Option>, - /// This is a callback to hash otherwise untracked state used by the caller, if the - /// hash changes between runs the incremental cache will be cleared. + /// This is a callback to track otherwise untracked state used by the caller. /// - /// e.g. used by Clippy to hash its config file - pub hash_untracked_state: Option>, + /// You can write to `sess.env_depinfo` and `sess.file_depinfo` to track env vars and files. + /// To track any other state you can write to the given hasher. If the hash changes between + /// runs the incremental cache will be cleared. + /// + /// The hashing functionality has no known user. FIXME should this be removed? + pub track_state: Option>, /// This is a callback from the driver that is called when we're registering lints; /// it is called during lint loading when we have the LintStore in a non-shared state. @@ -464,9 +467,9 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se psess_created(&mut sess.psess); } - if let Some(hash_untracked_state) = config.hash_untracked_state { + if let Some(track_state) = config.track_state { let mut hasher = StableHasher::new(); - hash_untracked_state(&sess, &mut hasher); + track_state(&sess, &mut hasher); sess.opts.untracked_state_hash = hasher.finish() } diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index a280b2a2a6bf7..db88baa0ca193 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -495,7 +495,7 @@ fn env_var_os<'tcx>(tcx: TyCtxt<'tcx>, key: &'tcx OsStr) -> Option<&'tcx OsStr> // NOTE: This only works for passes run before `write_dep_info`. See that // for extension points for configuring environment variables to be // properly change-tracked. - tcx.sess.psess.env_depinfo.borrow_mut().insert(( + tcx.sess.env_depinfo.borrow_mut().insert(( Symbol::intern(&key.to_string_lossy()), value.as_ref().and_then(|value| value.to_str()).map(|value| Symbol::intern(value)), )); @@ -607,7 +607,7 @@ fn write_out_deps(tcx: TyCtxt<'_>, outputs: &OutputFilenames, out_filenames: &[P // Account for explicitly marked-to-track files // (e.g. accessed in proc macros). - let file_depinfo = sess.psess.file_depinfo.borrow(); + let file_depinfo = sess.file_depinfo.borrow(); let normalize_path = |path: PathBuf| escape_dep_filename(&path.to_string_lossy()); @@ -719,7 +719,7 @@ fn write_out_deps(tcx: TyCtxt<'_>, outputs: &OutputFilenames, out_filenames: &[P } // Emit special comments with information about accessed environment variables. - let env_depinfo = sess.psess.env_depinfo.borrow(); + let env_depinfo = sess.env_depinfo.borrow(); if !env_depinfo.is_empty() { // We will soon sort, so the initial order does not matter. #[allow(rustc::potential_query_instability)] diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 74b3aa11d0d80..c625e86ccd9bb 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -419,9 +419,9 @@ top_level_options!( /// directory to store intermediate results. incremental: Option [UNTRACKED], assert_incr_state: Option [UNTRACKED], - /// Set by the `Config::hash_untracked_state` callback for custom - /// drivers to invalidate the incremental cache - #[rustc_lint_opt_deny_field_access("should only be used via `Config::hash_untracked_state`")] + /// 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`")] untracked_state_hash: Hash64 [TRACKED_NO_CRATE_HASH], unstable_opts: UnstableOptions [SUBSTRUCT UnstableOptionsTargetModifiers UnstableOptions], diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 9c12c480cacdd..bb60da36bbb7d 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -6,7 +6,7 @@ use std::sync::Arc; use rustc_ast::attr::AttrIdGenerator; use rustc_ast::node_id::NodeId; -use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet}; +use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_data_structures::sync::{AppendOnlyVec, Lock}; use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitter; use rustc_errors::emitter::{EmitterWithNote, stderr_destination}; @@ -264,10 +264,6 @@ pub struct ParseSess { pub ambiguous_block_expr_parse: Lock>, pub gated_spans: GatedSpans, pub symbol_gallery: SymbolGallery, - /// Environment variables accessed during the build and their values when they exist. - pub env_depinfo: Lock)>>, - /// File paths accessed during the build. - pub file_depinfo: Lock>, /// Whether cfg(version) should treat the current release as incomplete pub assume_incomplete_release: bool, /// Spans passed to `proc_macro::quote_span`. Each span has a numerical @@ -303,8 +299,6 @@ impl ParseSess { ambiguous_block_expr_parse: Lock::new(Default::default()), gated_spans: GatedSpans::default(), symbol_gallery: SymbolGallery::default(), - env_depinfo: Default::default(), - file_depinfo: Default::default(), assume_incomplete_release: false, proc_macro_quoted_spans: Default::default(), attr_id_generator: AttrIdGenerator::new(), diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 0548380331bef..8290bdf91a030 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -143,6 +143,12 @@ pub struct Session { /// None signifies that this is not tracked. pub using_internal_features: &'static AtomicBool, + /// Environment variables accessed during the build and their values when they exist. + pub env_depinfo: Lock)>>, + + /// File paths accessed during the build. + pub file_depinfo: Lock>, + target_filesearch: FileSearch, host_filesearch: FileSearch, @@ -1095,6 +1101,8 @@ pub fn build_session( unstable_target_features: Default::default(), cfg_version, using_internal_features, + env_depinfo: Default::default(), + file_depinfo: Default::default(), target_filesearch, host_filesearch, invocation_temp, diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 89b4df1a51ce5..a875d6d002219 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -296,7 +296,7 @@ pub(crate) fn create_config( file_loader: None, lint_caps, psess_created: None, - hash_untracked_state: None, + track_state: None, register_lints: Some(Box::new(crate::lint::register_lints)), override_queries: Some(|_sess, providers| { // We do not register late module lints, so this only runs `MissingDoc`. diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index a61f85bd40074..bfcdc3a505585 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -190,7 +190,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions file_loader: None, lint_caps, psess_created: None, - hash_untracked_state: None, + track_state: None, register_lints: Some(Box::new(crate::lint::register_lints)), override_queries: None, extra_symbols: Vec::new(), diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs index f27cb67087096..7b7aac09643af 100644 --- a/src/tools/clippy/src/driver.rs +++ b/src/tools/clippy/src/driver.rs @@ -23,9 +23,8 @@ extern crate tikv_jemalloc_sys as _; use clippy_utils::sym; use declare_clippy_lint::LintListBuilder; use rustc_interface::interface; -use rustc_session::EarlyDiagCtxt; use rustc_session::config::ErrorOutputType; -use rustc_session::parse::ParseSess; +use rustc_session::{EarlyDiagCtxt, Session}; use rustc_span::symbol::Symbol; use std::env; @@ -81,17 +80,16 @@ fn test_has_arg() { assert!(!has_arg(args, "--bar")); } -fn track_clippy_args(psess: &mut ParseSess, args_env_var: Option<&str>) { - psess - .env_depinfo - .get_mut() +fn track_clippy_args(sess: &Session, args_env_var: Option<&str>) { + sess.env_depinfo + .borrow_mut() .insert((sym::CLIPPY_ARGS, args_env_var.map(Symbol::intern))); } /// Track files that may be accessed at runtime in `file_depinfo` so that cargo will re-run clippy /// when any of them are modified -fn track_files(psess: &mut ParseSess) { - let file_depinfo = psess.file_depinfo.get_mut(); +fn track_files(sess: &Session) { + let mut file_depinfo = sess.file_depinfo.borrow_mut(); // Used by `clippy::cargo` lints and to determine the MSRV. `cargo clippy` executes `clippy-driver` // with the current directory set to `CARGO_MANIFEST_DIR` so a relative path is fine @@ -123,8 +121,8 @@ struct RustcCallbacks { impl rustc_driver::Callbacks for RustcCallbacks { fn config(&mut self, config: &mut interface::Config) { let clippy_args_var = self.clippy_args_var.take(); - config.psess_created = Some(Box::new(move |psess| { - track_clippy_args(psess, clippy_args_var.as_deref()); + config.track_state = Some(Box::new(move |sess, _hasher| { + track_clippy_args(sess, clippy_args_var.as_deref()); })); config.extra_symbols = sym::EXTRA_SYMBOLS.into(); } @@ -140,13 +138,13 @@ impl rustc_driver::Callbacks for ClippyCallbacks { let conf_path = clippy_config::lookup_conf_file(); let previous = config.register_lints.take(); let clippy_args_var = self.clippy_args_var.take(); - config.psess_created = Some(Box::new(move |psess| { - track_clippy_args(psess, clippy_args_var.as_deref()); - track_files(psess); + config.track_state = Some(Box::new(move |sess, _hasher| { + track_clippy_args(sess, clippy_args_var.as_deref()); + track_files(sess); // Trigger a rebuild if CLIPPY_CONF_DIR changes. The value must be a valid string so // changes between dirs that are invalid UTF-8 will not trigger rebuilds - psess.env_depinfo.get_mut().insert(( + sess.env_depinfo.borrow_mut().insert(( sym::CLIPPY_CONF_DIR, env::var("CLIPPY_CONF_DIR").ok().map(|dir| Symbol::intern(&dir)), )); diff --git a/tests/ui-fulldeps/run-compiler-twice.rs b/tests/ui-fulldeps/run-compiler-twice.rs index bd92cc6218f19..d99d9c42d547f 100644 --- a/tests/ui-fulldeps/run-compiler-twice.rs +++ b/tests/ui-fulldeps/run-compiler-twice.rs @@ -66,7 +66,7 @@ fn compile(code: String, output: PathBuf, sysroot: Sysroot, linker: Option<&Path file_loader: None, lint_caps: Default::default(), psess_created: None, - hash_untracked_state: None, + track_state: None, register_lints: None, override_queries: None, extra_symbols: Vec::new(), From fbd3b6d9443a4da80db1c18277e4ce61d1da662b Mon Sep 17 00:00:00 2001 From: Zalathar Date: Tue, 17 Mar 2026 13:39:29 +1100 Subject: [PATCH 3/4] Move query-stack-frame spans into `QueryStackFrame` Code that previously used `QueryStackFrame` now uses `TaggedQueryKey` directly. Code that previously used `Spanned` now uses `QueryStackFrame`, which includes a span. --- compiler/rustc_middle/src/query/plumbing.rs | 11 ++-- compiler/rustc_middle/src/query/stack.rs | 6 ++- compiler/rustc_query_impl/src/execution.rs | 6 +-- .../rustc_query_impl/src/from_cycle_error.rs | 10 ++-- compiler/rustc_query_impl/src/job.rs | 54 ++++++++++--------- 5 files changed, 46 insertions(+), 41 deletions(-) diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 17fa9bf085ebc..e8e2c8dbd2249 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -8,15 +8,14 @@ use rustc_data_structures::sync::{AtomicU64, WorkerLocal}; use rustc_errors::Diag; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::hir_id::OwnerId; -use rustc_span::{Span, Spanned}; +use rustc_span::Span; pub use sealed::IntoQueryParam; use crate::dep_graph::{DepKind, DepNodeIndex, SerializedDepNodeIndex}; use crate::ich::StableHashingContext; use crate::queries::{ExternProviders, Providers, QueryArenas, QueryVTables, TaggedQueryKey}; use crate::query::on_disk_cache::OnDiskCache; -use crate::query::stack::QueryStackFrame; -use crate::query::{QueryCache, QueryJob}; +use crate::query::{QueryCache, QueryJob, QueryStackFrame}; use crate::ty::TyCtxt; /// For a particular query, keeps track of "active" keys, i.e. keys whose @@ -53,10 +52,10 @@ pub enum ActiveKeyStatus<'tcx> { #[derive(Debug)] pub struct CycleError<'tcx> { /// The query and related span that uses the cycle. - pub usage: Option>>, + pub usage: Option>, /// The span here corresponds to the reason for which this query was required. - pub cycle: Vec>>, + pub cycle: Vec>, } #[derive(Debug)] @@ -505,7 +504,7 @@ macro_rules! define_callbacks { /// Identifies a query by kind and key. This is in contrast to `QueryJobId` which is just a number. #[allow(non_camel_case_types)] - #[derive(Clone, Debug)] + #[derive(Clone, Copy, Debug)] pub enum TaggedQueryKey<'tcx> { $( $name($name::Key<'tcx>), diff --git a/compiler/rustc_middle/src/query/stack.rs b/compiler/rustc_middle/src/query/stack.rs index 6a77ddc1eaa7f..9465fc87edf09 100644 --- a/compiler/rustc_middle/src/query/stack.rs +++ b/compiler/rustc_middle/src/query/stack.rs @@ -1,10 +1,14 @@ +use rustc_span::Span; + use crate::queries::TaggedQueryKey; /// Description of a frame in the query stack. /// /// This is mostly used in case of cycles for error reporting. -#[derive(Clone, Debug)] +#[derive(Debug)] pub struct QueryStackFrame<'tcx> { + pub span: Span, + /// The query and key of the query method call that this stack frame /// corresponds to. /// diff --git a/compiler/rustc_query_impl/src/execution.rs b/compiler/rustc_query_impl/src/execution.rs index 6c91db16967b1..aea0bb4d35342 100644 --- a/compiler/rustc_query_impl/src/execution.rs +++ b/compiler/rustc_query_impl/src/execution.rs @@ -9,7 +9,7 @@ use rustc_errors::FatalError; use rustc_middle::dep_graph::{DepGraphData, DepNodeKey, SerializedDepNodeIndex}; use rustc_middle::query::{ ActiveKeyStatus, CycleError, EnsureMode, QueryCache, QueryJob, QueryJobId, QueryKey, - QueryLatch, QueryMode, QueryStackFrame, QueryState, QueryVTable, + QueryLatch, QueryMode, QueryState, QueryVTable, }; use rustc_middle::ty::TyCtxt; use rustc_middle::verify_ich::incremental_verify_ich; @@ -75,8 +75,8 @@ fn collect_active_query_jobs_inner<'tcx, C>( if let ActiveKeyStatus::Started(job) = status { // It's fine to call `create_tagged_key` with the shard locked, // because it's just a `TaggedQueryKey` variant constructor. - let frame = QueryStackFrame { tagged_key: (query.create_tagged_key)(*key) }; - job_map.insert(job.id, QueryJobInfo { frame, job: job.clone() }); + let tagged_key = (query.create_tagged_key)(*key); + job_map.insert(job.id, QueryJobInfo { tagged_key, job: job.clone() }); } } }; diff --git a/compiler/rustc_query_impl/src/from_cycle_error.rs b/compiler/rustc_query_impl/src/from_cycle_error.rs index 317b2482c05cc..0c6082e65f624 100644 --- a/compiler/rustc_query_impl/src/from_cycle_error.rs +++ b/compiler/rustc_query_impl/src/from_cycle_error.rs @@ -76,7 +76,7 @@ fn check_representability<'tcx>(tcx: TyCtxt<'tcx>, cycle_error: CycleError<'tcx> let mut item_and_field_ids = Vec::new(); let mut representable_ids = FxHashSet::default(); for frame in &cycle_error.cycle { - if let TaggedQueryKey::check_representability(def_id) = frame.node.tagged_key + if let TaggedQueryKey::check_representability(def_id) = frame.tagged_key && tcx.def_kind(def_id) == DefKind::Field { let field_id: LocalDefId = def_id; @@ -89,7 +89,7 @@ fn check_representability<'tcx>(tcx: TyCtxt<'tcx>, cycle_error: CycleError<'tcx> } } for frame in &cycle_error.cycle { - if let TaggedQueryKey::check_representability_adt_ty(key) = frame.node.tagged_key + if let TaggedQueryKey::check_representability_adt_ty(key) = frame.tagged_key && let Some(adt) = key.ty_adt_def() && let Some(def_id) = adt.did().as_local() && !item_and_field_ids.iter().any(|&(id, _)| id == def_id) @@ -134,7 +134,7 @@ fn layout_of<'tcx>( let diag = search_for_cycle_permutation( &cycle_error.cycle, |cycle| { - if let TaggedQueryKey::layout_of(key) = cycle[0].node.tagged_key + if let TaggedQueryKey::layout_of(key) = cycle[0].tagged_key && let ty::Coroutine(def_id, _) = key.value.kind() && let Some(def_id) = def_id.as_local() && let def_kind = tcx.def_kind(def_id) @@ -159,7 +159,7 @@ fn layout_of<'tcx>( tcx.def_kind_descr(def_kind, def_id.to_def_id()), ); for (i, frame) in cycle.iter().enumerate() { - let TaggedQueryKey::layout_of(frame_key) = frame.node.tagged_key else { + let TaggedQueryKey::layout_of(frame_key) = frame.tagged_key else { continue; }; let &ty::Coroutine(frame_def_id, _) = frame_key.value.kind() else { @@ -169,7 +169,7 @@ fn layout_of<'tcx>( continue; }; let frame_span = - frame.node.tagged_key.default_span(tcx, cycle[(i + 1) % cycle.len()].span); + frame.tagged_key.default_span(tcx, cycle[(i + 1) % cycle.len()].span); if frame_span.is_dummy() { continue; } diff --git a/compiler/rustc_query_impl/src/job.rs b/compiler/rustc_query_impl/src/job.rs index 9d2d6cc54d49e..29877c8aac88f 100644 --- a/compiler/rustc_query_impl/src/job.rs +++ b/compiler/rustc_query_impl/src/job.rs @@ -11,7 +11,7 @@ use rustc_middle::query::{ CycleError, QueryJob, QueryJobId, QueryLatch, QueryStackFrame, QueryWaiter, }; use rustc_middle::ty::TyCtxt; -use rustc_span::{DUMMY_SP, Span, respan}; +use rustc_span::{DUMMY_SP, Span}; use crate::{CollectActiveJobsKind, collect_active_query_jobs}; @@ -30,8 +30,8 @@ impl<'tcx> QueryJobMap<'tcx> { self.map.insert(id, info); } - fn frame_of(&self, id: QueryJobId) -> &QueryStackFrame<'tcx> { - &self.map[&id].frame + fn tagged_key_of(&self, id: QueryJobId) -> TaggedQueryKey<'tcx> { + self.map[&id].tagged_key } fn span_of(&self, id: QueryJobId) -> Span { @@ -49,7 +49,7 @@ impl<'tcx> QueryJobMap<'tcx> { #[derive(Debug)] pub(crate) struct QueryJobInfo<'tcx> { - pub(crate) frame: QueryStackFrame<'tcx>, + pub(crate) tagged_key: TaggedQueryKey<'tcx>, pub(crate) job: QueryJob<'tcx>, } @@ -65,7 +65,7 @@ pub(crate) fn find_cycle_in_stack<'tcx>( while let Some(job) = current_job { let info = &job_map.map[&job]; - cycle.push(respan(info.job.span, info.frame.clone())); + cycle.push(QueryStackFrame { span: info.job.span, tagged_key: info.tagged_key }); if job == id { cycle.reverse(); @@ -78,7 +78,7 @@ pub(crate) fn find_cycle_in_stack<'tcx>( // Find out why the cycle itself was used let usage = try { let parent = info.job.parent?; - respan(info.job.span, job_map.frame_of(parent).clone()) + QueryStackFrame { span: info.job.span, tagged_key: job_map.tagged_key_of(parent) } }; return CycleError { usage, cycle }; } @@ -100,19 +100,19 @@ pub(crate) fn find_dep_kind_root<'tcx>( ) -> (Span, String, usize) { let mut depth = 1; let mut info = &job_map.map[&id]; - // Two query stack frames are for the same query method if they have the same + // Two query jobs are for the same query method if they have the same // `TaggedQueryKey` discriminant. - let expected_query = mem::discriminant::>(&info.frame.tagged_key); + let expected_query = mem::discriminant::>(&info.tagged_key); let mut last_info = info; while let Some(id) = info.job.parent { info = &job_map.map[&id]; - if mem::discriminant(&info.frame.tagged_key) == expected_query { + if mem::discriminant(&info.tagged_key) == expected_query { depth += 1; last_info = info; } } - (last_info.job.span, last_info.frame.tagged_key.description(tcx), depth) + (last_info.job.span, last_info.tagged_key.description(tcx), depth) } /// The locaton of a resumable waiter. The usize is the index into waiters in the query's latch. @@ -316,14 +316,17 @@ fn remove_cycle<'tcx>( let usage = entry_point .query_waiting_on_cycle - .map(|(span, job)| respan(span, job_map.frame_of(job).clone())); + .map(|(span, job)| QueryStackFrame { span, tagged_key: job_map.tagged_key_of(job) }); // Create the cycle error let error = CycleError { usage, cycle: stack .iter() - .map(|&(span, job)| respan(span, job_map.frame_of(job).clone())) + .map(|&(span, job)| QueryStackFrame { + span, + tagged_key: job_map.tagged_key_of(job), + }) .collect(), }; @@ -419,12 +422,12 @@ pub fn print_query_stack<'tcx>( let Some(query_info) = job_map.map.get(&query) else { break; }; - let description = query_info.frame.tagged_key.description(tcx); + let description = query_info.tagged_key.description(tcx); if Some(count_printed) < limit_frames || limit_frames.is_none() { // Only print to stderr as many stack frames as `num_frames` when present. dcx.struct_failure_note(format!( "#{count_printed} [{query_name}] {description}", - query_name = query_info.frame.tagged_key.query_name(), + query_name = query_info.tagged_key.query_name(), )) .with_span(query_info.job.span) .emit(); @@ -435,7 +438,7 @@ pub fn print_query_stack<'tcx>( let _ = writeln!( file, "#{count_total} [{query_name}] {description}", - query_name = query_info.frame.tagged_key.query_name(), + query_name = query_info.tagged_key.query_name(), ); } @@ -457,12 +460,12 @@ pub(crate) fn report_cycle<'tcx>( ) -> Diag<'tcx> { assert!(!stack.is_empty()); - let span = stack[0].node.tagged_key.default_span(tcx, stack[1 % stack.len()].span); + let span = stack[0].tagged_key.default_span(tcx, stack[1 % stack.len()].span); let mut cycle_stack = Vec::new(); use crate::error::StackCount; - let stack_bottom = stack[0].node.tagged_key.description(tcx); + let stack_bottom = stack[0].tagged_key.description(tcx); let stack_count = if stack.len() == 1 { StackCount::Single { stack_bottom: stack_bottom.clone() } } else { @@ -470,24 +473,23 @@ pub(crate) fn report_cycle<'tcx>( }; for i in 1..stack.len() { - let node = &stack[i].node; - let span = node.tagged_key.default_span(tcx, stack[(i + 1) % stack.len()].span); - cycle_stack.push(crate::error::CycleStack { span, desc: node.tagged_key.description(tcx) }); + let frame = &stack[i]; + let span = frame.tagged_key.default_span(tcx, stack[(i + 1) % stack.len()].span); + cycle_stack + .push(crate::error::CycleStack { span, desc: frame.tagged_key.description(tcx) }); } let cycle_usage = usage.as_ref().map(|usage| crate::error::CycleUsage { - span: usage.node.tagged_key.default_span(tcx, usage.span), - usage: usage.node.tagged_key.description(tcx), + span: usage.tagged_key.default_span(tcx, usage.span), + usage: usage.tagged_key.description(tcx), }); let alias = if stack .iter() - .all(|entry| matches!(entry.node.tagged_key.def_kind(tcx), Some(DefKind::TyAlias))) + .all(|frame| frame.tagged_key.def_kind(tcx) == Some(DefKind::TyAlias)) { Some(crate::error::Alias::Ty) - } else if stack - .iter() - .all(|entry| entry.node.tagged_key.def_kind(tcx) == Some(DefKind::TraitAlias)) + } else if stack.iter().all(|frame| frame.tagged_key.def_kind(tcx) == Some(DefKind::TraitAlias)) { Some(crate::error::Alias::Trait) } else { From fb850aebcd39f7dd7973adabf380bdc5bb22a369 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 18 Mar 2026 10:36:19 +1100 Subject: [PATCH 4/4] Remove unused types `UnusedGenericParams` and `FiniteBitSet` These types have been unused since polymorphization was removed in . --- .../src/stable_hasher.rs | 9 -- compiler/rustc_index/src/bit_set.rs | 113 +----------------- compiler/rustc_metadata/src/rmeta/mod.rs | 2 +- compiler/rustc_metadata/src/rmeta/table.rs | 10 -- compiler/rustc_middle/src/query/erase.rs | 2 - compiler/rustc_middle/src/ty/instance.rs | 50 +------- compiler/rustc_middle/src/ty/mod.rs | 2 +- 7 files changed, 4 insertions(+), 184 deletions(-) diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs index 9fb4d4352c2f6..f8e72d66d07ef 100644 --- a/compiler/rustc_data_structures/src/stable_hasher.rs +++ b/compiler/rustc_data_structures/src/stable_hasher.rs @@ -555,15 +555,6 @@ impl HashStable for bit_set::BitMatrix { } } -impl HashStable for bit_set::FiniteBitSet -where - T: HashStable + bit_set::FiniteBitSetTy, -{ - fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { - self.0.hash_stable(hcx, hasher); - } -} - impl_stable_traits_for_trivial_type!(::std::ffi::OsStr); impl_stable_traits_for_trivial_type!(::std::path::Path); diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs index 68384c73ba25a..f833acf6824e4 100644 --- a/compiler/rustc_index/src/bit_set.rs +++ b/compiler/rustc_index/src/bit_set.rs @@ -1,7 +1,7 @@ use std::marker::PhantomData; #[cfg(not(feature = "nightly"))] use std::mem; -use std::ops::{BitAnd, BitAndAssign, BitOrAssign, Bound, Not, Range, RangeBounds, Shl}; +use std::ops::{Bound, Range, RangeBounds}; use std::rc::Rc; use std::{fmt, iter, slice}; @@ -1736,114 +1736,3 @@ fn max_bit(word: Word) -> usize { fn count_ones(words: &[Word]) -> usize { words.iter().map(|word| word.count_ones() as usize).sum() } - -/// Integral type used to represent the bit set. -pub trait FiniteBitSetTy: - BitAnd - + BitAndAssign - + BitOrAssign - + Clone - + Copy - + Shl - + Not - + PartialEq - + Sized -{ - /// Size of the domain representable by this type, e.g. 64 for `u64`. - const DOMAIN_SIZE: u32; - - /// Value which represents the `FiniteBitSet` having every bit set. - const FILLED: Self; - /// Value which represents the `FiniteBitSet` having no bits set. - const EMPTY: Self; - - /// Value for one as the integral type. - const ONE: Self; - /// Value for zero as the integral type. - const ZERO: Self; - - /// Perform a checked left shift on the integral type. - fn checked_shl(self, rhs: u32) -> Option; - /// Perform a checked right shift on the integral type. - fn checked_shr(self, rhs: u32) -> Option; -} - -impl FiniteBitSetTy for u32 { - const DOMAIN_SIZE: u32 = 32; - - const FILLED: Self = Self::MAX; - const EMPTY: Self = Self::MIN; - - const ONE: Self = 1u32; - const ZERO: Self = 0u32; - - fn checked_shl(self, rhs: u32) -> Option { - self.checked_shl(rhs) - } - - fn checked_shr(self, rhs: u32) -> Option { - self.checked_shr(rhs) - } -} - -impl std::fmt::Debug for FiniteBitSet { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:032b}", self.0) - } -} - -/// A fixed-sized bitset type represented by an integer type. Indices outwith than the range -/// representable by `T` are considered set. -#[cfg_attr(feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext))] -#[derive(Copy, Clone, Eq, PartialEq)] -pub struct FiniteBitSet(pub T); - -impl FiniteBitSet { - /// Creates a new, empty bitset. - pub fn new_empty() -> Self { - Self(T::EMPTY) - } - - /// Sets the `index`th bit. - pub fn set(&mut self, index: u32) { - self.0 |= T::ONE.checked_shl(index).unwrap_or(T::ZERO); - } - - /// Unsets the `index`th bit. - pub fn clear(&mut self, index: u32) { - self.0 &= !T::ONE.checked_shl(index).unwrap_or(T::ZERO); - } - - /// Sets the `i`th to `j`th bits. - pub fn set_range(&mut self, range: Range) { - let bits = T::FILLED - .checked_shl(range.end - range.start) - .unwrap_or(T::ZERO) - .not() - .checked_shl(range.start) - .unwrap_or(T::ZERO); - self.0 |= bits; - } - - /// Is the set empty? - pub fn is_empty(&self) -> bool { - self.0 == T::EMPTY - } - - /// Returns the domain size of the bitset. - pub fn within_domain(&self, index: u32) -> bool { - index < T::DOMAIN_SIZE - } - - /// Returns if the `index`th bit is set. - pub fn contains(&self, index: u32) -> Option { - self.within_domain(index) - .then(|| ((self.0.checked_shr(index).unwrap_or(T::ONE)) & T::ONE) == T::ONE) - } -} - -impl Default for FiniteBitSet { - fn default() -> Self { - Self::new_empty() - } -} diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 80d7ae4e9cb38..9dee913e8389c 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -33,7 +33,7 @@ use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault; use rustc_middle::mir; use rustc_middle::mir::ConstValue; use rustc_middle::ty::fast_reject::SimplifiedType; -use rustc_middle::ty::{self, Ty, TyCtxt, UnusedGenericParams}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::util::Providers; use rustc_serialize::opaque::FileEncoder; use rustc_session::config::{SymbolManglingVersion, TargetModifier}; diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index 5e256438ad953..3b0570dd373a8 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -44,16 +44,6 @@ impl IsDefault for LazyArray { } } -impl IsDefault for UnusedGenericParams { - fn is_default(&self) -> bool { - // UnusedGenericParams encodes the *un*usedness as a bitset. - // This means that 0 corresponds to all bits used, which is indeed the default. - let is_default = self.bits() == 0; - debug_assert_eq!(is_default, self.all_used()); - is_default - } -} - /// Helper trait, for encoding to, and decoding from, a fixed number of bytes. /// Used mainly for Lazy positions and lengths. /// diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index d15e0b2a122b9..036aa2ed05a4a 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -356,7 +356,6 @@ impl_erasable_for_simple_types! { rustc_hir::OwnerId, rustc_hir::Stability, rustc_hir::Upvar, - rustc_index::bit_set::FiniteBitSet, rustc_middle::middle::deduced_param_attrs::DeducedParamAttrs, rustc_middle::middle::dependency_format::Linkage, rustc_middle::middle::exported_symbols::SymbolExportInfo, @@ -383,7 +382,6 @@ impl_erasable_for_simple_types! { rustc_middle::ty::Destructor, rustc_middle::ty::fast_reject::SimplifiedType, rustc_middle::ty::ImplPolarity, - rustc_middle::ty::UnusedGenericParams, rustc_middle::ty::util::AlwaysRequiresDrop, rustc_middle::ty::Visibility, rustc_middle::middle::codegen_fn_attrs::SanitizerFnAttrs, diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 4cea8b62f0b62..9759e376c0586 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -6,8 +6,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Namespace}; use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::lang_items::LangItem; -use rustc_index::bit_set::FiniteBitSet; -use rustc_macros::{Decodable, Encodable, HashStable, Lift, TyDecodable, TyEncodable}; +use rustc_macros::{HashStable, Lift, TyDecodable, TyEncodable}; use rustc_span::def_id::LOCAL_CRATE; use rustc_span::{DUMMY_SP, Span}; use tracing::{debug, instrument}; @@ -941,50 +940,3 @@ fn needs_fn_once_adapter_shim( (ty::ClosureKind::FnMut | ty::ClosureKind::FnOnce, _) => Err(()), } } - -// Set bits represent unused generic parameters. -// An empty set indicates that all parameters are used. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Decodable, Encodable, HashStable)] -pub struct UnusedGenericParams(FiniteBitSet); - -impl Default for UnusedGenericParams { - fn default() -> Self { - UnusedGenericParams::new_all_used() - } -} - -impl UnusedGenericParams { - pub fn new_all_unused(amount: u32) -> Self { - let mut bitset = FiniteBitSet::new_empty(); - bitset.set_range(0..amount); - Self(bitset) - } - - pub fn new_all_used() -> Self { - Self(FiniteBitSet::new_empty()) - } - - pub fn mark_used(&mut self, idx: u32) { - self.0.clear(idx); - } - - pub fn is_unused(&self, idx: u32) -> bool { - self.0.contains(idx).unwrap_or(false) - } - - pub fn is_used(&self, idx: u32) -> bool { - !self.is_unused(idx) - } - - pub fn all_used(&self) -> bool { - self.0.is_empty() - } - - pub fn bits(&self) -> u32 { - self.0.0 - } - - pub fn from_bits(bits: u32) -> UnusedGenericParams { - UnusedGenericParams(FiniteBitSet(bits)) - } -} diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 01c351de93198..2b02d42890aa9 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -85,7 +85,7 @@ pub use self::context::{ CtxtInterners, CurrentGcx, Feed, FreeRegionInfo, GlobalCtxt, Lift, TyCtxt, TyCtxtFeed, tls, }; pub use self::fold::*; -pub use self::instance::{Instance, InstanceKind, ReifyReason, UnusedGenericParams}; +pub use self::instance::{Instance, InstanceKind, ReifyReason}; pub use self::list::{List, ListWithCachedTypeInfo}; pub use self::opaque_types::OpaqueTypeKey; pub use self::pattern::{Pattern, PatternKind};