diff --git a/compiler/rustc_interface/src/callbacks.rs b/compiler/rustc_interface/src/callbacks.rs index 4a1da0f50cc23..e85f530588311 100644 --- a/compiler/rustc_interface/src/callbacks.rs +++ b/compiler/rustc_interface/src/callbacks.rs @@ -42,7 +42,7 @@ fn track_diagnostic(diagnostic: DiagInner, f: &mut dyn FnMut(DiagInner) -> R) icx.tcx.dep_graph.record_diagnostic(icx.tcx, &diagnostic); // Diagnostics are tracked, we can ignore the dependency. - let icx = tls::ImplicitCtxt { task_deps: TaskDepsRef::Ignore, ..icx.clone() }; + let icx = tls::ImplicitCtxt { task_deps: TaskDepsRef::Ignore, ..*icx }; tls::enter_context(&icx, move || (*f)(diagnostic)) } else { // In any other case, invoke diagnostics anyway. diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs index 1bd9a1692db08..9787a998d6371 100644 --- a/compiler/rustc_middle/src/dep_graph/mod.rs +++ b/compiler/rustc_middle/src/dep_graph/mod.rs @@ -63,7 +63,7 @@ where OP: FnOnce() -> R, { ty::tls::with_context(|icx| { - let icx = ty::tls::ImplicitCtxt { task_deps, ..icx.clone() }; + let icx = ty::tls::ImplicitCtxt { task_deps, ..*icx }; ty::tls::enter_context(&icx, op) }) } diff --git a/compiler/rustc_middle/src/ty/context/tls.rs b/compiler/rustc_middle/src/ty/context/tls.rs index d37ad56c2e83d..d1561c37172c3 100644 --- a/compiler/rustc_middle/src/ty/context/tls.rs +++ b/compiler/rustc_middle/src/ty/context/tls.rs @@ -1,5 +1,3 @@ -use std::{mem, ptr}; - use rustc_data_structures::sync; use super::{GlobalCtxt, TyCtxt}; @@ -11,7 +9,6 @@ use crate::query::QueryJobId; /// executing a new query. Whenever there's a `TyCtxt` value available /// you should also have access to an `ImplicitCtxt` through the functions /// in this module. -#[derive(Clone)] pub struct ImplicitCtxt<'a, 'tcx> { /// The current `TyCtxt`. pub tcx: TyCtxt<'tcx>, @@ -89,29 +86,6 @@ where 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] diff --git a/compiler/rustc_query_impl/src/execution.rs b/compiler/rustc_query_impl/src/execution.rs index 323d40fdbaabb..18e3f045cea43 100644 --- a/compiler/rustc_query_impl/src/execution.rs +++ b/compiler/rustc_query_impl/src/execution.rs @@ -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, || { diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 425ca28910073..f9b75359c7ceb 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -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 { - tls::with_related_context(tcx, |icx| icx.query) +pub(crate) fn current_query_job() -> Option { + 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( + 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 }; // Use the `ImplicitCtxt` while we execute the query. - tls::enter_context(&new_icx, compute) + tls::enter_context(&icx, compute) }) }