Don't rely on Debug impl for Erased

This commit is contained in:
John Kåre Alsaker 2023-03-26 11:00:26 +02:00
parent 785459d630
commit 36b4199a8e
7 changed files with 33 additions and 23 deletions

View File

@ -1,21 +1,12 @@
use crate::ty;
use std::intrinsics::type_name;
use std::{
fmt,
mem::{size_of, transmute_copy, MaybeUninit},
};
use std::mem::{size_of, transmute_copy, MaybeUninit};
#[derive(Copy, Clone)]
pub struct Erased<T: Copy> {
data: MaybeUninit<T>,
}
impl<T: Copy> fmt::Debug for Erased<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Erased")
}
}
pub trait EraseType: Copy {
type Result: Copy;
}

View File

@ -501,6 +501,7 @@ macro_rules! define_feedable {
match try_get_cached(tcx, cache, &key) {
Some(old) => {
let old = restore::<$V>(old);
bug!(
"Trying to feed an already recorded value for query {} key={key:?}:\nold value: {old:?}\nnew value: {value:?}",
stringify!($name),

View File

@ -486,6 +486,11 @@ macro_rules! define_queries {
stringify!($name)
}
#[inline]
fn format_value(self) -> fn(&Self::Value) -> String {
|value| format!("{:?}", restore::<query_values::$name<'tcx>>(*value))
}
#[inline]
fn cache_on_disk(self, tcx: TyCtxt<'tcx>, key: &Self::Key) -> bool {
::rustc_middle::query::cached::$name(tcx, key)
@ -819,7 +824,7 @@ macro_rules! define_queries_struct {
$($(#[$attr])*
#[inline(always)]
#[tracing::instrument(level = "trace", skip(self, tcx), ret)]
#[tracing::instrument(level = "trace", skip(self, tcx))]
fn $name(
&'tcx self,
tcx: TyCtxt<'tcx>,

View File

@ -538,7 +538,14 @@ impl<K: DepKind> DepGraph<K> {
if let Some(prev_index) = data.previous.node_to_index_opt(&node) {
let dep_node_index = data.current.prev_index_to_index.lock()[prev_index];
if let Some(dep_node_index) = dep_node_index {
crate::query::incremental_verify_ich(cx, data, result, prev_index, hash_result);
crate::query::incremental_verify_ich(
cx,
data,
result,
prev_index,
hash_result,
|value| format!("{:?}", value),
);
#[cfg(debug_assertions)]
if hash_result.is_some() {

View File

@ -18,7 +18,7 @@ pub trait CacheSelector<'tcx, V> {
pub trait QueryCache: Sized {
type Key: Hash + Eq + Copy + Debug;
type Value: Copy + Debug;
type Value: Copy;
/// Checks if the query is already computed and in the cache.
fn lookup(&self, key: &Self::Key) -> Option<(Self::Value, DepNodeIndex)>;
@ -52,7 +52,7 @@ impl<K, V> Default for DefaultCache<K, V> {
impl<K, V> QueryCache for DefaultCache<K, V>
where
K: Eq + Hash + Copy + Debug,
V: Copy + Debug,
V: Copy,
{
type Key = K;
type Value = V;
@ -120,7 +120,7 @@ impl<V> Default for SingleCache<V> {
impl<V> QueryCache for SingleCache<V>
where
V: Copy + Debug,
V: Copy,
{
type Key = ();
type Value = V;
@ -164,7 +164,7 @@ impl<K: Idx, V> Default for VecCache<K, V> {
impl<K, V> QueryCache for VecCache<K, V>
where
K: Eq + Idx + Copy + Debug,
V: Copy + Debug,
V: Copy,
{
type Key = K;
type Value = V;

View File

@ -20,10 +20,12 @@ pub trait QueryConfig<Qcx: QueryContext>: Copy {
// `Key` and `Value` are `Copy` instead of `Clone` to ensure copying them stays cheap,
// but it isn't necessary.
type Key: DepNodeParams<Qcx::DepContext> + Eq + Hash + Copy + Debug;
type Value: Debug + Copy;
type Value: Copy;
type Cache: QueryCache<Key = Self::Key, Value = Self::Value>;
fn format_value(self) -> fn(&Self::Value) -> String;
// Don't use this method to access query results, instead use the methods on TyCtxt
fn query_state<'a>(self, tcx: Qcx) -> &'a QueryState<Self::Key, Qcx::DepKind>
where

View File

@ -411,7 +411,8 @@ where
// get evaluated first, and re-feed the query.
if let Some((cached_result, _)) = cache.lookup(&key) {
panic!(
"fed query later has its value computed. The already cached value: {cached_result:?}"
"fed query later has its value computed. The already cached value: {}",
(query.format_value())(&cached_result)
);
}
}
@ -582,6 +583,7 @@ where
&result,
prev_dep_node_index,
query.hash_result(),
query.format_value(),
);
}
@ -627,19 +629,21 @@ where
&result,
prev_dep_node_index,
query.hash_result(),
query.format_value(),
);
Some((result, dep_node_index))
}
#[inline]
#[instrument(skip(tcx, dep_graph_data, result, hash_result), level = "debug")]
pub(crate) fn incremental_verify_ich<Tcx, V: Debug>(
#[instrument(skip(tcx, dep_graph_data, result, hash_result, format_value), level = "debug")]
pub(crate) fn incremental_verify_ich<Tcx, V>(
tcx: Tcx,
dep_graph_data: &DepGraphData<Tcx::DepKind>,
result: &V,
prev_index: SerializedDepNodeIndex,
hash_result: Option<fn(&mut StableHashingContext<'_>, &V) -> Fingerprint>,
format_value: fn(&V) -> String,
) where
Tcx: DepContext,
{
@ -654,7 +658,7 @@ pub(crate) fn incremental_verify_ich<Tcx, V: Debug>(
let old_hash = dep_graph_data.prev_fingerprint_of(prev_index);
if new_hash != old_hash {
incremental_verify_ich_failed(tcx, prev_index, result);
incremental_verify_ich_failed(tcx, prev_index, &|| format_value(&result));
}
}
@ -678,7 +682,7 @@ where
fn incremental_verify_ich_failed<Tcx>(
tcx: Tcx,
prev_index: SerializedDepNodeIndex,
result: &dyn Debug,
result: &dyn Fn() -> String,
) where
Tcx: DepContext,
{
@ -708,7 +712,7 @@ fn incremental_verify_ich_failed<Tcx>(
run_cmd,
dep_node: format!("{dep_node:?}"),
});
panic!("Found unstable fingerprints for {dep_node:?}: {result:?}");
panic!("Found unstable fingerprints for {dep_node:?}: {}", result());
}
INSIDE_VERIFY_PANIC.with(|in_panic| in_panic.set(old_in_panic));