mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
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:
@@ -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);
|
||||
|
||||
@@ -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,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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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.
|
||||
///
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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>),
|
||||
|
||||
@@ -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.
|
||||
///
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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)),
|
||||
));
|
||||
|
||||
@@ -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)
|
||||
})),
|
||||
})
|
||||
|
||||
@@ -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(),
|
||||
|
||||
Reference in New Issue
Block a user