Immediately enter in TyCtxt::create_global_ctxt
This commit is contained in:
parent
954cd79ced
commit
6545a2dc92
2 changed files with 62 additions and 68 deletions
|
@ -709,25 +709,10 @@ pub static DEFAULT_QUERY_PROVIDERS: LazyLock<Providers> = LazyLock::new(|| {
|
||||||
*providers
|
*providers
|
||||||
});
|
});
|
||||||
|
|
||||||
pub fn create_and_enter_global_ctxt<T>(
|
pub fn create_and_enter_global_ctxt<T, F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> T>(
|
||||||
compiler: &Compiler,
|
compiler: &Compiler,
|
||||||
krate: rustc_ast::Crate,
|
|
||||||
f: impl for<'tcx> FnOnce(TyCtxt<'tcx>) -> T,
|
|
||||||
) -> T {
|
|
||||||
let gcx_cell = OnceLock::new();
|
|
||||||
let arena = WorkerLocal::new(|_| Arena::default());
|
|
||||||
let hir_arena = WorkerLocal::new(|_| rustc_hir::Arena::default());
|
|
||||||
|
|
||||||
create_and_enter_global_ctxt_inner(compiler, krate, &gcx_cell, &arena, &hir_arena, f)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_and_enter_global_ctxt_inner<'tcx, T>(
|
|
||||||
compiler: &'tcx Compiler,
|
|
||||||
mut krate: rustc_ast::Crate,
|
mut krate: rustc_ast::Crate,
|
||||||
gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
|
f: F,
|
||||||
arena: &'tcx WorkerLocal<Arena<'tcx>>,
|
|
||||||
hir_arena: &'tcx WorkerLocal<rustc_hir::Arena<'tcx>>,
|
|
||||||
f: impl FnOnce(TyCtxt<'tcx>) -> T,
|
|
||||||
) -> T {
|
) -> T {
|
||||||
let sess = &compiler.sess;
|
let sess = &compiler.sess;
|
||||||
|
|
||||||
|
@ -776,8 +761,25 @@ fn create_and_enter_global_ctxt_inner<'tcx, T>(
|
||||||
|
|
||||||
let incremental = dep_graph.is_fully_enabled();
|
let incremental = dep_graph.is_fully_enabled();
|
||||||
|
|
||||||
let qcx = gcx_cell.get_or_init(move || {
|
let gcx_cell = OnceLock::new();
|
||||||
|
let arena = WorkerLocal::new(|_| Arena::default());
|
||||||
|
let hir_arena = WorkerLocal::new(|_| rustc_hir::Arena::default());
|
||||||
|
|
||||||
|
// This closure is necessary to force rustc to perform the correct lifetime
|
||||||
|
// subtyping for GlobalCtxt::enter to be allowed.
|
||||||
|
let inner: Box<
|
||||||
|
dyn for<'tcx> FnOnce(
|
||||||
|
&'tcx Compiler,
|
||||||
|
&'tcx OnceLock<GlobalCtxt<'tcx>>,
|
||||||
|
&'tcx WorkerLocal<Arena<'tcx>>,
|
||||||
|
&'tcx WorkerLocal<rustc_hir::Arena<'tcx>>,
|
||||||
|
F,
|
||||||
|
) -> T,
|
||||||
|
> = Box::new(move |compiler, gcx_cell, arena, hir_arena, f| {
|
||||||
|
let sess = &compiler.sess;
|
||||||
|
|
||||||
TyCtxt::create_global_ctxt(
|
TyCtxt::create_global_ctxt(
|
||||||
|
gcx_cell,
|
||||||
sess,
|
sess,
|
||||||
crate_types,
|
crate_types,
|
||||||
stable_crate_id,
|
stable_crate_id,
|
||||||
|
@ -794,28 +796,29 @@ fn create_and_enter_global_ctxt_inner<'tcx, T>(
|
||||||
),
|
),
|
||||||
providers.hooks,
|
providers.hooks,
|
||||||
compiler.current_gcx.clone(),
|
compiler.current_gcx.clone(),
|
||||||
|
|tcx| {
|
||||||
|
let feed = tcx.create_crate_num(stable_crate_id).unwrap();
|
||||||
|
assert_eq!(feed.key(), LOCAL_CRATE);
|
||||||
|
feed.crate_name(crate_name);
|
||||||
|
|
||||||
|
let feed = tcx.feed_unit_query();
|
||||||
|
feed.features_query(tcx.arena.alloc(rustc_expand::config::features(
|
||||||
|
sess,
|
||||||
|
&pre_configured_attrs,
|
||||||
|
crate_name,
|
||||||
|
)));
|
||||||
|
feed.crate_for_resolver(tcx.arena.alloc(Steal::new((krate, pre_configured_attrs))));
|
||||||
|
feed.output_filenames(Arc::new(outputs));
|
||||||
|
|
||||||
|
let res = f(tcx);
|
||||||
|
// FIXME maybe run finish even when a fatal error occured? or at least tcx.alloc_self_profile_query_strings()?
|
||||||
|
tcx.finish();
|
||||||
|
res
|
||||||
|
},
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
qcx.enter(|tcx| {
|
inner(compiler, &gcx_cell, &arena, &hir_arena, f)
|
||||||
let feed = tcx.create_crate_num(stable_crate_id).unwrap();
|
|
||||||
assert_eq!(feed.key(), LOCAL_CRATE);
|
|
||||||
feed.crate_name(crate_name);
|
|
||||||
|
|
||||||
let feed = tcx.feed_unit_query();
|
|
||||||
feed.features_query(tcx.arena.alloc(rustc_expand::config::features(
|
|
||||||
sess,
|
|
||||||
&pre_configured_attrs,
|
|
||||||
crate_name,
|
|
||||||
)));
|
|
||||||
feed.crate_for_resolver(tcx.arena.alloc(Steal::new((krate, pre_configured_attrs))));
|
|
||||||
feed.output_filenames(Arc::new(outputs));
|
|
||||||
|
|
||||||
let res = f(tcx);
|
|
||||||
// FIXME maybe run finish even when a fatal error occured? or at least tcx.alloc_self_profile_query_strings()?
|
|
||||||
tcx.finish();
|
|
||||||
res
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Runs all analyses that we guarantee to run, even if errors were reported in earlier analyses.
|
/// Runs all analyses that we guarantee to run, even if errors were reported in earlier analyses.
|
||||||
|
|
|
@ -10,6 +10,7 @@ use std::cmp::Ordering;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::ops::{Bound, Deref};
|
use std::ops::{Bound, Deref};
|
||||||
|
use std::sync::OnceLock;
|
||||||
use std::{fmt, iter, mem};
|
use std::{fmt, iter, mem};
|
||||||
|
|
||||||
use rustc_abi::{ExternAbi, FieldIdx, Layout, LayoutData, TargetDataLayout, VariantIdx};
|
use rustc_abi::{ExternAbi, FieldIdx, Layout, LayoutData, TargetDataLayout, VariantIdx};
|
||||||
|
@ -1347,33 +1348,6 @@ pub struct GlobalCtxt<'tcx> {
|
||||||
|
|
||||||
/// Stores memory for globals (statics/consts).
|
/// Stores memory for globals (statics/consts).
|
||||||
pub(crate) alloc_map: Lock<interpret::AllocMap<'tcx>>,
|
pub(crate) alloc_map: Lock<interpret::AllocMap<'tcx>>,
|
||||||
|
|
||||||
current_gcx: CurrentGcx,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> GlobalCtxt<'tcx> {
|
|
||||||
/// Installs `self` in a `TyCtxt` and `ImplicitCtxt` for the duration of
|
|
||||||
/// `f`.
|
|
||||||
pub fn enter<F, R>(&'tcx self, f: F) -> R
|
|
||||||
where
|
|
||||||
F: FnOnce(TyCtxt<'tcx>) -> R,
|
|
||||||
{
|
|
||||||
let icx = tls::ImplicitCtxt::new(self);
|
|
||||||
|
|
||||||
// Reset `current_gcx` to `None` when we exit.
|
|
||||||
let _on_drop = defer(move || {
|
|
||||||
*self.current_gcx.value.write() = None;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Set this `GlobalCtxt` as the current one.
|
|
||||||
{
|
|
||||||
let mut guard = self.current_gcx.value.write();
|
|
||||||
assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
|
|
||||||
*guard = Some(self as *const _ as *const ());
|
|
||||||
}
|
|
||||||
|
|
||||||
tls::enter_context(&icx, || f(icx.tcx))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is used to get a reference to a `GlobalCtxt` if one is available.
|
/// This is used to get a reference to a `GlobalCtxt` if one is available.
|
||||||
|
@ -1517,7 +1491,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
/// By only providing the `TyCtxt` inside of the closure we enforce that the type
|
/// By only providing the `TyCtxt` inside of the closure we enforce that the type
|
||||||
/// context and any interned value (types, args, etc.) can only be used while `ty::tls`
|
/// context and any interned value (types, args, etc.) can only be used while `ty::tls`
|
||||||
/// has a valid reference to the context, to allow formatting values that need it.
|
/// has a valid reference to the context, to allow formatting values that need it.
|
||||||
pub fn create_global_ctxt(
|
pub fn create_global_ctxt<T>(
|
||||||
|
gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
|
||||||
s: &'tcx Session,
|
s: &'tcx Session,
|
||||||
crate_types: Vec<CrateType>,
|
crate_types: Vec<CrateType>,
|
||||||
stable_crate_id: StableCrateId,
|
stable_crate_id: StableCrateId,
|
||||||
|
@ -1529,7 +1504,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
query_system: QuerySystem<'tcx>,
|
query_system: QuerySystem<'tcx>,
|
||||||
hooks: crate::hooks::Providers,
|
hooks: crate::hooks::Providers,
|
||||||
current_gcx: CurrentGcx,
|
current_gcx: CurrentGcx,
|
||||||
) -> GlobalCtxt<'tcx> {
|
f: impl FnOnce(TyCtxt<'tcx>) -> T,
|
||||||
|
) -> T {
|
||||||
let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| {
|
let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| {
|
||||||
s.dcx().emit_fatal(err);
|
s.dcx().emit_fatal(err);
|
||||||
});
|
});
|
||||||
|
@ -1538,7 +1514,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
let common_lifetimes = CommonLifetimes::new(&interners);
|
let common_lifetimes = CommonLifetimes::new(&interners);
|
||||||
let common_consts = CommonConsts::new(&interners, &common_types, s, &untracked);
|
let common_consts = CommonConsts::new(&interners, &common_types, s, &untracked);
|
||||||
|
|
||||||
GlobalCtxt {
|
let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
|
||||||
sess: s,
|
sess: s,
|
||||||
crate_types,
|
crate_types,
|
||||||
stable_crate_id,
|
stable_crate_id,
|
||||||
|
@ -1562,8 +1538,23 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
canonical_param_env_cache: Default::default(),
|
canonical_param_env_cache: Default::default(),
|
||||||
data_layout,
|
data_layout,
|
||||||
alloc_map: Lock::new(interpret::AllocMap::new()),
|
alloc_map: Lock::new(interpret::AllocMap::new()),
|
||||||
current_gcx,
|
});
|
||||||
|
|
||||||
|
let icx = tls::ImplicitCtxt::new(&gcx);
|
||||||
|
|
||||||
|
// Reset `current_gcx` to `None` when we exit.
|
||||||
|
let _on_drop = defer(|| {
|
||||||
|
*current_gcx.value.write() = None;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set this `GlobalCtxt` as the current one.
|
||||||
|
{
|
||||||
|
let mut guard = current_gcx.value.write();
|
||||||
|
assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
|
||||||
|
*guard = Some(&gcx as *const _ as *const ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tls::enter_context(&icx, || f(icx.tcx))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Obtain all lang items of this crate and all dependencies (recursively)
|
/// Obtain all lang items of this crate and all dependencies (recursively)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue