Skip to content

Commit 9b520e8

Browse files
committed
Expose constraints
1 parent 36fb31c commit 9b520e8

File tree

5 files changed

+81
-38
lines changed

5 files changed

+81
-38
lines changed

macros/src/track.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -200,23 +200,23 @@ fn create(
200200
#(#variants,)*
201201
}
202202

203-
impl ::comemo::Track for #ty {}
203+
impl ::comemo::Track for #ty {
204+
#[inline]
205+
fn valid(&self, constraint: &::comemo::Constraint<Self>) -> bool {
206+
let mut this = #maybe_cloned;
207+
constraint.valid(|call| match &call.0 { #(#validations,)* })
208+
}
209+
}
204210

205211
#[doc(hidden)]
206212
impl ::comemo::internal::Trackable for #ty {
207213
type Call = __ComemoCall;
208214
type Surface = __ComemoSurfaceFamily;
209215
type SurfaceMut = __ComemoSurfaceMutFamily;
210216

211-
#[inline]
212-
fn valid(&self, constraint: &::comemo::internal::Constraint<Self::Call>) -> bool {
213-
let mut this = #maybe_cloned;
214-
constraint.valid(|call| match &call.0 { #(#validations,)* })
215-
}
216-
217217
#[inline]
218218
#[allow(unused_variables)]
219-
fn replay(&mut self, constraint: &::comemo::internal::Constraint<Self::Call>) {
219+
fn replay(&mut self, constraint: &::comemo::Constraint<Self>) {
220220
constraint.replay(|call| match &call.0 { #(#replays,)* });
221221
}
222222

src/constraint.rs

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,14 @@ use std::hash::Hash;
33

44
use siphasher::sip128::{Hasher128, SipHasher};
55

6+
use crate::track::Trackable;
7+
68
/// Defines a constraint for a tracked method without arguments.
7-
pub struct Constraint<Call> {
8-
calls: RefCell<Vec<Entry<Call>>>,
9+
pub struct Constraint<T>
10+
where
11+
T: Trackable + ?Sized,
12+
{
13+
calls: RefCell<Vec<Entry<T::Call>>>,
914
}
1015

1116
/// A call entry.
@@ -15,13 +20,21 @@ struct Entry<Call> {
1520
mutable: bool,
1621
}
1722

18-
impl<Call> Constraint<Call>
23+
impl<T> Constraint<T>
1924
where
20-
Call: Clone + PartialEq,
25+
T: Trackable + ?Sized,
2126
{
27+
/// Create empty constraints.
28+
pub fn new() -> Self {
29+
Self::default()
30+
}
31+
2232
/// Enter a constraint for a call to an immutable function.
33+
///
34+
/// This method is not part of the public API!
2335
#[inline]
24-
pub fn push(&self, call: Call, hash: u128, mutable: bool) {
36+
#[doc(hidden)]
37+
pub fn push(&self, call: T::Call, hash: u128, mutable: bool) {
2538
let mut calls = self.calls.borrow_mut();
2639

2740
if !mutable {
@@ -41,19 +54,25 @@ where
4154
}
4255

4356
/// Whether the method satisfies as all input-output pairs.
57+
///
58+
/// This method is not part of the public API!
4459
#[inline]
60+
#[doc(hidden)]
4561
pub fn valid<F>(&self, mut f: F) -> bool
4662
where
47-
F: FnMut(&Call) -> u128,
63+
F: FnMut(&T::Call) -> u128,
4864
{
4965
self.calls.borrow().iter().all(|entry| f(&entry.call) == entry.hash)
5066
}
5167

5268
/// Replay all input-output pairs.
69+
///
70+
/// This method is not part of the public API!
5371
#[inline]
72+
#[doc(hidden)]
5473
pub fn replay<F>(&self, mut f: F)
5574
where
56-
F: FnMut(&Call),
75+
F: FnMut(&T::Call),
5776
{
5877
for entry in self.calls.borrow().iter() {
5978
if entry.mutable {
@@ -63,9 +82,9 @@ where
6382
}
6483
}
6584

66-
impl<Call> Default for Constraint<Call>
85+
impl<T> Default for Constraint<T>
6786
where
68-
Call: Clone + PartialEq,
87+
T: Trackable + ?Sized,
6988
{
7089
fn default() -> Self {
7190
Self { calls: RefCell::new(vec![]) }
@@ -87,9 +106,9 @@ impl<T: Join> Join<T> for Option<&T> {
87106
}
88107
}
89108

90-
impl<Call> Join for Constraint<Call>
109+
impl<T> Join for Constraint<T>
91110
where
92-
Call: Clone + PartialEq,
111+
T: Trackable + ?Sized,
93112
{
94113
#[inline]
95114
fn join(&self, inner: &Self) {

src/input.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::marker::PhantomData;
33

44
use crate::constraint::{Constraint, Join};
55
use crate::internal::Family;
6-
use crate::track::{Track, Trackable, Tracked, TrackedMut};
6+
use crate::track::{Track, Tracked, TrackedMut};
77

88
/// Ensure a type is suitable as input.
99
#[inline]
@@ -85,16 +85,16 @@ where
8585
T: Track + ?Sized,
8686
{
8787
// Forward constraint from `Trackable` implementation.
88-
type Constraint = Constraint<T::Call>;
88+
type Constraint = Constraint<T>;
8989
type Tracked = TrackedFamily<T>;
90-
type Outer = Option<&'a Constraint<T::Call>>;
90+
type Outer = Option<&'a Constraint<T>>;
9191

9292
#[inline]
9393
fn key<H: Hasher>(&self, _: &mut H) {}
9494

9595
#[inline]
9696
fn valid(&self, constraint: &Self::Constraint) -> bool {
97-
Trackable::valid(self.value, constraint)
97+
self.value.valid(constraint)
9898
}
9999

100100
#[inline]
@@ -104,7 +104,7 @@ where
104104
fn retrack<'r>(
105105
self,
106106
constraint: &'r Self::Constraint,
107-
) -> (Tracked<'r, T>, Option<&'a Constraint<T::Call>>)
107+
) -> (Tracked<'r, T>, Option<&'a Constraint<T>>)
108108
where
109109
Self: 'r,
110110
{
@@ -131,16 +131,16 @@ where
131131
T: Track + ?Sized,
132132
{
133133
// Forward constraint from `Trackable` implementation.
134-
type Constraint = Constraint<T::Call>;
134+
type Constraint = Constraint<T>;
135135
type Tracked = TrackedMutFamily<T>;
136-
type Outer = Option<&'a Constraint<T::Call>>;
136+
type Outer = Option<&'a Constraint<T>>;
137137

138138
#[inline]
139139
fn key<H: Hasher>(&self, _: &mut H) {}
140140

141141
#[inline]
142142
fn valid(&self, constraint: &Self::Constraint) -> bool {
143-
Trackable::valid(self.value, constraint)
143+
self.value.valid(constraint)
144144
}
145145

146146
#[inline]
@@ -152,7 +152,7 @@ where
152152
fn retrack<'r>(
153153
self,
154154
constraint: &'r Self::Constraint,
155-
) -> (TrackedMut<'r, T>, Option<&'a Constraint<T::Call>>)
155+
) -> (TrackedMut<'r, T>, Option<&'a Constraint<T>>)
156156
where
157157
Self: 'r,
158158
{

src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ mod prehashed;
8989
mod track;
9090

9191
pub use crate::cache::evict;
92+
pub use crate::constraint::Constraint;
9293
pub use crate::prehashed::Prehashed;
9394
pub use crate::track::{Track, Tracked, TrackedMut};
9495
pub use comemo_macros::{memoize, track};
@@ -97,7 +98,7 @@ pub use comemo_macros::{memoize, track};
9798
#[doc(hidden)]
9899
pub mod internal {
99100
pub use crate::cache::{last_was_hit, memoized};
100-
pub use crate::constraint::{hash, Constraint};
101+
pub use crate::constraint::hash;
101102
pub use crate::input::{assert_hashable_or_trackable, Args};
102103
pub use crate::track::{to_parts_mut_mut, to_parts_mut_ref, to_parts_ref, Trackable};
103104

src/track.rs

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,32 @@ pub trait Track: Trackable {
2121
fn track_mut(&mut self) -> TrackedMut<Self> {
2222
TrackedMut { value: self, constraint: None }
2323
}
24+
25+
/// Start tracking all accesses into a constraint.
26+
#[inline]
27+
fn track_with<'a>(&'a self, constraint: &'a Constraint<Self>) -> Tracked<'a, Self> {
28+
Tracked {
29+
value: self,
30+
constraint: Some(constraint),
31+
}
32+
}
33+
34+
/// Start tracking all accesses and mutations into a constraint.
35+
#[inline]
36+
fn track_mut_with<'a>(
37+
&'a mut self,
38+
constraint: &'a Constraint<Self>,
39+
) -> TrackedMut<'a, Self> {
40+
TrackedMut {
41+
value: self,
42+
constraint: Some(constraint),
43+
}
44+
}
45+
46+
/// Whether this value fulfills the given constraints.
47+
///
48+
/// Such constraints can be generated with `track_with` or `track_mut_with`.
49+
fn valid(&self, constraint: &Constraint<Self>) -> bool;
2450
}
2551

2652
/// Non-exposed parts of the `Track` trait.
@@ -34,11 +60,8 @@ pub trait Trackable: 'static {
3460
/// The mutable tracked API surface of this type.
3561
type SurfaceMut: for<'a> Family<'a>;
3662

37-
/// Whether an instance fulfills the given constraint.
38-
fn valid(&self, constraint: &Constraint<Self::Call>) -> bool;
39-
4063
/// Replay mutations to the value.
41-
fn replay(&mut self, constraint: &Constraint<Self::Call>);
64+
fn replay(&mut self, constraint: &Constraint<Self>);
4265

4366
/// Access the immutable surface from a `Tracked`.
4467
fn surface_ref<'a, 't>(
@@ -79,7 +102,7 @@ where
79102
///
80103
/// Starts out as `None` and is set to a stack-stored constraint in the
81104
/// preamble of memoized functions.
82-
pub(crate) constraint: Option<&'a Constraint<T::Call>>,
105+
pub(crate) constraint: Option<&'a Constraint<T>>,
83106
}
84107

85108
// The type `Tracked<T>` automatically dereferences to T's generated surface
@@ -136,7 +159,7 @@ where
136159
///
137160
/// Starts out as `None` and is set to a stack-stored constraint in the
138161
/// preamble of memoized functions.
139-
pub(crate) constraint: Option<&'a Constraint<T::Call>>,
162+
pub(crate) constraint: Option<&'a Constraint<T>>,
140163
}
141164

142165
impl<'a, T> TrackedMut<'a, T>
@@ -214,7 +237,7 @@ where
214237

215238
/// Destructure a `Tracked<_>` into its parts.
216239
#[inline]
217-
pub fn to_parts_ref<T>(tracked: Tracked<T>) -> (&T, Option<&Constraint<T::Call>>)
240+
pub fn to_parts_ref<T>(tracked: Tracked<T>) -> (&T, Option<&Constraint<T>>)
218241
where
219242
T: Track + ?Sized,
220243
{
@@ -225,7 +248,7 @@ where
225248
#[inline]
226249
pub fn to_parts_mut_ref<'a, T>(
227250
tracked: &'a TrackedMut<T>,
228-
) -> (&'a T, Option<&'a Constraint<T::Call>>)
251+
) -> (&'a T, Option<&'a Constraint<T>>)
229252
where
230253
T: Track + ?Sized,
231254
{
@@ -236,7 +259,7 @@ where
236259
#[inline]
237260
pub fn to_parts_mut_mut<'a, T>(
238261
tracked: &'a mut TrackedMut<T>,
239-
) -> (&'a mut T, Option<&'a Constraint<T::Call>>)
262+
) -> (&'a mut T, Option<&'a Constraint<T>>)
240263
where
241264
T: Track + ?Sized,
242265
{

0 commit comments

Comments
 (0)