1use std::{
4 borrow::Borrow,
5 ops::{Index, IndexMut},
6};
7
8use derive_generic_visitor::{Drive, DriveMut, DriveTwo};
9use index_vec::Idx;
10use macros::EnumIsA;
11use serde::{Deserialize, Serialize};
12use serde_state::{DeserializeState, SerializeState};
13
14use crate::{ast::*, impl_from_enum};
15
16#[derive(
18 Debug,
19 PartialEq,
20 Eq,
21 Copy,
22 Clone,
23 Hash,
24 PartialOrd,
25 Ord,
26 Serialize,
27 Deserialize,
28 Drive,
29 DriveMut,
30 DriveTwo,
31)]
32#[serde(transparent)]
33#[cfg_attr(feature = "charon_on_charon", charon::transparent)]
34pub struct DeBruijnId {
35 pub index: usize,
36}
37
38impl DeBruijnId {
39 pub const ZERO: DeBruijnId = DeBruijnId { index: 0 };
40}
41
42#[derive(
73 Debug,
74 PartialEq,
75 Eq,
76 Copy,
77 Clone,
78 Hash,
79 PartialOrd,
80 Ord,
81 SerializeState,
82 DeserializeState,
83 Drive,
84 DriveMut,
85 DriveTwo,
86)]
87pub enum DeBruijnVar<Id> {
88 Bound(#[serde_state(stateless)] DeBruijnId, Id),
90 Free(Id),
93}
94
95generate_index_type!(RegionId, "Region");
100generate_index_type!(TypeVarId, "T");
101generate_index_type!(ConstGenericVarId, "Const");
102generate_index_type!(TraitClauseId, "TraitClause");
103generate_index_type!(TraitTypeConstraintId, "TraitTypeConstraint");
104
105#[derive(
107 Debug,
108 Clone,
109 Copy,
110 PartialEq,
111 Eq,
112 PartialOrd,
113 Ord,
114 Hash,
115 Serialize,
116 Deserialize,
117 Drive,
118 DriveMut,
119 DriveTwo,
120)]
121pub enum Variance {
122 Covariant,
123 Invariant,
124 Contravariant,
125 Bivariant,
126 #[cfg_attr(feature = "charon_on_charon", charon::rename("VaUnknown"))]
129 Unknown,
130}
131
132#[derive(
134 Debug,
135 Clone,
136 PartialEq,
137 Eq,
138 PartialOrd,
139 Ord,
140 Hash,
141 Serialize,
142 Deserialize,
143 Drive,
144 DriveMut,
145 DriveTwo,
146)]
147pub struct TypeParam {
148 pub index: TypeVarId,
150 pub name: String,
152 pub variance: Variance,
154}
155
156#[derive(
158 Debug,
159 Clone,
160 PartialEq,
161 Eq,
162 PartialOrd,
163 Ord,
164 Hash,
165 Serialize,
166 Deserialize,
167 Drive,
168 DriveMut,
169 DriveTwo,
170)]
171pub struct RegionParam {
172 pub index: RegionId,
174 pub name: Option<String>,
176 pub variance: Variance,
178 pub mutability: LifetimeMutability,
182}
183
184#[derive(
187 Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, EnumIsA,
188)]
189#[cfg_attr(feature = "charon_on_charon", charon::variants_prefix("Lt"))]
190pub enum LifetimeMutability {
191 Mutable,
193 Shared,
195 Unknown,
197}
198
199#[derive(
201 Debug,
202 Clone,
203 PartialEq,
204 Eq,
205 PartialOrd,
206 Ord,
207 Hash,
208 SerializeState,
209 DeserializeState,
210 Drive,
211 DriveMut,
212 DriveTwo,
213)]
214pub struct ConstGenericParam {
215 pub index: ConstGenericVarId,
217 pub name: String,
219 pub ty: Ty,
221}
222
223#[derive(Debug, Clone, SerializeState, DeserializeState, Drive, DriveMut, DriveTwo)]
226pub struct TraitParam {
227 pub clause_id: TraitClauseId,
229 pub span: Option<Span>,
231 pub origin: PredicateOrigin,
233 #[cfg_attr(feature = "charon_on_charon", charon::rename("trait"))]
235 pub trait_: PolyTraitDeclRef,
236}
237
238#[derive(
240 Debug,
241 Clone,
242 PartialEq,
243 Eq,
244 PartialOrd,
245 Ord,
246 Hash,
247 SerializeState,
248 DeserializeState,
249 Drive,
250 DriveMut,
251 DriveTwo,
252)]
253pub enum PredicateOrigin {
254 WhereClauseOnFn,
261 WhereClauseOnType,
267 WhereClauseOnImpl,
274 TraitSelf,
280 WhereClauseOnTrait,
287 TraitItem(AssocTypeId),
293 #[cfg_attr(feature = "charon_on_charon", charon::rename("OriginDyn"))]
295 Dyn,
296}
297
298impl TypeParam {
299 pub fn new(index: TypeVarId, name: String, variance: Variance) -> Self {
300 Self {
301 index,
302 name,
303 variance,
304 }
305 }
306}
307
308impl RegionParam {
309 pub fn new(index: RegionId, name: Option<String>, variance: Variance) -> Self {
310 Self {
311 index,
312 name,
313 variance,
314 mutability: LifetimeMutability::Unknown,
315 }
316 }
317}
318
319impl ConstGenericParam {
320 pub fn new(index: ConstGenericVarId, name: String, ty: Ty) -> Self {
321 Self { index, name, ty }
322 }
323}
324
325impl TraitParam {
326 pub fn identity_tref(&self) -> TraitRef {
328 self.identity_tref_at_depth(DeBruijnId::zero())
329 }
330
331 pub fn identity_tref_at_depth(&self, depth: DeBruijnId) -> TraitRef {
333 TraitRef::new(
334 TraitRefKind::Clause(DeBruijnVar::bound(depth, self.clause_id)),
335 self.trait_.clone().move_under_binders(depth),
336 )
337 }
338}
339
340impl PartialEq for TraitParam {
341 fn eq(&self, other: &Self) -> bool {
342 self.clause_id == other.clause_id && self.trait_ == other.trait_
344 }
345}
346
347impl Eq for TraitParam {}
348
349impl PartialOrd for TraitParam {
350 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
351 Some(self.cmp(other))
352 }
353}
354
355impl Ord for TraitParam {
356 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
357 (&self.clause_id, &self.trait_).cmp(&(&other.clause_id, &other.trait_))
358 }
359}
360
361impl std::hash::Hash for TraitParam {
362 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
363 self.clause_id.hash(state);
364 self.trait_.hash(state);
365 }
366}
367
368pub type RegionDbVar = DeBruijnVar<RegionId>;
369pub type TypeDbVar = DeBruijnVar<TypeVarId>;
370pub type ConstGenericDbVar = DeBruijnVar<ConstGenericVarId>;
371pub type ClauseDbVar = DeBruijnVar<TraitClauseId>;
372
373impl_from_enum!(Region::Var(RegionDbVar));
374impl_from_enum!(TyKind::TypeVar(TypeDbVar));
375impl_from_enum!(ConstantExprKind::Var(ConstGenericDbVar));
376impl_from_enum!(TraitRefKind::Clause(ClauseDbVar));
377impl From<TypeDbVar> for Ty {
378 fn from(x: TypeDbVar) -> Self {
379 TyKind::TypeVar(x).into_ty()
380 }
381}
382
383impl DeBruijnId {
384 pub fn zero() -> Self {
385 DeBruijnId { index: 0 }
386 }
387
388 pub fn one() -> Self {
389 DeBruijnId { index: 1 }
390 }
391
392 pub fn new(index: usize) -> Self {
393 DeBruijnId { index }
394 }
395
396 pub fn is_zero(&self) -> bool {
397 self.index == 0
398 }
399
400 pub fn incr(&self) -> Self {
401 DeBruijnId {
402 index: self.index + 1,
403 }
404 }
405
406 pub fn decr(&self) -> Self {
407 DeBruijnId {
408 index: self.index - 1,
409 }
410 }
411
412 pub fn plus(&self, delta: Self) -> Self {
413 DeBruijnId {
414 index: self.index + delta.index,
415 }
416 }
417
418 pub fn sub(&self, delta: Self) -> Option<Self> {
419 Some(DeBruijnId {
420 index: self.index.checked_sub(delta.index)?,
421 })
422 }
423}
424
425impl<Id> DeBruijnVar<Id>
426where
427 Id: Copy,
428{
429 pub fn new_at_zero(id: Id) -> Self {
430 DeBruijnVar::Bound(DeBruijnId::new(0), id)
431 }
432
433 pub fn free(id: Id) -> Self {
434 DeBruijnVar::Free(id)
435 }
436
437 pub fn bound(index: DeBruijnId, id: Id) -> Self {
438 DeBruijnVar::Bound(index, id)
439 }
440
441 pub fn incr(&self) -> Self {
442 match *self {
443 DeBruijnVar::Bound(dbid, varid) => DeBruijnVar::Bound(dbid.incr(), varid),
444 DeBruijnVar::Free(varid) => DeBruijnVar::Free(varid),
445 }
446 }
447
448 pub fn decr(&self) -> Self {
449 match *self {
450 DeBruijnVar::Bound(dbid, varid) => DeBruijnVar::Bound(dbid.decr(), varid),
451 DeBruijnVar::Free(varid) => DeBruijnVar::Free(varid),
452 }
453 }
454
455 pub fn bound_at_depth(&self, depth: DeBruijnId) -> Option<Id> {
457 match *self {
458 DeBruijnVar::Bound(dbid, varid) if dbid == depth => Some(varid),
459 _ => None,
460 }
461 }
462 pub fn bound_at_depth_mut(&mut self, depth: DeBruijnId) -> Option<&mut Id> {
464 match self {
465 DeBruijnVar::Bound(dbid, varid) if *dbid == depth => Some(varid),
466 _ => None,
467 }
468 }
469
470 pub fn move_out_from_depth(&self, depth: DeBruijnId) -> Option<Self> {
473 Some(match *self {
474 DeBruijnVar::Bound(dbid, varid) => DeBruijnVar::Bound(dbid.sub(depth)?, varid),
475 DeBruijnVar::Free(_) => *self,
476 })
477 }
478
479 pub fn move_under_binders(&self, depth: DeBruijnId) -> Self {
481 match *self {
482 DeBruijnVar::Bound(dbid, varid) => DeBruijnVar::Bound(dbid.plus(depth), varid),
483 DeBruijnVar::Free(_) => *self,
484 }
485 }
486}
487
488impl Default for DeBruijnId {
489 fn default() -> Self {
490 Self::zero()
491 }
492}
493
494#[derive(Clone, Hash)]
499pub struct BindingStack<T> {
500 stack: Vec<T>,
503}
504
505impl<T> BindingStack<T> {
506 pub fn new(x: T) -> Self {
507 Self { stack: vec![x] }
508 }
509 pub fn empty() -> Self {
511 Self { stack: vec![] }
512 }
513
514 pub fn is_empty(&self) -> bool {
515 self.stack.is_empty()
516 }
517 pub fn len(&self) -> usize {
518 self.stack.len()
519 }
520 pub fn depth(&self) -> DeBruijnId {
521 DeBruijnId::new(self.stack.len() - 1)
522 }
523 pub fn as_bound_var<Id>(&self, var: DeBruijnVar<Id>) -> (DeBruijnId, Id) {
525 match var {
526 DeBruijnVar::Bound(dbid, varid) => (dbid, varid),
527 DeBruijnVar::Free(varid) => (self.depth(), varid),
528 }
529 }
530 pub fn push(&mut self, x: T) {
531 self.stack.push(x);
532 }
533 pub fn pop(&mut self) -> Option<T> {
534 self.stack.pop()
535 }
536 fn real_index(&self, id: DeBruijnId) -> Option<usize> {
538 self.stack.len().checked_sub(id.index + 1)
539 }
540 pub fn get(&self, id: DeBruijnId) -> Option<&T> {
541 self.stack.get(self.real_index(id)?)
542 }
543 pub fn get_var<'a, Id: Idx, Inner>(&'a self, var: DeBruijnVar<Id>) -> Option<&'a Inner::Output>
544 where
545 T: Borrow<Inner>,
546 Inner: HasIdxVecOf<Id> + 'a,
547 {
548 let (dbid, varid) = self.as_bound_var(var);
549 self.get(dbid)
550 .and_then(|x| x.borrow().get_idx_vec().get(varid))
551 }
552 pub fn get_mut(&mut self, id: DeBruijnId) -> Option<&mut T> {
553 let index = self.real_index(id)?;
554 self.stack.get_mut(index)
555 }
556 pub fn iter(&self) -> impl DoubleEndedIterator<Item = &T> + ExactSizeIterator {
558 self.stack.iter().rev()
559 }
560 pub fn iter_enumerated(
562 &self,
563 ) -> impl DoubleEndedIterator<Item = (DeBruijnId, &T)> + ExactSizeIterator {
564 self.iter()
565 .enumerate()
566 .map(|(i, x)| (DeBruijnId::new(i), x))
567 }
568 pub fn map_ref<'a, U>(&'a self, f: impl FnMut(&'a T) -> U) -> BindingStack<U> {
569 BindingStack {
570 stack: self.stack.iter().map(f).collect(),
571 }
572 }
573
574 pub fn innermost(&self) -> &T {
575 self.stack.last().unwrap()
576 }
577 pub fn innermost_mut(&mut self) -> &mut T {
578 self.stack.last_mut().unwrap()
579 }
580 pub fn outermost(&self) -> &T {
581 self.stack.first().unwrap()
582 }
583 pub fn outermost_mut(&mut self) -> &mut T {
584 self.stack.first_mut().unwrap()
585 }
586}
587
588impl<T> Default for BindingStack<T> {
589 fn default() -> Self {
590 Self {
591 stack: Default::default(),
592 }
593 }
594}
595
596impl<T: std::fmt::Debug> std::fmt::Debug for BindingStack<T> {
597 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
598 write!(f, "{:?}", self.stack)
599 }
600}
601
602impl<T> Index<DeBruijnId> for BindingStack<T> {
603 type Output = T;
604 fn index(&self, id: DeBruijnId) -> &Self::Output {
605 self.get(id).unwrap()
606 }
607}
608impl<T> IndexMut<DeBruijnId> for BindingStack<T> {
609 fn index_mut(&mut self, id: DeBruijnId) -> &mut Self::Output {
610 self.get_mut(id).unwrap()
611 }
612}