remove the horrible dyn_descriptor and generate an enum

This commit is contained in:
Niko Matsakis 2018-09-29 06:01:44 -04:00
parent d6821d1097
commit c85edccc1e
2 changed files with 28 additions and 54 deletions

View file

@ -1,46 +0,0 @@
use crate::Query;
use crate::QueryContext;
use crate::QueryTable;
use rustc_hash::FxHashMap;
use std::any::{Any, TypeId};
use std::cell::RefCell;
use std::collections::hash_map::Entry;
use std::fmt::Debug;
use std::fmt::Display;
use std::fmt::Write;
use std::hash::Hash;
// Total hack for now: assume that the Debug string
// for the key, combined with the type-id of the query,
// is sufficient for an equality comparison.
/// A simple-to-use query descriptor that is meant only for dumping
/// out cycle stack errors and not for any real recovery; also, not
/// especially efficient.
#[derive(PartialEq, Eq)]
pub struct DynDescriptor {
type_id: TypeId,
debug_string: String,
}
impl DynDescriptor {
pub fn from_key<QC, Q>(_query: &QC, key: &Q::Key) -> DynDescriptor
where
QC: QueryContext,
Q: Query<QC>,
{
let type_id = TypeId::of::<Q>();
let query = Q::default();
let debug_string = format!("Query `{:?}` applied to `{:?}`", query, key);
DynDescriptor {
type_id,
debug_string,
}
}
}
impl std::fmt::Debug for DynDescriptor {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(fmt, "{}", self.debug_string)
}
}

View file

@ -19,7 +19,6 @@ use std::fmt::Display;
use std::fmt::Write; use std::fmt::Write;
use std::hash::Hash; use std::hash::Hash;
pub mod dyn_descriptor;
pub mod memoized; pub mod memoized;
pub mod runtime; pub mod runtime;
pub mod transparent; pub mod transparent;
@ -48,7 +47,7 @@ pub trait QueryContextStorageTypes {
/// At runtime, it can be implemented in various ways: a monster enum /// At runtime, it can be implemented in various ways: a monster enum
/// works for a fixed set of queries, but a boxed trait object is good /// works for a fixed set of queries, but a boxed trait object is good
/// for a more open-ended option. /// for a more open-ended option.
type QueryDescriptor: Debug + Eq; type QueryDescriptor: Debug + Eq + Hash;
/// Defines the "storage type", where all the query data is kept. /// Defines the "storage type", where all the query data is kept.
/// This type is defined by the `query_context_storage` macro. /// This type is defined by the `query_context_storage` macro.
@ -331,7 +330,6 @@ macro_rules! query_context_storage {
)* )*
} }
) => { ) => {
#[allow(non_snake_case)]
#[derive(Default)] #[derive(Default)]
$(#[$attr])* $(#[$attr])*
$v struct $Storage { $v struct $Storage {
@ -342,8 +340,28 @@ macro_rules! query_context_storage {
)* )*
} }
/// Identifies a query and its key. You are not meant to name
/// this type directly or use its fields etc. It is a
/// **private query descriptor type generated by salsa** and
/// its exact structure is subject to change. Sadly, I don't
/// know any way to hide this with hygiene, so use `__`
/// instead.
#[derive(Debug, PartialEq, Eq, Hash)]
$v struct __SalsaQueryDescriptor {
kind: __SalsaQueryDescriptorKind
}
#[derive(Debug, PartialEq, Eq, Hash)]
enum __SalsaQueryDescriptorKind {
$(
$(
$query_method(<$QueryType as $crate::Query<$QueryContext>>::Key),
)*
)*
}
impl $crate::QueryContextStorageTypes for $QueryContext { impl $crate::QueryContextStorageTypes for $QueryContext {
type QueryDescriptor = $crate::dyn_descriptor::DynDescriptor; type QueryDescriptor = __SalsaQueryDescriptor;
type QueryStorage = $Storage; type QueryStorage = $Storage;
} }
@ -356,10 +374,12 @@ macro_rules! query_context_storage {
$crate::QueryTable::new( $crate::QueryTable::new(
self, self,
&$crate::QueryContext::salsa_storage(self).$query_method, &$crate::QueryContext::salsa_storage(self).$query_method,
$crate::dyn_descriptor::DynDescriptor::from_key::< |_, key| {
Self, let key = std::clone::Clone::clone(key);
$QueryType, __SalsaQueryDescriptor {
>, kind: __SalsaQueryDescriptorKind::$query_method(key),
}
},
) )
} }
)* )*