Auto merge of #154032 - Zalathar:rollup-Aejl3zc, r=Zalathar

Rollup of 3 pull requests

Successful merges:

 - rust-lang/rust#153998 (Move query-stack-frame spans into `QueryStackFrame`)
 - rust-lang/rust#153778 (Couple of driver interface improvements)
 - rust-lang/rust#154026 (Remove unused types `UnusedGenericParams` and `FiniteBitSet`)
This commit is contained in:
bors
2026-03-18 04:09:07 +00:00
26 changed files with 120 additions and 295 deletions
+2 -2
View File
@@ -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 {
@@ -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()));
@@ -555,15 +555,6 @@ fn hash_stable(&self, _ctx: &mut CTX, hasher: &mut StableHasher) {
}
}
impl<T, CTX> HashStable<CTX> for bit_set::FiniteBitSet<T>
where
T: HashStable<CTX> + 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);
+1 -1
View File
@@ -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(),
@@ -475,14 +475,15 @@ fn injected_env_var(&mut self, var: &str) -> Option<String> {
}
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<Literal<Self::Span, Self::Symbol>, String> {
+1 -112
View File
@@ -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<Output = Self>
+ BitAndAssign
+ BitOrAssign
+ Clone
+ Copy
+ Shl
+ Not<Output = Self>
+ 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<Self>;
/// Perform a checked right shift on the integral type.
fn checked_shr(self, rhs: u32) -> Option<Self>;
}
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> {
self.checked_shl(rhs)
}
fn checked_shr(self, rhs: u32) -> Option<Self> {
self.checked_shr(rhs)
}
}
impl std::fmt::Debug for FiniteBitSet<u32> {
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<T: FiniteBitSetTy>(pub T);
impl<T: FiniteBitSetTy> FiniteBitSet<T> {
/// 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<u32>) {
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<bool> {
self.within_domain(index)
.then(|| ((self.0.checked_shr(index).unwrap_or(T::ONE)) & T::ONE) == T::ONE)
}
}
impl<T: FiniteBitSetTy> Default for FiniteBitSet<T> {
fn default() -> Self {
Self::new_empty()
}
}
+23 -23
View File
@@ -22,7 +22,6 @@
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;
@@ -337,11 +336,14 @@ pub struct Config {
/// This is a callback from the driver that is called when [`ParseSess`] is created.
pub psess_created: Option<Box<dyn FnOnce(&mut ParseSess) + Send>>,
/// 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<Box<dyn FnOnce(&Session, &mut StableHasher) + Send>>,
/// 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<Box<dyn FnOnce(&Session, &mut StableHasher) + Send>>,
/// 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.
@@ -364,8 +366,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<dyn FnOnce(&config::Options, &Target) -> Box<dyn CodegenBackend> + Send>>,
pub make_codegen_backend: Option<Box<dyn FnOnce(&Session) -> Box<dyn CodegenBackend> + 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 +420,6 @@ pub fn run_compiler<R: Send>(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 +437,19 @@ pub fn run_compiler<R: Send>(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();
@@ -467,9 +467,9 @@ pub fn run_compiler<R: Send>(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()
}
+3 -3
View File
@@ -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 hash_iter_files<P: AsRef<Path>>(
}
// 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)]
+1 -1
View File
@@ -33,7 +33,7 @@
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};
@@ -44,16 +44,6 @@ fn is_default(&self) -> bool {
}
}
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.
///
-2
View File
@@ -356,7 +356,6 @@ impl Erasable for $ty {
rustc_hir::OwnerId,
rustc_hir::Stability,
rustc_hir::Upvar,
rustc_index::bit_set::FiniteBitSet<u32>,
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 $ty {
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_span::def_id::DefId>,
rustc_middle::middle::codegen_fn_attrs::SanitizerFnAttrs,
+5 -6
View File
@@ -8,15 +8,14 @@
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<Spanned<QueryStackFrame<'tcx>>>,
pub usage: Option<QueryStackFrame<'tcx>>,
/// The span here corresponds to the reason for which this query was required.
pub cycle: Vec<Spanned<QueryStackFrame<'tcx>>>,
pub cycle: Vec<QueryStackFrame<'tcx>>,
}
#[derive(Debug)]
@@ -505,7 +504,7 @@ pub fn $name(self, value: $name::ProvidedValue<'tcx>) {
/// 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>),
+5 -1
View File
@@ -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.
///
+1 -49
View File
@@ -6,8 +6,7 @@
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<u32>);
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))
}
}
+1 -1
View File
@@ -85,7 +85,7 @@
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};
+3 -3
View File
@@ -9,7 +9,7 @@
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() });
}
}
};
@@ -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;
}
+28 -26
View File
@@ -11,7 +11,7 @@
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 @@ pub(crate) fn insert(&mut self, id: QueryJobId, info: QueryJobInfo<'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 @@ fn latch_of(&self, id: QueryJobId) -> Option<&QueryLatch<'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::<TaggedQueryKey<'tcx>>(&info.frame.tagged_key);
let expected_query = mem::discriminant::<TaggedQueryKey<'tcx>>(&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 @@ struct EntryPoint {
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 {
+3 -3
View File
@@ -419,9 +419,9 @@ pub struct Options {
/// directory to store intermediate results.
incremental: Option<PathBuf> [UNTRACKED],
assert_incr_state: Option<IncrementalStateAssertion> [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],
+1 -7
View File
@@ -6,7 +6,7 @@
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<FxIndexMap<Span, Span>>,
pub gated_spans: GatedSpans,
pub symbol_gallery: SymbolGallery,
/// Environment variables accessed during the build and their values when they exist.
pub env_depinfo: Lock<FxIndexSet<(Symbol, Option<Symbol>)>>,
/// File paths accessed during the build.
pub file_depinfo: Lock<FxIndexSet<Symbol>>,
/// 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 @@ pub fn with_dcx(dcx: DiagCtxt, source_map: Arc<SourceMap>) -> Self {
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(),
+8
View File
@@ -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<FxIndexSet<(Symbol, Option<Symbol>)>>,
/// File paths accessed during the build.
pub file_depinfo: Lock<FxIndexSet<Symbol>>,
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,
+1 -1
View File
@@ -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`.
+1 -1
View File
@@ -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(),
+12 -14
View File
@@ -23,9 +23,8 @@
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 @@ fn config(&mut self, config: &mut interface::Config) {
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)),
));
+11 -11
View File
@@ -18,7 +18,6 @@
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::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::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<dyn CodegenBackend> {
let early_dcx = EarlyDiagCtxt::new(opts.error_format);
fn make_miri_codegen_backend(sess: &Session) -> Box<dyn CodegenBackend> {
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)
})),
})
+1 -1
View File
@@ -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(),