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::*, impl_from_enum};
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
35impl DeBruijnId {
36 pub const ZERO: DeBruijnId = DeBruijnId { index: 0 };
37}
38
39#[derive(
73 Debug,
74 PartialEq,
75 Eq,
76 Copy,
77 Clone,
78 Hash,
79 PartialOrd,
80 Ord,
81 Serialize,
82 Deserialize,
83 Drive,
84 DriveMut,
85)]
86pub enum DeBruijnVar<Id> {
87 Bound(DeBruijnId, Id),
89 Free(Id),
92}
93
94generate_index_type!(RegionId, "Region");
99generate_index_type!(TypeVarId, "T");
100generate_index_type!(ConstGenericVarId, "Const");
101generate_index_type!(TraitClauseId, "TraitClause");
102generate_index_type!(TraitTypeConstraintId, "TraitTypeConstraint");
103
104#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Drive, DriveMut)]
106pub struct TypeVar {
107 pub index: TypeVarId,
109 #[drive(skip)]
111 pub name: String,
112}
113
114#[derive(
116 Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Drive, DriveMut,
117)]
118pub struct RegionVar {
119 pub index: RegionId,
121 #[drive(skip)]
123 pub name: Option<String>,
124}
125
126#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Drive, DriveMut)]
128pub struct ConstGenericVar {
129 pub index: ConstGenericVarId,
131 #[drive(skip)]
133 pub name: String,
134 pub ty: LiteralTy,
136}
137
138#[derive(Debug, Clone, Serialize, Deserialize, Drive, DriveMut)]
141pub struct TraitClause {
142 pub clause_id: TraitClauseId,
144 pub span: Option<Span>,
146 #[charon::opaque]
148 #[drive(skip)]
149 pub origin: PredicateOrigin,
150 #[charon::rename("trait")]
152 pub trait_: PolyTraitDeclRef,
153}
154
155impl PartialEq for TraitClause {
156 fn eq(&self, other: &Self) -> bool {
157 self.clause_id == other.clause_id && self.trait_ == other.trait_
159 }
160}
161
162impl std::hash::Hash for TraitClause {
163 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
164 self.clause_id.hash(state);
165 self.trait_.hash(state);
166 }
167}
168
169pub type RegionDbVar = DeBruijnVar<RegionId>;
170pub type TypeDbVar = DeBruijnVar<TypeVarId>;
171pub type ConstGenericDbVar = DeBruijnVar<ConstGenericVarId>;
172pub type ClauseDbVar = DeBruijnVar<TraitClauseId>;
173
174impl_from_enum!(Region::Var(RegionDbVar));
175impl_from_enum!(TyKind::TypeVar(TypeDbVar));
176impl_from_enum!(ConstGeneric::Var(ConstGenericDbVar));
177impl_from_enum!(TraitRefKind::Clause(ClauseDbVar));
178impl From<TypeDbVar> for Ty {
179 fn from(x: TypeDbVar) -> Self {
180 TyKind::TypeVar(x).into_ty()
181 }
182}
183
184impl DeBruijnId {
185 pub fn zero() -> Self {
186 DeBruijnId { index: 0 }
187 }
188
189 pub fn one() -> Self {
190 DeBruijnId { index: 1 }
191 }
192
193 pub fn new(index: usize) -> Self {
194 DeBruijnId { index }
195 }
196
197 pub fn is_zero(&self) -> bool {
198 self.index == 0
199 }
200
201 pub fn incr(&self) -> Self {
202 DeBruijnId {
203 index: self.index + 1,
204 }
205 }
206
207 pub fn decr(&self) -> Self {
208 DeBruijnId {
209 index: self.index - 1,
210 }
211 }
212
213 pub fn plus(&self, delta: Self) -> Self {
214 DeBruijnId {
215 index: self.index + delta.index,
216 }
217 }
218
219 pub fn sub(&self, delta: Self) -> Option<Self> {
220 Some(DeBruijnId {
221 index: self.index.checked_sub(delta.index)?,
222 })
223 }
224}
225
226impl<Id> DeBruijnVar<Id>
227where
228 Id: Copy,
229{
230 pub fn new_at_zero(id: Id) -> Self {
231 DeBruijnVar::Bound(DeBruijnId::new(0), id)
232 }
233
234 pub fn free(id: Id) -> Self {
235 DeBruijnVar::Free(id)
236 }
237
238 pub fn bound(index: DeBruijnId, id: Id) -> Self {
239 DeBruijnVar::Bound(index, id)
240 }
241
242 pub fn incr(&self) -> Self {
243 match *self {
244 DeBruijnVar::Bound(dbid, varid) => DeBruijnVar::Bound(dbid.incr(), varid),
245 DeBruijnVar::Free(varid) => DeBruijnVar::Free(varid),
246 }
247 }
248
249 pub fn decr(&self) -> Self {
250 match *self {
251 DeBruijnVar::Bound(dbid, varid) => DeBruijnVar::Bound(dbid.decr(), varid),
252 DeBruijnVar::Free(varid) => DeBruijnVar::Free(varid),
253 }
254 }
255
256 pub fn bound_at_depth(&self, depth: DeBruijnId) -> Option<Id> {
258 match *self {
259 DeBruijnVar::Bound(dbid, varid) if dbid == depth => Some(varid),
260 _ => None,
261 }
262 }
263 pub fn bound_at_depth_mut(&mut self, depth: DeBruijnId) -> Option<&mut Id> {
265 match self {
266 DeBruijnVar::Bound(dbid, varid) if *dbid == depth => Some(varid),
267 _ => None,
268 }
269 }
270
271 pub fn move_out_from_depth(&self, depth: DeBruijnId) -> Option<Self> {
274 Some(match *self {
275 DeBruijnVar::Bound(dbid, varid) => DeBruijnVar::Bound(dbid.sub(depth)?, varid),
276 DeBruijnVar::Free(_) => *self,
277 })
278 }
279
280 pub fn move_under_binders(&self, depth: DeBruijnId) -> Self {
282 match *self {
283 DeBruijnVar::Bound(dbid, varid) => DeBruijnVar::Bound(dbid.plus(depth), varid),
284 DeBruijnVar::Free(_) => *self,
285 }
286 }
287}
288
289impl TypeVar {
290 pub fn new(index: TypeVarId, name: String) -> TypeVar {
291 TypeVar { index, name }
292 }
293}
294
295impl Default for DeBruijnId {
296 fn default() -> Self {
297 Self::zero()
298 }
299}
300
301#[derive(Clone, Hash)]
306pub struct BindingStack<T> {
307 stack: Vec<T>,
310}
311
312impl<T> BindingStack<T> {
313 pub fn new(x: T) -> Self {
314 Self { stack: vec![x] }
315 }
316
317 pub fn is_empty(&self) -> bool {
318 self.stack.is_empty()
319 }
320 pub fn len(&self) -> usize {
321 self.stack.len()
322 }
323 pub fn depth(&self) -> DeBruijnId {
324 DeBruijnId::new(self.stack.len() - 1)
325 }
326 pub fn as_bound_var<Id>(&self, var: DeBruijnVar<Id>) -> (DeBruijnId, Id) {
328 match var {
329 DeBruijnVar::Bound(dbid, varid) => (dbid, varid),
330 DeBruijnVar::Free(varid) => (self.depth(), varid),
331 }
332 }
333 pub fn push(&mut self, x: T) {
334 self.stack.push(x);
335 }
336 pub fn pop(&mut self) -> Option<T> {
337 self.stack.pop()
338 }
339 fn real_index(&self, id: DeBruijnId) -> Option<usize> {
341 self.stack.len().checked_sub(id.index + 1)
342 }
343 pub fn get(&self, id: DeBruijnId) -> Option<&T> {
344 self.stack.get(self.real_index(id)?)
345 }
346 pub fn get_var<'a, Id: Idx, Inner>(&'a self, var: DeBruijnVar<Id>) -> Option<&'a Inner::Output>
347 where
348 T: Borrow<Inner>,
349 Inner: HasVectorOf<Id> + 'a,
350 {
351 let (dbid, varid) = self.as_bound_var(var);
352 self.get(dbid)
353 .and_then(|x| x.borrow().get_vector().get(varid))
354 }
355 pub fn get_mut(&mut self, id: DeBruijnId) -> Option<&mut T> {
356 let index = self.real_index(id)?;
357 self.stack.get_mut(index)
358 }
359 pub fn iter(&self) -> impl Iterator<Item = &T> + DoubleEndedIterator + ExactSizeIterator {
361 self.stack.iter().rev()
362 }
363 pub fn iter_enumerated(
365 &self,
366 ) -> impl Iterator<Item = (DeBruijnId, &T)> + DoubleEndedIterator + ExactSizeIterator {
367 self.iter()
368 .enumerate()
369 .map(|(i, x)| (DeBruijnId::new(i), x))
370 }
371 pub fn map_ref<'a, U>(&'a self, f: impl FnMut(&'a T) -> U) -> BindingStack<U> {
372 BindingStack {
373 stack: self.stack.iter().map(f).collect(),
374 }
375 }
376
377 pub fn innermost(&self) -> &T {
378 self.stack.last().unwrap()
379 }
380 pub fn innermost_mut(&mut self) -> &mut T {
381 self.stack.last_mut().unwrap()
382 }
383 pub fn outermost(&self) -> &T {
384 self.stack.first().unwrap()
385 }
386 pub fn outermost_mut(&mut self) -> &mut T {
387 self.stack.first_mut().unwrap()
388 }
389}
390
391impl<T> Default for BindingStack<T> {
392 fn default() -> Self {
393 Self {
394 stack: Default::default(),
395 }
396 }
397}
398
399impl<T: std::fmt::Debug> std::fmt::Debug for BindingStack<T> {
400 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
401 write!(f, "{:?}", self.stack)
402 }
403}
404
405impl<T> Index<DeBruijnId> for BindingStack<T> {
406 type Output = T;
407 fn index(&self, id: DeBruijnId) -> &Self::Output {
408 self.get(id).unwrap()
409 }
410}
411impl<T> IndexMut<DeBruijnId> for BindingStack<T> {
412 fn index_mut(&mut self, id: DeBruijnId) -> &mut Self::Output {
413 self.get_mut(id).unwrap()
414 }
415}