1use derive_generic_visitor::*;
2use itertools::Itertools;
3use serde_state::{DeserializeState, SerializeState};
4use std::{collections::HashSet, mem};
5
6use crate::ast::*;
7
8pub mod regions;
9pub mod substitute;
10pub mod trait_proofs;
11pub mod type_info;
12pub mod types;
13pub mod vars;
14
15pub use regions::*;
16pub use substitute::*;
17pub use trait_proofs::*;
18pub use type_info::*;
19pub use types::*;
20pub use vars::*;
21
22#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
24#[derive(SerializeState, DeserializeState, Drive, DriveMut, DriveTwo)]
25pub struct GenericArgs {
26 pub regions: IndexVec<RegionId, Region>,
27 pub types: IndexVec<TypeVarId, Ty>,
28 pub const_generics: IndexVec<ConstGenericVarId, ConstantExpr>,
29 pub trait_refs: IndexVec<TraitClauseId, PolyTraitRef>,
30}
31
32#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
34#[derive(SerializeState, DeserializeState, Drive, DriveMut, DriveTwo)]
35pub struct RegionArgs {
36 pub regions: IndexVec<RegionId, Region>,
37}
38
39pub type PolyTraitDeclRef = RegionBinder<TraitDeclRef>;
41
42#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
44#[derive(SerializeState, DeserializeState, Drive, DriveMut, DriveTwo)]
45pub struct OutlivesPred<T, U>(pub T, pub U);
46
47pub type RegionOutlives = OutlivesPred<Region, Region>;
48pub type TypeOutlives = OutlivesPred<Ty, Region>;
49pub type PolyRegionOutlives = RegionBinder<RegionOutlives>;
50pub type PolyTypeOutlives = RegionBinder<TypeOutlives>;
51
52#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
60#[derive(SerializeState, DeserializeState, Drive, DriveMut, DriveTwo)]
61pub struct TraitTypeConstraint {
62 pub trait_ref: TraitRef,
63 pub type_id: AssocTypeId,
64 pub ty: Ty,
65}
66
67pub type BoxedArgs = Box<GenericArgs>;
68
69#[derive(Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
71#[derive(SerializeState, DeserializeState, Drive, DriveMut, DriveTwo)]
72pub struct GenericParams {
73 #[serde_state(stateless)]
74 pub regions: IndexVec<RegionId, RegionParam>,
75 #[serde_state(stateless)]
76 pub types: IndexVec<TypeVarId, TypeParam>,
77 pub const_generics: IndexVec<ConstGenericVarId, ConstGenericParam>,
78 pub trait_clauses: IndexVec<TraitClauseId, TraitParam>,
80 pub regions_outlive: Vec<PolyRegionOutlives>,
82 pub types_outlive: Vec<PolyTypeOutlives>,
84 pub trait_type_constraints: IndexVec<TraitTypeConstraintId, RegionBinder<TraitTypeConstraint>>,
86}
87
88#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
89#[derive(SerializeState, DeserializeState, Drive, DriveMut, DriveTwo)]
90#[cfg_attr(feature = "charon_on_charon", charon::variants_prefix("BK"))]
91pub enum BinderKind {
92 TraitType(TraitDeclId, AssocTypeId),
94 TraitMethod(TraitDeclId, TraitMethodId),
97 InherentImplBlock,
99 Dyn,
101 Other,
103}
104
105#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
109#[derive(SerializeState, DeserializeState, Drive, DriveMut, DriveTwo)]
110pub struct Binder<T> {
111 #[cfg_attr(feature = "charon_on_charon", charon::rename("binder_params"))]
112 pub params: GenericParams,
113 #[cfg_attr(feature = "charon_on_charon", charon::rename("binder_value"))]
116 pub skip_binder: T,
117 #[cfg_attr(feature = "charon_on_charon", charon::opaque)]
119 pub kind: BinderKind,
120}
121
122#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
125#[derive(SerializeState, DeserializeState, Drive, DriveMut, DriveTwo)]
126#[serde_state(state_implements = DedupSerializerState)] pub struct RegionBinder<T> {
128 #[cfg_attr(feature = "charon_on_charon", charon::rename("binder_regions"))]
129 #[serde_state(stateless)]
130 pub regions: IndexVec<RegionId, RegionParam>,
131 pub regions_outlive: Vec<PolyRegionOutlives>,
133 pub types_outlive: Vec<PolyTypeOutlives>,
135 #[cfg_attr(feature = "charon_on_charon", charon::rename("binder_value"))]
138 pub skip_binder: T,
139}
140
141impl GenericArgs {
142 pub fn len(&self) -> usize {
143 let GenericArgs {
144 regions,
145 types,
146 const_generics,
147 trait_refs,
148 } = self;
149 regions.len() + types.len() + const_generics.len() + trait_refs.len()
150 }
151
152 pub fn is_empty(&self) -> bool {
153 self.len() == 0
154 }
155 pub fn has_explicits(&self) -> bool {
157 !self.regions.is_empty() || !self.types.is_empty() || !self.const_generics.is_empty()
158 }
159 pub fn has_implicits(&self) -> bool {
161 !self.trait_refs.is_empty()
162 }
163
164 pub fn empty() -> Self {
165 GenericArgs {
166 regions: Default::default(),
167 types: Default::default(),
168 const_generics: Default::default(),
169 trait_refs: Default::default(),
170 }
171 }
172
173 pub fn new(
174 regions: IndexVec<RegionId, Region>,
175 types: IndexVec<TypeVarId, Ty>,
176 const_generics: IndexVec<ConstGenericVarId, ConstantExpr>,
177 trait_refs: IndexVec<TraitClauseId, PolyTraitRef>,
178 ) -> Self {
179 Self {
180 regions,
181 types,
182 const_generics,
183 trait_refs,
184 }
185 }
186 pub fn new_types(types: IndexVec<TypeVarId, Ty>) -> Self {
187 Self {
188 types,
189 ..Self::empty()
190 }
191 }
192 pub fn new_lifetimes(regions: IndexVec<RegionId, Region>) -> Self {
193 Self {
194 regions,
195 ..Self::empty()
196 }
197 }
198
199 pub fn matches(&self, params: &GenericParams) -> bool {
202 params.regions.len() == self.regions.len()
203 && params.types.len() == self.types.len()
204 && params.const_generics.len() == self.const_generics.len()
205 && params.trait_clauses.len() == self.trait_refs.len()
206 }
207
208 pub fn pop_first_type_arg(&self) -> (Ty, Self) {
213 let mut generics = self.clone();
214 let mut it = mem::take(&mut generics.types).into_iter();
215 let ty = it.next().unwrap();
216 generics.types = it.collect();
217 (ty, generics)
218 }
219
220 pub fn concat(mut self, other: &Self) -> Self {
223 let Self {
224 regions,
225 types,
226 const_generics,
227 trait_refs,
228 } = other;
229 self.regions.clone_extend_from_other(regions);
230 self.types.clone_extend_from_other(types);
231 self.const_generics.clone_extend_from_other(const_generics);
232 self.trait_refs.clone_extend_from_other(trait_refs);
233 self
234 }
235}
236
237impl RegionArgs {
238 pub fn empty() -> Self {
239 Self {
240 regions: Default::default(),
241 }
242 }
243
244 pub fn erased(len: usize) -> Self {
245 Self::new(std::iter::repeat_n(Region::Erased, len).collect())
246 }
247
248 pub fn new(regions: IndexVec<RegionId, Region>) -> Self {
249 Self { regions }
250 }
251
252 pub fn iter(&self) -> impl DoubleEndedIterator<Item = &Region> + ExactSizeIterator {
253 self.regions.iter()
254 }
255
256 pub fn is_empty(&self) -> bool {
257 self.regions.is_empty()
258 }
259}
260
261impl GenericParams {
262 pub fn empty() -> Self {
263 Self::default()
264 }
265
266 pub fn is_empty(&self) -> bool {
267 self.len() == 0
268 }
269 pub fn has_explicits(&self) -> bool {
271 !self.regions.is_empty() || !self.types.is_empty() || !self.const_generics.is_empty()
272 }
273 pub fn has_predicates(&self) -> bool {
276 !self.trait_clauses.is_empty()
277 || !self.types_outlive.is_empty()
278 || !self.regions_outlive.is_empty()
279 || !self.trait_type_constraints.is_empty()
280 }
281
282 pub fn check_consistency(&self) {
284 assert!(
286 self.trait_clauses
287 .iter()
288 .enumerate()
289 .all(|(i, c)| c.clause_id.index() == i)
290 );
291
292 let mut s = HashSet::new();
297 for r in &self.regions {
298 if let Some(name) = &r.name {
299 assert!(
300 !s.contains(name),
301 "Name \"{}\" reused for two different lifetimes",
302 name
303 );
304 s.insert(name);
305 }
306 }
307 }
308
309 pub fn len(&self) -> usize {
310 let GenericParams {
311 regions,
312 types,
313 const_generics,
314 trait_clauses,
315 regions_outlive,
316 types_outlive,
317 trait_type_constraints,
318 } = self;
319 regions.len()
320 + types.len()
321 + const_generics.len()
322 + trait_clauses.len()
323 + regions_outlive.len()
324 + types_outlive.len()
325 + trait_type_constraints.len()
326 }
327
328 pub fn identity_args(&self) -> GenericArgs {
332 self.identity_args_at_depth(DeBruijnId::zero())
333 }
334
335 pub fn identity_args_at_depth(&self, depth: DeBruijnId) -> GenericArgs {
337 GenericArgs {
338 regions: self
339 .regions
340 .map_ref_indexed(|id, _| Region::Var(DeBruijnVar::bound(depth, id))),
341 types: self
342 .types
343 .map_ref_indexed(|id, _| TyKind::TypeVar(DeBruijnVar::bound(depth, id)).into_ty()),
344 const_generics: self.const_generics.map_ref_indexed(|id, c| {
345 ConstantExpr::new(
346 ConstantExprKind::Var(DeBruijnVar::bound(depth, id)),
347 c.ty.clone(),
348 )
349 }),
350 trait_refs: self
351 .trait_clauses
352 .map_ref(|clause| clause.identity_tref_at_depth(depth)),
353 }
354 }
355
356 pub fn take_predicates_from(&mut self, other: GenericParams) {
359 assert!(!other.has_explicits());
360 let num_clauses = self.trait_clauses.len();
361 let GenericParams {
362 regions: _,
363 types: _,
364 const_generics: _,
365 trait_clauses,
366 regions_outlive,
367 types_outlive,
368 trait_type_constraints,
369 } = other;
370 self.trait_clauses
371 .extend(trait_clauses.into_iter().update(|clause| {
372 clause.clause_id += num_clauses;
373 }));
374 self.regions_outlive.extend(regions_outlive);
375 self.types_outlive.extend(types_outlive);
376 self.trait_type_constraints.extend(trait_type_constraints);
377 }
378
379 pub fn merge_predicates_from(&mut self, mut other: GenericParams) {
383 other.types.clear();
385 other.regions.clear();
386 other.const_generics.clear();
387 struct ShiftClausesVisitor(usize);
389 impl VarsVisitor for ShiftClausesVisitor {
390 fn visit_clause_var(&mut self, v: ClauseDbVar) -> Option<ClauseReplacement> {
391 if let DeBruijnVar::Bound(DeBruijnId::ZERO, clause_id) = v {
392 Some(ClauseReplacement::Var(DeBruijnVar::Bound(
394 DeBruijnId::ZERO,
395 clause_id + self.0,
396 )))
397 } else {
398 None
399 }
400 }
401 }
402 let num_clauses = self.trait_clauses.len();
403 other.visit_vars(&mut ShiftClausesVisitor(num_clauses));
404 self.take_predicates_from(other);
405 }
406}
407
408impl<T> Binder<T> {
409 pub fn empty(kind: BinderKind, x: T) -> Self
411 where
412 T: TyVisitable,
413 {
414 Binder {
415 params: Default::default(),
416 skip_binder: x.move_under_binder(),
417 kind,
418 }
419 }
420 pub fn new(kind: BinderKind, params: GenericParams, skip_binder: T) -> Self {
421 Self {
422 params,
423 skip_binder,
424 kind,
425 }
426 }
427
428 pub fn binds_anything(&self) -> bool {
430 !self.params.is_empty()
431 }
432
433 pub fn get_if_binds_nothing(&self) -> Option<T>
436 where
437 T: TyVisitable + Clone,
438 {
439 self.params
440 .is_empty()
441 .then(|| self.skip_binder.clone().move_from_under_binder().unwrap())
442 }
443
444 pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Binder<U> {
445 Binder {
446 params: self.params,
447 skip_binder: f(self.skip_binder),
448 kind: self.kind,
449 }
450 }
451
452 pub fn map_ref<U>(&self, f: impl FnOnce(&T) -> U) -> Binder<U> {
453 Binder {
454 params: self.params.clone(),
455 skip_binder: f(&self.skip_binder),
456 kind: self.kind.clone(),
457 }
458 }
459
460 pub fn apply(self, args: &GenericArgs) -> T
463 where
464 T: TyVisitable,
465 {
466 self.skip_binder.substitute(args)
467 }
468
469 pub fn apply_keep_params(self, args: &GenericArgs) -> (GenericParams, T)
472 where
473 T: TyVisitable,
474 {
475 (
476 self.params.substitute(args),
477 self.skip_binder.substitute(args),
478 )
479 }
480}
481
482impl<T: AstVisitable> Binder<Binder<T>> {
483 pub fn flatten(self) -> Binder<T> {
485 #[derive(Visitor)]
486 struct FlattenVisitor<'a> {
487 shift_by: &'a GenericParams,
488 binder_depth: DeBruijnId,
489 }
490 impl VisitorWithBinderDepth for FlattenVisitor<'_> {
491 fn binder_depth_mut(&mut self) -> &mut DeBruijnId {
492 &mut self.binder_depth
493 }
494 }
495 impl VisitAstMut for FlattenVisitor<'_> {
496 fn visit<T: AstVisitable>(&mut self, x: &mut T) -> ControlFlow<Self::Break> {
497 VisitWithBinderDepth::new(self).visit(x)
498 }
499
500 fn enter_de_bruijn_id(&mut self, db_id: &mut DeBruijnId) {
501 if *db_id > self.binder_depth {
502 *db_id = db_id.decr();
507 }
508 }
509 fn enter_region(&mut self, x: &mut Region) {
510 if let Region::Var(var) = x
511 && let Some(id) = var.bound_at_depth_mut(self.binder_depth)
512 {
513 *id += self.shift_by.regions.len();
514 }
515 }
516 fn enter_ty_kind(&mut self, x: &mut TyKind) {
517 if let TyKind::TypeVar(var) = x
518 && let Some(id) = var.bound_at_depth_mut(self.binder_depth)
519 {
520 *id += self.shift_by.types.len();
521 }
522 }
523 fn enter_constant_expr_kind(&mut self, kind: &mut ConstantExprKind) {
524 if let ConstantExprKind::Var(var) = kind
525 && let Some(id) = var.bound_at_depth_mut(self.binder_depth)
526 {
527 *id += self.shift_by.const_generics.len();
528 }
529 }
530 fn enter_trait_ref_kind(&mut self, x: &mut TraitRefKind) {
531 if let TraitRefKind::Clause(var, _) = x
532 && let Some(id) = var.bound_at_depth_mut(self.binder_depth)
533 {
534 *id += self.shift_by.trait_clauses.len();
535 }
536 }
537 }
538
539 let mut outer_params = self.params;
541
542 let mut bound_value = self.skip_binder.skip_binder;
546 let _ = bound_value.drive_mut(&mut FlattenVisitor {
547 shift_by: &outer_params,
548 binder_depth: Default::default(),
549 });
550
551 let mut inner_params = self.skip_binder.params;
554 let _ = inner_params.drive_mut(&mut FlattenVisitor {
555 shift_by: &outer_params,
556 binder_depth: Default::default(),
557 });
558 inner_params
559 .regions
560 .iter_mut()
561 .for_each(|v| v.index += outer_params.regions.len());
562 inner_params
563 .types
564 .iter_mut()
565 .for_each(|v| v.index += outer_params.types.len());
566 inner_params
567 .const_generics
568 .iter_mut()
569 .for_each(|v| v.index += outer_params.const_generics.len());
570 inner_params
571 .trait_clauses
572 .iter_mut()
573 .for_each(|v| v.clause_id += outer_params.trait_clauses.len());
574
575 let GenericParams {
576 regions,
577 types,
578 const_generics,
579 trait_clauses,
580 regions_outlive,
581 types_outlive,
582 trait_type_constraints,
583 } = &inner_params;
584 outer_params.regions.clone_extend_from_other(regions);
585 outer_params.types.clone_extend_from_other(types);
586 outer_params
587 .const_generics
588 .clone_extend_from_other(const_generics);
589 outer_params
590 .trait_clauses
591 .clone_extend_from_other(trait_clauses);
592 outer_params
593 .regions_outlive
594 .extend_from_slice(regions_outlive);
595 outer_params.types_outlive.extend_from_slice(types_outlive);
596 outer_params
597 .trait_type_constraints
598 .clone_extend_from_other(trait_type_constraints);
599
600 Binder {
601 params: outer_params,
602 skip_binder: bound_value,
603 kind: BinderKind::Other,
604 }
605 }
606}
607
608impl<T> RegionBinder<T> {
609 pub fn empty(x: T) -> Self
611 where
612 T: TyVisitable,
613 {
614 RegionBinder {
615 regions: Default::default(),
616 regions_outlive: Default::default(),
617 types_outlive: Default::default(),
618 skip_binder: x.move_under_binder(),
619 }
620 }
621
622 pub fn to_params(&self) -> GenericParams {
624 GenericParams {
625 regions: self.regions.clone(),
626 regions_outlive: self.regions_outlive.clone(),
627 types_outlive: self.types_outlive.clone(),
628 ..GenericParams::default()
629 }
630 }
631
632 pub fn map<U>(self, f: impl FnOnce(T) -> U) -> RegionBinder<U> {
633 RegionBinder {
634 regions: self.regions,
635 regions_outlive: self.regions_outlive,
636 types_outlive: self.types_outlive,
637 skip_binder: f(self.skip_binder),
638 }
639 }
640
641 pub fn map_ref<U>(&self, f: impl FnOnce(&T) -> U) -> RegionBinder<U> {
642 RegionBinder {
643 regions: self.regions.clone(),
644 regions_outlive: self.regions_outlive.clone(),
645 types_outlive: self.types_outlive.clone(),
646 skip_binder: f(&self.skip_binder),
647 }
648 }
649
650 pub fn map_ref_opt<U>(&self, f: impl FnOnce(&T) -> Option<U>) -> Option<RegionBinder<U>> {
651 Some(RegionBinder {
652 regions: self.regions.clone(),
653 regions_outlive: self.regions_outlive.clone(),
654 types_outlive: self.types_outlive.clone(),
655 skip_binder: f(&self.skip_binder)?,
656 })
657 }
658
659 pub fn apply(self, args: RegionArgs) -> T
661 where
662 T: TyVisitable,
663 {
664 assert_eq!(args.regions.len(), self.regions.len());
665 let args = GenericArgs::new_lifetimes(args.regions);
666 self.skip_binder.substitute_inner_binder(&args)
667 }
668
669 pub fn apply_keep_params(
672 self,
673 args: RegionArgs,
674 ) -> (T, Vec<PolyRegionOutlives>, Vec<PolyTypeOutlives>)
675 where
676 T: TyVisitable,
677 {
678 assert_eq!(args.regions.len(), self.regions.len());
679 let args = GenericArgs::new_lifetimes(args.regions);
680 (
681 self.skip_binder.substitute_inner_binder(&args),
682 self.regions_outlive.substitute_inner_binder(&args),
683 self.types_outlive.substitute_inner_binder(&args),
684 )
685 }
686
687 #[track_caller]
689 pub fn no_bound_vars(self) -> T
690 where
691 T: TyVisitable,
692 {
693 assert!(self.regions.is_empty());
694 self.skip_binder.move_from_under_binder().unwrap()
695 }
696
697 pub fn erase(self) -> T
699 where
700 T: TyVisitable,
701 {
702 let args = RegionArgs::erased(self.regions.len());
703 self.apply(args)
704 }
705}
706
707pub trait HasIdxVecOf<Id: Idx>: std::ops::Index<Id, Output: Sized> {
708 fn get_idx_vec(&self) -> &IndexVec<Id, Self::Output>;
709 fn get_idx_vec_mut(&mut self) -> &mut IndexVec<Id, Self::Output>;
710}
711
712macro_rules! mk_index_impls {
714 ($ty:ident.$field:ident[$idx:ty]: $output:ty) => {
715 impl std::ops::Index<$idx> for $ty {
716 type Output = $output;
717 fn index(&self, index: $idx) -> &Self::Output {
718 &self.$field[index]
719 }
720 }
721 impl std::ops::IndexMut<$idx> for $ty {
722 fn index_mut(&mut self, index: $idx) -> &mut Self::Output {
723 &mut self.$field[index]
724 }
725 }
726 impl HasIdxVecOf<$idx> for $ty {
727 fn get_idx_vec(&self) -> &IndexVec<$idx, Self::Output> {
728 &self.$field
729 }
730 fn get_idx_vec_mut(&mut self) -> &mut IndexVec<$idx, Self::Output> {
731 &mut self.$field
732 }
733 }
734 };
735}
736mk_index_impls!(GenericArgs.regions[RegionId]: Region);
737mk_index_impls!(GenericArgs.types[TypeVarId]: Ty);
738mk_index_impls!(GenericArgs.const_generics[ConstGenericVarId]: ConstantExpr);
739mk_index_impls!(GenericArgs.trait_refs[TraitClauseId]: PolyTraitRef);
740mk_index_impls!(GenericParams.regions[RegionId]: RegionParam);
741mk_index_impls!(GenericParams.types[TypeVarId]: TypeParam);
742mk_index_impls!(GenericParams.const_generics[ConstGenericVarId]: ConstGenericParam);
743mk_index_impls!(GenericParams.trait_clauses[TraitClauseId]: TraitParam);
744
745impl FromIterator<Region> for RegionArgs {
746 fn from_iter<T: IntoIterator<Item = Region>>(iter: T) -> Self {
747 Self::new(iter.into_iter().collect())
748 }
749}