1 use crate::implementation
::{TestContext, TestContextImpl}
;
2 use salsa
::debug
::DebugQueryTable
;
5 #[salsa::query_group(Constants)]
6 pub(crate) trait ConstantsDatabase
: TestContext
{
8 fn input(&self, key
: char) -> usize;
10 fn add(&self, key1
: char, key2
: char) -> usize;
12 fn add3(&self, key1
: char, key2
: char, key3
: char) -> usize;
15 fn add(db
: &dyn ConstantsDatabase
, key1
: char, key2
: char) -> usize {
16 db
.log().add(format
!("add({}, {})", key1
, key2
));
17 db
.input(key1
) + db
.input(key2
)
20 fn add3(db
: &dyn ConstantsDatabase
, key1
: char, key2
: char, key3
: char) -> usize {
21 db
.log().add(format
!("add3({}, {}, {})", key1
, key2
, key3
));
22 db
.add(key1
, key2
) + db
.input(key3
)
25 // Test we can assign a constant and things will be correctly
26 // recomputed afterwards.
28 fn invalidate_constant() {
29 let db
= &mut TestContextImpl
::default();
30 db
.set_input_with_durability('a'
, 44, Durability
::HIGH
);
31 db
.set_input_with_durability('b'
, 22, Durability
::HIGH
);
32 assert_eq
!(db
.add('a'
, 'b'
), 66);
34 db
.set_input_with_durability('a'
, 66, Durability
::HIGH
);
35 assert_eq
!(db
.add('a'
, 'b'
), 88);
39 fn invalidate_constant_1() {
40 let db
= &mut TestContextImpl
::default();
43 db
.set_input('a'
, 44);
44 assert_eq
!(db
.add('a'
, 'a'
), 88);
47 db
.set_input_with_durability('a'
, 44, Durability
::HIGH
);
48 assert_eq
!(db
.add('a'
, 'a'
), 88);
51 db
.set_input_with_durability('a'
, 33, Durability
::HIGH
);
52 assert_eq
!(db
.add('a'
, 'a'
), 66);
55 // Test cases where we assign same value to 'a' after declaring it a
58 fn set_after_constant_same_value() {
59 let db
= &mut TestContextImpl
::default();
60 db
.set_input_with_durability('a'
, 44, Durability
::HIGH
);
61 db
.set_input_with_durability('a'
, 44, Durability
::HIGH
);
62 db
.set_input('a'
, 44);
67 let mut db
= TestContextImpl
::default();
69 db
.set_input('a'
, 22);
70 db
.set_input('b'
, 44);
71 assert_eq
!(db
.add('a'
, 'b'
), 66);
72 assert_eq
!(Durability
::LOW
, AddQuery
.in_db(&db
).durability(('a'
, 'b'
)));
77 let mut db
= TestContextImpl
::default();
79 db
.set_input_with_durability('a'
, 22, Durability
::HIGH
);
80 db
.set_input_with_durability('b'
, 44, Durability
::HIGH
);
81 assert_eq
!(db
.add('a'
, 'b'
), 66);
82 assert_eq
!(Durability
::HIGH
, AddQuery
.in_db(&db
).durability(('a'
, 'b'
)));
87 let mut db
= TestContextImpl
::default();
89 db
.set_input_with_durability('a'
, 22, Durability
::HIGH
);
90 db
.set_input('b'
, 44);
91 assert_eq
!(db
.add('a'
, 'b'
), 66);
92 assert_eq
!(Durability
::LOW
, AddQuery
.in_db(&db
).durability(('a'
, 'b'
)));
96 fn becomes_constant_with_change() {
97 let mut db
= TestContextImpl
::default();
99 db
.set_input('a'
, 22);
100 db
.set_input('b'
, 44);
101 assert_eq
!(db
.add('a'
, 'b'
), 66);
102 assert_eq
!(Durability
::LOW
, AddQuery
.in_db(&db
).durability(('a'
, 'b'
)));
104 db
.set_input_with_durability('a'
, 23, Durability
::HIGH
);
105 assert_eq
!(db
.add('a'
, 'b'
), 67);
106 assert_eq
!(Durability
::LOW
, AddQuery
.in_db(&db
).durability(('a'
, 'b'
)));
108 db
.set_input_with_durability('b'
, 45, Durability
::HIGH
);
109 assert_eq
!(db
.add('a'
, 'b'
), 68);
110 assert_eq
!(Durability
::HIGH
, AddQuery
.in_db(&db
).durability(('a'
, 'b'
)));
112 db
.set_input_with_durability('b'
, 45, Durability
::MEDIUM
);
113 assert_eq
!(db
.add('a'
, 'b'
), 68);
116 AddQuery
.in_db(&db
).durability(('a'
, 'b'
))
120 // Test a subtle case in which an input changes from constant to
121 // non-constant, but its value doesn't change. If we're not careful,
122 // this can cause us to incorrectly consider derived values as still
125 fn constant_to_non_constant() {
126 let mut db
= TestContextImpl
::default();
128 db
.set_input_with_durability('a'
, 11, Durability
::HIGH
);
129 db
.set_input_with_durability('b'
, 22, Durability
::HIGH
);
130 db
.set_input_with_durability('c'
, 33, Durability
::HIGH
);
132 // Here, `add3` invokes `add`, which yields 33. Both calls are
134 assert_eq
!(db
.add3('a'
, 'b'
, 'c'
), 66);
136 db
.set_input('a'
, 11);
138 // Here, `add3` invokes `add`, which *still* yields 33, but which
139 // is no longer constant. Since value didn't change, we might
140 // preserve `add3` unchanged, not noticing that it is no longer
142 assert_eq
!(db
.add3('a'
, 'b'
, 'c'
), 66);
144 // In that case, we would not get the correct result here, when
145 // 'a' changes *again*.
146 db
.set_input('a'
, 22);
147 assert_eq
!(db
.add3('a'
, 'b'
, 'c'
), 77);