]> git.proxmox.com Git - rustc.git/blob - vendor/rust-analyzer-salsa/tests/incremental/constants.rs
New upstream version 1.76.0+dfsg1
[rustc.git] / vendor / rust-analyzer-salsa / tests / incremental / constants.rs
1 use crate::implementation::{TestContext, TestContextImpl};
2 use salsa::debug::DebugQueryTable;
3 use salsa::Durability;
4
5 #[salsa::query_group(Constants)]
6 pub(crate) trait ConstantsDatabase: TestContext {
7 #[salsa::input]
8 fn input(&self, key: char) -> usize;
9
10 fn add(&self, key1: char, key2: char) -> usize;
11
12 fn add3(&self, key1: char, key2: char, key3: char) -> usize;
13 }
14
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)
18 }
19
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)
23 }
24
25 // Test we can assign a constant and things will be correctly
26 // recomputed afterwards.
27 #[test]
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);
33
34 db.set_input_with_durability('a', 66, Durability::HIGH);
35 assert_eq!(db.add('a', 'b'), 88);
36 }
37
38 #[test]
39 fn invalidate_constant_1() {
40 let db = &mut TestContextImpl::default();
41
42 // Not constant:
43 db.set_input('a', 44);
44 assert_eq!(db.add('a', 'a'), 88);
45
46 // Becomes constant:
47 db.set_input_with_durability('a', 44, Durability::HIGH);
48 assert_eq!(db.add('a', 'a'), 88);
49
50 // Invalidates:
51 db.set_input_with_durability('a', 33, Durability::HIGH);
52 assert_eq!(db.add('a', 'a'), 66);
53 }
54
55 // Test cases where we assign same value to 'a' after declaring it a
56 // constant.
57 #[test]
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);
63 }
64
65 #[test]
66 fn not_constant() {
67 let mut db = TestContextImpl::default();
68
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')));
73 }
74
75 #[test]
76 fn durability() {
77 let mut db = TestContextImpl::default();
78
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')));
83 }
84
85 #[test]
86 fn mixed_constant() {
87 let mut db = TestContextImpl::default();
88
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')));
93 }
94
95 #[test]
96 fn becomes_constant_with_change() {
97 let mut db = TestContextImpl::default();
98
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')));
103
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')));
107
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')));
111
112 db.set_input_with_durability('b', 45, Durability::MEDIUM);
113 assert_eq!(db.add('a', 'b'), 68);
114 assert_eq!(
115 Durability::MEDIUM,
116 AddQuery.in_db(&db).durability(('a', 'b'))
117 );
118 }
119
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
123 // being constant.
124 #[test]
125 fn constant_to_non_constant() {
126 let mut db = TestContextImpl::default();
127
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);
131
132 // Here, `add3` invokes `add`, which yields 33. Both calls are
133 // constant.
134 assert_eq!(db.add3('a', 'b', 'c'), 66);
135
136 db.set_input('a', 11);
137
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
141 // constant.
142 assert_eq!(db.add3('a', 'b', 'c'), 66);
143
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);
148 }