Skip to content

Commit 7c8908d

Browse files
committed
add a size method to Visitor
this can be used to force ambiguity
1 parent c98a93a commit 7c8908d

File tree

7 files changed

+122
-12
lines changed

7 files changed

+122
-12
lines changed

crates/formality-macros/src/visit.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ pub(crate) fn derive_visit(mut s: synstructure::Structure) -> TokenStream {
99

1010
let free_variables_body = s.each(|field| quote!(output.extend(Visit::free_variables(#field))));
1111

12+
let size_body = s.each(|field| quote!(__sum += Visit::size(#field)));
13+
1214
// s.add_bounds(synstructure::AddBounds::None);
1315
s.gen_impl(quote! {
1416
use crate::derive_links::{Visit, Variable};
@@ -21,6 +23,15 @@ pub(crate) fn derive_visit(mut s: synstructure::Structure) -> TokenStream {
2123
}
2224
output
2325
}
26+
27+
fn size(&self) -> usize {
28+
let mut __sum = 0;
29+
__sum += 1;
30+
match self {
31+
#size_body
32+
}
33+
__sum
34+
}
2435
}
2536
})
2637
}

crates/formality-prove/src/prove/constraints.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,19 @@ impl Fold for Constraints {
136136

137137
impl Visit for Constraints {
138138
fn free_variables(&self) -> Vec<Variable> {
139-
self.substitution.free_variables()
139+
let Constraints {
140+
known_true: _,
141+
substitution,
142+
} = self;
143+
substitution.free_variables()
144+
}
145+
146+
fn size(&self) -> usize {
147+
let Constraints {
148+
known_true: _,
149+
substitution,
150+
} = self;
151+
substitution.size()
140152
}
141153
}
142154

crates/formality-rust/src/trait_binder.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ where
4848
fn free_variables(&self) -> Vec<formality_types::grammar::Variable> {
4949
self.explicit_binder.free_variables()
5050
}
51+
52+
fn size(&self) -> usize {
53+
self.explicit_binder.size()
54+
}
5155
}
5256

5357
impl<T> Fold for TraitBinder<T>

crates/formality-types/src/grammar/binder.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,10 @@ impl<T: Visit> Visit for Binder<T> {
173173
fn free_variables(&self) -> Vec<Variable> {
174174
self.term.free_variables()
175175
}
176+
177+
fn size(&self) -> usize {
178+
self.term.size()
179+
}
176180
}
177181

178182
impl<T: Fold> Fold for Binder<T> {

crates/formality-types/src/grammar/ids.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ macro_rules! id {
3232
fn free_variables(&self) -> Vec<Variable> {
3333
vec![]
3434
}
35+
36+
fn size(&self) -> usize {
37+
1
38+
}
3539
}
3640

3741
impl Fold for $n {

crates/formality-types/src/grammar/ty.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,10 @@ impl Visit for InferenceVar {
143143
fn free_variables(&self) -> Vec<Variable> {
144144
vec![self.upcast()]
145145
}
146+
147+
fn size(&self) -> usize {
148+
1
149+
}
146150
}
147151

148152
#[term((rigid $name $*parameters))]
@@ -397,6 +401,28 @@ impl UpcastFrom<LtData> for LtData {
397401
}
398402
}
399403

404+
impl Visit for LtData {
405+
fn free_variables(&self) -> Vec<Variable> {
406+
match self {
407+
LtData::Variable(v) => {
408+
if v.is_free() {
409+
vec![v.clone()]
410+
} else {
411+
vec![]
412+
}
413+
}
414+
LtData::Static => vec![],
415+
}
416+
}
417+
418+
fn size(&self) -> usize {
419+
match self {
420+
LtData::Variable(v) => v.size(),
421+
LtData::Static => 1,
422+
}
423+
}
424+
}
425+
400426
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
401427
pub enum Variable {
402428
PlaceholderVar(PlaceholderVar),
@@ -489,6 +515,10 @@ impl Visit for Variable {
489515
vec![]
490516
}
491517
}
518+
519+
fn size(&self) -> usize {
520+
1
521+
}
492522
}
493523

494524
impl UpcastFrom<Variable> for Parameter {
@@ -670,6 +700,10 @@ impl Visit for Substitution {
670700
v.extend(self.domain());
671701
v
672702
}
703+
704+
fn size(&self) -> usize {
705+
self.range().iter().map(|r| r.size()).sum()
706+
}
673707
}
674708

675709
/// A substitution that is only between variables.

crates/formality-types/src/visit.rs

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::sync::Arc;
22

33
use crate::{
44
collections::Set,
5-
grammar::{Lt, LtData, Parameter, Ty, Universe, Variable},
5+
grammar::{Lt, Parameter, Ty, Universe, Variable},
66
};
77

88
/// Invoked for each variable that we find when Visiting, ignoring variables bound by binders
@@ -17,6 +17,10 @@ pub trait Visit: Sized {
1717
/// The list may contain duplicates and must be in a determinstic order (though the order itself isn't important).
1818
fn free_variables(&self) -> Vec<Variable>;
1919

20+
/// Measures the overall size of the term by counting constructors etc.
21+
/// Used to determine overflow.
22+
fn size(&self) -> usize;
23+
2024
/// True if this term references only placeholder variables.
2125
/// This means that it contains no inference variables.
2226
/// If this is a goal, then when we prove it true, we don't expect any substitution.
@@ -49,57 +53,80 @@ impl<T: Visit> Visit for Vec<T> {
4953
fn free_variables(&self) -> Vec<Variable> {
5054
self.iter().flat_map(|e| e.free_variables()).collect()
5155
}
56+
57+
fn size(&self) -> usize {
58+
self.iter().map(|e| e.size()).sum()
59+
}
5260
}
5361

5462
impl<T: Visit + Ord> Visit for Set<T> {
5563
fn free_variables(&self) -> Vec<Variable> {
5664
self.iter().flat_map(|e| e.free_variables()).collect()
5765
}
66+
67+
fn size(&self) -> usize {
68+
self.iter().map(|e| e.size()).sum()
69+
}
5870
}
5971

6072
impl<T: Visit> Visit for Option<T> {
6173
fn free_variables(&self) -> Vec<Variable> {
6274
self.iter().flat_map(|e| e.free_variables()).collect()
6375
}
76+
77+
fn size(&self) -> usize {
78+
self.as_ref().map(|e| e.size()).unwrap_or(0)
79+
}
6480
}
6581

6682
impl<T: Visit> Visit for Arc<T> {
6783
fn free_variables(&self) -> Vec<Variable> {
6884
T::free_variables(self)
6985
}
86+
87+
fn size(&self) -> usize {
88+
T::size(self)
89+
}
7090
}
7191

7292
impl Visit for Ty {
7393
fn free_variables(&self) -> Vec<Variable> {
7494
self.data().free_variables()
7595
}
96+
97+
fn size(&self) -> usize {
98+
self.data().size()
99+
}
76100
}
77101

78102
impl Visit for Lt {
79103
fn free_variables(&self) -> Vec<Variable> {
80-
match self.data() {
81-
LtData::Variable(v) => {
82-
if v.is_free() {
83-
vec![v.clone()]
84-
} else {
85-
vec![]
86-
}
87-
}
88-
LtData::Static => vec![],
89-
}
104+
self.data().free_variables()
105+
}
106+
107+
fn size(&self) -> usize {
108+
self.data().size()
90109
}
91110
}
92111

93112
impl Visit for usize {
94113
fn free_variables(&self) -> Vec<Variable> {
95114
vec![]
96115
}
116+
117+
fn size(&self) -> usize {
118+
1
119+
}
97120
}
98121

99122
impl Visit for u32 {
100123
fn free_variables(&self) -> Vec<Variable> {
101124
vec![]
102125
}
126+
127+
fn size(&self) -> usize {
128+
1
129+
}
103130
}
104131

105132
impl<A: Visit, B: Visit> Visit for (A, B) {
@@ -110,6 +137,11 @@ impl<A: Visit, B: Visit> Visit for (A, B) {
110137
fv.extend(b.free_variables());
111138
fv
112139
}
140+
141+
fn size(&self) -> usize {
142+
let (a, b) = self;
143+
a.size() + b.size()
144+
}
113145
}
114146

115147
impl<A: Visit, B: Visit, C: Visit> Visit for (A, B, C) {
@@ -121,10 +153,19 @@ impl<A: Visit, B: Visit, C: Visit> Visit for (A, B, C) {
121153
fv.extend(c.free_variables());
122154
fv
123155
}
156+
157+
fn size(&self) -> usize {
158+
let (a, b, c) = self;
159+
a.size() + b.size() + c.size()
160+
}
124161
}
125162

126163
impl<A: Visit> Visit for &A {
127164
fn free_variables(&self) -> Vec<Variable> {
128165
A::free_variables(self)
129166
}
167+
168+
fn size(&self) -> usize {
169+
A::size(self)
170+
}
130171
}

0 commit comments

Comments
 (0)