rustc_middle/ty/
erase_regions.rs1use tracing::debug;
2
3use crate::query::Providers;
4use crate::ty::{
5    self, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
6};
7
8pub(super) fn provide(providers: &mut Providers) {
9    *providers = Providers { erase_and_anonymize_regions_ty, ..*providers };
10}
11
12fn erase_and_anonymize_regions_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
13    ty.super_fold_with(&mut RegionEraserAndAnonymizerVisitor { tcx })
16}
17
18impl<'tcx> TyCtxt<'tcx> {
19    pub fn erase_and_anonymize_regions<T>(self, value: T) -> T
23    where
24        T: TypeFoldable<TyCtxt<'tcx>>,
25    {
26        if !value.has_type_flags(TypeFlags::HAS_BINDER_VARS | TypeFlags::HAS_FREE_REGIONS) {
28            return value;
29        }
30        debug!("erase_and_anonymize_regions({:?})", value);
31        let value1 = value.fold_with(&mut RegionEraserAndAnonymizerVisitor { tcx: self });
32        debug!("erase_and_anonymize_regions = {:?}", value1);
33        value1
34    }
35}
36
37struct RegionEraserAndAnonymizerVisitor<'tcx> {
38    tcx: TyCtxt<'tcx>,
39}
40
41impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RegionEraserAndAnonymizerVisitor<'tcx> {
42    fn cx(&self) -> TyCtxt<'tcx> {
43        self.tcx
44    }
45
46    fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
47        if !ty.has_type_flags(TypeFlags::HAS_BINDER_VARS | TypeFlags::HAS_FREE_REGIONS) {
48            ty
49        } else if ty.has_infer() {
50            ty.super_fold_with(self)
51        } else {
52            self.tcx.erase_and_anonymize_regions_ty(ty)
53        }
54    }
55
56    fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T>
57    where
58        T: TypeFoldable<TyCtxt<'tcx>>,
59    {
60        let u = self.tcx.anonymize_bound_vars(t);
61        u.super_fold_with(self)
62    }
63
64    fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
65        match r.kind() {
69            ty::ReBound(..) => r,
70            _ => self.tcx.lifetimes.re_erased,
71        }
72    }
73
74    fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
75        if ct.has_type_flags(TypeFlags::HAS_BINDER_VARS | TypeFlags::HAS_FREE_REGIONS) {
76            ct.super_fold_with(self)
77        } else {
78            ct
79        }
80    }
81
82    fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
83        if p.has_type_flags(TypeFlags::HAS_BINDER_VARS | TypeFlags::HAS_FREE_REGIONS) {
84            p.super_fold_with(self)
85        } else {
86            p
87        }
88    }
89
90    fn fold_clauses(&mut self, c: ty::Clauses<'tcx>) -> ty::Clauses<'tcx> {
91        if c.has_type_flags(TypeFlags::HAS_BINDER_VARS | TypeFlags::HAS_FREE_REGIONS) {
92            c.super_fold_with(self)
93        } else {
94            c
95        }
96    }
97}