From abb4345c08071757ad5094a28f0c2ee024fbbf04 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 28 Sep 2018 13:53:15 -0400 Subject: [PATCH] add a bunch of comments, some new bounds --- src/lib.rs | 58 +++++++++++++++++++++++++++++++++++++++----------- src/storage.rs | 12 ++++++++++- 2 files changed, 56 insertions(+), 14 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ae016481..d5f4ae56 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -46,8 +46,8 @@ pub trait BaseQueryContext: Sized { } pub trait Query: Debug + Default + Sized + 'static { - type Key: Clone + Debug + Hash + Eq; - type Value: Clone + Debug + Hash + Eq; + type Key: Clone + Debug + Hash + Eq + Send; + type Value: Clone + Debug + Hash + Eq + Send; type Storage: QueryStorageOps; fn execute(query: &QC, key: Self::Key) -> Self::Value; @@ -77,12 +77,6 @@ where pub descriptor_fn: fn(&QC, &Q::Key) -> QC::QueryDescriptor, } -#[derive(Debug)] -pub enum QueryState { - InProgress, - Memoized(V), -} - pub struct CycleDetected; impl QueryTable<'me, QC, Q> @@ -103,16 +97,38 @@ where } } -/// A macro helper for writing the query contexts in traits that helps -/// you avoid repeating information. +/// A macro that helps in defining the "context trait" of a given +/// module. This is a trait that defines everything that a block of +/// queries need to execute, as well as defining the queries +/// themselves that are exported for others to use. +/// +/// This macro declares the "prototype" for a single query. This will +/// expand into a `fn` item. This prototype specifies name of the +/// method (in the example below, that would be `my_query`) and +/// connects it to query definition type (`MyQuery`, in the example +/// below). These typically have the same name but a distinct +/// capitalization convention. Note that the actual input/output type +/// of the query are given only in the query definition (see the +/// `query_definition` macro for more details). /// /// Example: /// /// ```ignore /// trait TypeckQueryContext { -/// query_prototype!(fn () for ); +/// query_prototype! { +/// /// Comments or other attributes can go here +/// fn my_query() for MyQuery +/// } /// } /// ``` +/// +/// This just expands to something like: +/// +/// ```ignore +/// fn my_query(&self) -> QueryTable<'_, Self, $query_type>; +/// ``` +/// +/// This permits us to invoke the query via `query.my_query().of(key)`. #[macro_export] macro_rules! query_prototype { ( @@ -124,15 +140,31 @@ macro_rules! query_prototype { } } +/// Creates a **Query Definition** type. This defines the input (key) +/// of the query, the output key (value), and the query context trait +/// that the query requires. +/// /// Example: /// /// ```ignore /// query_definition! { -/// QueryName(query: &impl TypeckQueryContext, key: DefId) -> Arc> { -/// ... +/// pub MyQuery(query: &impl MyQueryContext, key: MyKey) -> MyValue { +/// ... // fn body specifies what happens when query is invoked /// } /// } /// ``` +/// +/// Here, the query context trait would be `MyQueryContext` -- this +/// should be a trait containing all the other queries that the +/// definition needs to invoke (as well as any other methods that you +/// may want). +/// +/// The `MyKey` type is the **key** to the query -- it must be Clone, +/// Debug, Hash, Eq, and Send, as specified in the `Query` trait. +/// +/// The `MyKey` type is the **value** to the query -- it too must be +/// Clone, Debug, Hash, Eq, and Send, as specified in the `Query` +/// trait. #[macro_export] macro_rules! query_definition { ( diff --git a/src/storage.rs b/src/storage.rs index 8aa15054..0b85f307 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -1,7 +1,6 @@ use crate::BaseQueryContext; use crate::CycleDetected; use crate::Query; -use crate::QueryState; use crate::QueryStorageOps; use crate::QueryTable; use rustc_hash::FxHashMap; @@ -25,6 +24,17 @@ where map: RefCell>>, } +/// Defines the "current state" of query's memoized results. +#[derive(Debug)] +pub enum QueryState { + /// We are currently computing the result of this query; if we see + /// this value in the table, it indeeds a cycle. + InProgress, + + /// We have computed the query already, and here is the result. + Memoized(V), +} + impl Default for MemoizedStorage where Q: Query,