1use std::{
4 borrow::Borrow,
5 ops::{Index, IndexMut},
6};
7
8use derive_generic_visitor::{Drive, DriveMut};
9use index_vec::Idx;
10use serde::{Deserialize, Serialize};
11
12use crate::ast::*;
13
14#[derive(
16 Debug,
17 PartialEq,
18 Eq,
19 Copy,
20 Clone,
21 Hash,
22 PartialOrd,
23 Ord,
24 Serialize,
25 Deserialize,
26 Drive,
27 DriveMut,
28)]
29#[serde(transparent)]
30#[drive(skip)]
31pub struct DeBruijnId {
32 pub index: usize,
33}
34
35#[derive(
69 Debug,
70 PartialEq,
71 Eq,
72 Copy,
73 Clone,
74 Hash,
75 PartialOrd,
76 Ord,
77 Serialize,
78 Deserialize,
79 Drive,
80 DriveMut,
81)]
82pub enum DeBruijnVar<Id> {
83 Bound(DeBruijnId, Id),
85 Free(Id),
88}
89
90generate_index_type!(RegionId, "Region");
95generate_index_type!(TypeVarId, "T");
96generate_index_type!(ConstGenericVarId, "Const");
97generate_index_type!(TraitClauseId, "TraitClause");
98generate_index_type!(TraitTypeConstraintId, "TraitTypeConstraint");
99
100#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Drive, DriveMut)]
102pub struct TypeVar {
103 pub index: TypeVarId,
105 #[drive(skip)]
107 pub name: String,
108}
109
110#[derive(
112 Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Drive, DriveMut,
113)]
114pub struct RegionVar {
115 pub index: RegionId,
117 #[drive(skip)]
119 pub name: Option<String>,
120}
121
122#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Drive, DriveMut)]
124pub struct ConstGenericVar {
125 pub index: ConstGenericVarId,
127 #[drive(skip)]
129 pub name: String,
130 pub ty: LiteralTy,
132}
133
134#[derive(Debug, Clone, Serialize, Deserialize, Drive, DriveMut)]
137pub struct TraitClause {
138 pub clause_id: TraitClauseId,
140 pub span: Option<Span>,
142 #[charon::opaque]
144 #[drive(skip)]
145 pub origin: PredicateOrigin,
146 #[charon::rename("trait")]
148 pub trait_: PolyTraitDeclRef,
149}
150
151impl PartialEq for TraitClause {
152 fn eq(&self, other: &Self) -> bool {
153 self.clause_id == other.clause_id && self.trait_ == other.trait_
155 }
156}
157
158impl std::hash::Hash for TraitClause {
159 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
160 self.clause_id.hash(state);
161 self.trait_.hash(state);
162 }
163}
164
165pub type RegionDbVar = DeBruijnVar<RegionId>;
166pub type TypeDbVar = DeBruijnVar<TypeVarId>;
167pub type ConstGenericDbVar = DeBruijnVar<ConstGenericVarId>;
168pub type ClauseDbVar = DeBruijnVar<TraitClauseId>;
169
170impl DeBruijnId {
171 pub fn zero() -> Self {
172 DeBruijnId { index: 0 }
173 }
174
175 pub fn one() -> Self {
176 DeBruijnId { index: 1 }
177 }
178
179 pub fn new(index: usize) -> Self {
180 DeBruijnId { index }
181 }
182
183 pub fn is_zero(&self) -> bool {
184 self.index == 0
185 }
186
187 pub fn incr(&self) -> Self {
188 DeBruijnId {
189 index: self.index + 1,
190 }
191 }
192
193 pub fn decr(&self) -> Self {
194 DeBruijnId {
195 index: self.index - 1,
196 }
197 }
198
199 pub fn plus(&self, delta: Self) -> Self {
200 DeBruijnId {
201 index: self.index + delta.index,
202 }
203 }
204
205 pub fn sub(&self, delta: Self) -> Option<Self> {
206 Some(DeBruijnId {
207 index: self.index.checked_sub(delta.index)?,
208 })
209 }
210}
211
212impl<Id> DeBruijnVar<Id>
213where
214 Id: Copy,
215{
216 pub fn new_at_zero(id: Id) -> Self {
217 DeBruijnVar::Bound(DeBruijnId::new(0), id)
218 }
219
220 pub fn free(id: Id) -> Self {
221 DeBruijnVar::Free(id)
222 }
223
224 pub fn bound(index: DeBruijnId, id: Id) -> Self {
225 DeBruijnVar::Bound(index, id)
226 }
227
228 pub fn incr(&self) -> Self {
229 match *self {
230 DeBruijnVar::Bound(dbid, varid) => DeBruijnVar::Bound(dbid.incr(), varid),
231 DeBruijnVar::Free(varid) => DeBruijnVar::Free(varid),
232 }
233 }
234
235 pub fn decr(&self) -> Self {
236 match *self {
237 DeBruijnVar::Bound(dbid, varid) => DeBruijnVar::Bound(dbid.decr(), varid),
238 DeBruijnVar::Free(varid) => DeBruijnVar::Free(varid),
239 }
240 }
241
242 pub fn bound_at_depth(&self, depth: DeBruijnId) -> Option<Id> {
244 match *self {
245 DeBruijnVar::Bound(dbid, varid) if dbid == depth => Some(varid),
246 _ => None,
247 }
248 }
249 pub fn bound_at_depth_mut(&mut self, depth: DeBruijnId) -> Option<&mut Id> {
251 match self {
252 DeBruijnVar::Bound(dbid, varid) if *dbid == depth => Some(varid),
253 _ => None,
254 }
255 }
256
257 pub fn move_out_from_depth(&self, depth: DeBruijnId) -> Option<Self> {
260 Some(match *self {
261 DeBruijnVar::Bound(dbid, varid) => DeBruijnVar::Bound(dbid.sub(depth)?, varid),
262 DeBruijnVar::Free(_) => *self,
263 })
264 }
265
266 pub fn move_under_binders(&self, depth: DeBruijnId) -> Self {
268 match *self {
269 DeBruijnVar::Bound(dbid, varid) => DeBruijnVar::Bound(dbid.plus(depth), varid),
270 DeBruijnVar::Free(_) => *self,
271 }
272 }
273}
274
275impl TypeVar {
276 pub fn new(index: TypeVarId, name: String) -> TypeVar {
277 TypeVar { index, name }
278 }
279}
280
281impl Default for DeBruijnId {
282 fn default() -> Self {
283 Self::zero()
284 }
285}
286
287#[derive(Clone, Hash)]
292pub struct BindingStack<T> {
293 stack: Vec<T>,
296}
297
298impl<T> BindingStack<T> {
299 pub fn new(x: T) -> Self {
300 Self { stack: vec![x] }
301 }
302
303 pub fn is_empty(&self) -> bool {
304 self.stack.is_empty()
305 }
306 pub fn len(&self) -> usize {
307 self.stack.len()
308 }
309 pub fn depth(&self) -> DeBruijnId {
310 DeBruijnId::new(self.stack.len() - 1)
311 }
312 pub fn as_bound_var<Id>(&self, var: DeBruijnVar<Id>) -> (DeBruijnId, Id) {
314 match var {
315 DeBruijnVar::Bound(dbid, varid) => (dbid, varid),
316 DeBruijnVar::Free(varid) => (self.depth(), varid),
317 }
318 }
319 pub fn push(&mut self, x: T) {
320 self.stack.push(x);
321 }
322 pub fn pop(&mut self) -> Option<T> {
323 self.stack.pop()
324 }
325 fn real_index(&self, id: DeBruijnId) -> Option<usize> {
327 self.stack.len().checked_sub(id.index + 1)
328 }
329 pub fn get(&self, id: DeBruijnId) -> Option<&T> {
330 self.stack.get(self.real_index(id)?)
331 }
332 pub fn get_var<'a, Id: Idx, Inner>(&'a self, var: DeBruijnVar<Id>) -> Option<&'a Inner::Output>
333 where
334 T: Borrow<Inner>,
335 Inner: HasVectorOf<Id> + 'a,
336 {
337 let (dbid, varid) = self.as_bound_var(var);
338 self.get(dbid)
339 .and_then(|x| x.borrow().get_vector().get(varid))
340 }
341 pub fn get_mut(&mut self, id: DeBruijnId) -> Option<&mut T> {
342 let index = self.real_index(id)?;
343 self.stack.get_mut(index)
344 }
345 pub fn iter(&self) -> impl Iterator<Item = &T> + DoubleEndedIterator + ExactSizeIterator {
347 self.stack.iter().rev()
348 }
349 pub fn iter_enumerated(
351 &self,
352 ) -> impl Iterator<Item = (DeBruijnId, &T)> + DoubleEndedIterator + ExactSizeIterator {
353 self.iter()
354 .enumerate()
355 .map(|(i, x)| (DeBruijnId::new(i), x))
356 }
357 pub fn map_ref<'a, U>(&'a self, f: impl FnMut(&'a T) -> U) -> BindingStack<U> {
358 BindingStack {
359 stack: self.stack.iter().map(f).collect(),
360 }
361 }
362
363 pub fn innermost(&self) -> &T {
364 self.stack.last().unwrap()
365 }
366 pub fn innermost_mut(&mut self) -> &mut T {
367 self.stack.last_mut().unwrap()
368 }
369 pub fn outermost(&self) -> &T {
370 self.stack.first().unwrap()
371 }
372 pub fn outermost_mut(&mut self) -> &mut T {
373 self.stack.first_mut().unwrap()
374 }
375}
376
377impl<T> Default for BindingStack<T> {
378 fn default() -> Self {
379 Self {
380 stack: Default::default(),
381 }
382 }
383}
384
385impl<T: std::fmt::Debug> std::fmt::Debug for BindingStack<T> {
386 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
387 write!(f, "{:?}", self.stack)
388 }
389}
390
391impl<T> Index<DeBruijnId> for BindingStack<T> {
392 type Output = T;
393 fn index(&self, id: DeBruijnId) -> &Self::Output {
394 self.get(id).unwrap()
395 }
396}
397impl<T> IndexMut<DeBruijnId> for BindingStack<T> {
398 fn index_mut(&mut self, id: DeBruijnId) -> &mut Self::Output {
399 self.get_mut(id).unwrap()
400 }
401}