&self,
token: QueryJobId<Self::DepKind>,
diagnostics: Option<&Lock<ThinVec<Diagnostic>>>,
+ read_allowed: 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(**self, move |current_icx| {
+ let mut old_read_allowed = false;
+ if let Some(task_deps) = current_icx.task_deps {
+ old_read_allowed = std::mem::replace(&mut task_deps.lock().read_allowed, read_allowed);
+ }
// Update the `ImplicitCtxt` to point to our new query job.
let new_icx = ImplicitCtxt {
tcx: **self,
};
// Use the `ImplicitCtxt` while we execute the query.
- tls::enter_context(&new_icx, |_| {
+ let res = tls::enter_context(&new_icx, |_| {
rustc_data_structures::stack::ensure_sufficient_stack(compute)
- })
+ });
+
+ if let Some(task_deps) = new_icx.task_deps {
+ task_deps.lock().read_allowed = old_read_allowed;
+ }
+ res
})
}
}
reads: SmallVec::new(),
read_set: Default::default(),
phantom_data: PhantomData,
+ read_allowed: true,
}))
};
let result = K::with_deps(task_deps.as_ref(), || task(cx, arg));
if let Some(task_deps) = task_deps {
let mut task_deps = task_deps.lock();
let task_deps = &mut *task_deps;
+
+ if !task_deps.read_allowed {
+ panic!("Illegal read of: {:?}", dep_node_index);
+ }
+
if cfg!(debug_assertions) {
data.current.total_read_count.fetch_add(1, Relaxed);
}
reads: EdgesVec,
read_set: FxHashSet<DepNodeIndex>,
phantom_data: PhantomData<DepNode<K>>,
+ pub read_allowed: bool,
}
impl<K> Default for TaskDeps<K> {
reads: EdgesVec::new(),
read_set: FxHashSet::default(),
phantom_data: PhantomData,
+ read_allowed: true,
}
}
}
&self,
token: QueryJobId<Self::DepKind>,
diagnostics: Option<&Lock<ThinVec<Diagnostic>>>,
+ read_allowed: bool,
compute: impl FnOnce() -> R,
) -> R;
}
// Fast path for when incr. comp. is off.
if !dep_graph.is_fully_enabled() {
let prof_timer = tcx.dep_context().profiler().query_provider();
- let result = tcx.start_query(job_id, None, || query.compute(*tcx.dep_context(), key));
+ let result = tcx.start_query(job_id, None, true, || query.compute(*tcx.dep_context(), key));
let dep_node_index = dep_graph.next_virtual_depnode_index();
prof_timer.finish_with_query_invocation_id(dep_node_index.into());
return (result, dep_node_index);
// 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) = tcx.start_query(job_id, None, || {
+ if let Some(ret) = tcx.start_query(job_id, None, false, || {
try_load_from_disk_and_cache_in_memory(tcx, &key, &dep_node, query)
}) {
return ret;
let prof_timer = tcx.dep_context().profiler().query_provider();
let diagnostics = Lock::new(ThinVec::new());
- let (result, dep_node_index) = tcx.start_query(job_id, Some(&diagnostics), || {
+ let (result, dep_node_index) = tcx.start_query(job_id, Some(&diagnostics), true, || {
if query.anon {
return dep_graph.with_anon_task(*tcx.dep_context(), query.dep_kind, || {
query.compute(*tcx.dep_context(), key)