mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Remove tls::with_related_context.
This function gets the current `ImplicitCtxt` and checks that its `tcx` matches the passed-in `tcx`. It's an extra bit of sanity checking: when you already have a `tcx`, and you need access to the non-`tcx` parts of `ImplicitCtxt`, check that your `tcx` matches the one in `ImplicitCtxt`. However, it's only used in two places: `start_query` and `current_query_job`. The non-checked alternatives (`with_context`, `with_context_opt`) are used in more places, including some where a `tcx` is available. And things would have to go catastrophically wrong for the check to fail -- e.g. if we somehow end up with multiple `TyCtxt`s. In my opinion it's just an extra case to understand in `tls.rs` that adds little value. This commit removes it. This avoids the need for `tcx` parameters in a couple of places. The commit also adjusts how `start_query` sets up its `ImplicitCtxt` to more closely match how similar functions do it, i.e. with `..icx.clone()` for the unchanged fields.
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
use std::{mem, ptr};
|
||||
|
||||
use rustc_data_structures::sync;
|
||||
|
||||
use super::{GlobalCtxt, TyCtxt};
|
||||
@@ -89,29 +87,6 @@ pub fn with_context<F, R>(f: F) -> R
|
||||
with_context_opt(|opt_context| f(opt_context.expect("no ImplicitCtxt stored in tls")))
|
||||
}
|
||||
|
||||
/// Allows access to the current `ImplicitCtxt` whose tcx field is the same as the tcx argument
|
||||
/// passed in. This means the closure is given an `ImplicitCtxt` with the same `'tcx` lifetime
|
||||
/// as the `TyCtxt` passed in.
|
||||
/// This will panic if you pass it a `TyCtxt` which is different from the current
|
||||
/// `ImplicitCtxt`'s `tcx` field.
|
||||
#[inline]
|
||||
pub fn with_related_context<'tcx, F, R>(tcx: TyCtxt<'tcx>, f: F) -> R
|
||||
where
|
||||
F: FnOnce(&ImplicitCtxt<'_, 'tcx>) -> R,
|
||||
{
|
||||
with_context(|context| {
|
||||
// The two gcx have different invariant lifetimes, so we need to erase them for the comparison.
|
||||
assert!(ptr::eq(
|
||||
context.tcx.gcx as *const _ as *const (),
|
||||
tcx.gcx as *const _ as *const ()
|
||||
));
|
||||
|
||||
let context: &ImplicitCtxt<'_, '_> = unsafe { mem::transmute(context) };
|
||||
|
||||
f(context)
|
||||
})
|
||||
}
|
||||
|
||||
/// Allows access to the `TyCtxt` in the current `ImplicitCtxt`.
|
||||
/// Panics if there is no `ImplicitCtxt` available.
|
||||
#[inline]
|
||||
|
||||
@@ -228,7 +228,7 @@ fn cycle_error<'tcx, C: QueryCache>(
|
||||
.ok()
|
||||
.expect("failed to collect active queries");
|
||||
|
||||
let error = find_cycle_in_stack(try_execute, job_map, ¤t_query_job(tcx), span);
|
||||
let error = find_cycle_in_stack(try_execute, job_map, ¤t_query_job(), span);
|
||||
(mk_cycle(query, tcx, error.lift()), None)
|
||||
}
|
||||
|
||||
@@ -305,7 +305,7 @@ fn try_execute_query<'tcx, C: QueryCache, const INCR: bool>(
|
||||
}
|
||||
}
|
||||
|
||||
let current_job_id = current_query_job(tcx);
|
||||
let current_job_id = current_query_job();
|
||||
|
||||
match state_lock.entry(key_hash, equivalent_key(&key), |(k, _)| sharded::make_hash(k)) {
|
||||
Entry::Vacant(entry) => {
|
||||
@@ -422,8 +422,7 @@ fn execute_job_non_incr<'tcx, C: QueryCache>(
|
||||
|
||||
let prof_timer = tcx.prof.query_provider();
|
||||
// Call the query provider.
|
||||
let value =
|
||||
start_query(tcx, job_id, query.depth_limit, || (query.invoke_provider_fn)(tcx, key));
|
||||
let value = start_query(job_id, query.depth_limit, || (query.invoke_provider_fn)(tcx, key));
|
||||
let dep_node_index = tcx.dep_graph.next_virtual_depnode_index();
|
||||
prof_timer.finish_with_query_invocation_id(dep_node_index.into());
|
||||
|
||||
@@ -457,7 +456,7 @@ fn execute_job_incr<'tcx, C: QueryCache>(
|
||||
|
||||
// The diagnostics for this query will be promoted to the current session during
|
||||
// `try_mark_green()`, so we can ignore them here.
|
||||
if let Some(ret) = start_query(tcx, job_id, false, || try {
|
||||
if let Some(ret) = start_query(job_id, false, || try {
|
||||
let (prev_index, dep_node_index) = dep_graph_data.try_mark_green(tcx, dep_node)?;
|
||||
let value = load_from_disk_or_invoke_provider_green(
|
||||
tcx,
|
||||
@@ -476,7 +475,7 @@ fn execute_job_incr<'tcx, C: QueryCache>(
|
||||
|
||||
let prof_timer = tcx.prof.query_provider();
|
||||
|
||||
let (result, dep_node_index) = start_query(tcx, job_id, query.depth_limit, || {
|
||||
let (result, dep_node_index) = start_query(job_id, query.depth_limit, || {
|
||||
if query.anon {
|
||||
// Call the query provider inside an anon task.
|
||||
return dep_graph_data.with_anon_task_inner(tcx, query.dep_kind, || {
|
||||
|
||||
@@ -61,37 +61,31 @@ pub(crate) fn next_job_id<'tcx>(tcx: TyCtxt<'tcx>) -> QueryJobId {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn current_query_job<'tcx>(tcx: TyCtxt<'tcx>) -> Option<QueryJobId> {
|
||||
tls::with_related_context(tcx, |icx| icx.query)
|
||||
pub(crate) fn current_query_job() -> Option<QueryJobId> {
|
||||
tls::with_context(|icx| icx.query)
|
||||
}
|
||||
|
||||
/// Executes a job by changing the `ImplicitCtxt` to point to the
|
||||
/// new query job while it executes.
|
||||
/// Executes a job by changing the `ImplicitCtxt` to point to the new query job while it executes.
|
||||
#[inline(always)]
|
||||
pub(crate) fn start_query<'tcx, R>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
token: QueryJobId,
|
||||
pub(crate) fn start_query<R>(
|
||||
job_id: QueryJobId,
|
||||
depth_limit: bool,
|
||||
compute: impl FnOnce() -> R,
|
||||
) -> R {
|
||||
// The `TyCtxt` stored in TLS has the same global interner lifetime
|
||||
// as `self`, so we use `with_related_context` to relate the 'tcx lifetimes
|
||||
// when accessing the `ImplicitCtxt`.
|
||||
tls::with_related_context(tcx, move |current_icx| {
|
||||
if depth_limit && !tcx.recursion_limit().value_within_limit(current_icx.query_depth) {
|
||||
depth_limit_error(tcx, token);
|
||||
tls::with_context(move |icx| {
|
||||
if depth_limit && !icx.tcx.recursion_limit().value_within_limit(icx.query_depth) {
|
||||
depth_limit_error(icx.tcx, job_id);
|
||||
}
|
||||
|
||||
// Update the `ImplicitCtxt` to point to our new query job.
|
||||
let new_icx = ImplicitCtxt {
|
||||
tcx,
|
||||
query: Some(token),
|
||||
query_depth: current_icx.query_depth + depth_limit as usize,
|
||||
task_deps: current_icx.task_deps,
|
||||
let icx = ImplicitCtxt {
|
||||
query: Some(job_id),
|
||||
query_depth: icx.query_depth + if depth_limit { 1 } else { 0 },
|
||||
..icx.clone()
|
||||
};
|
||||
|
||||
// Use the `ImplicitCtxt` while we execute the query.
|
||||
tls::enter_context(&new_icx, compute)
|
||||
tls::enter_context(&icx, compute)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user