Skip to main content

rustc_middle/ty/
erase_regions.rs

1use rustc_type_ir::PredicateProxy;
2use tracing::debug;
3
4use crate::query::Providers;
5use crate::ty::{
6    self, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
7};
8
9pub(super) fn provide(providers: &mut Providers) {
10    *providers = Providers { erase_and_anonymize_regions_ty, ..*providers };
11}
12
13fn erase_and_anonymize_regions_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
14    // N.B., use `super_fold_with` here. If we used `fold_with`, it
15    // could invoke the `erase_and_anonymize_regions_ty` query recursively.
16    ty.super_fold_with(&mut RegionEraserAndAnonymizerVisitor { tcx })
17}
18
19impl<'tcx> TyCtxt<'tcx> {
20    /// Returns an equivalent value with all free regions removed and
21    /// bound regions anonymized. (note that bound regions are important
22    /// for subtyping and generally type equality so *cannot* be removed)
23    pub fn erase_and_anonymize_regions<T>(self, value: T) -> T
24    where
25        T: TypeFoldable<TyCtxt<'tcx>>,
26    {
27        // If there's nothing to erase or anonymize, avoid performing the query at all
28        if !value.has_type_flags(TypeFlags::HAS_BINDER_VARS | TypeFlags::HAS_FREE_REGIONS) {
29            return value;
30        }
31        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/f7575a9da8e4a4fca3b5668d5a2ea7476db44b3f/compiler/rustc_middle/src/ty/erase_regions.rs:31",
                        "rustc_middle::ty::erase_regions", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/f7575a9da8e4a4fca3b5668d5a2ea7476db44b3f/compiler/rustc_middle/src/ty/erase_regions.rs"),
                        ::tracing_core::__macro_support::Option::Some(31u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_middle::ty::erase_regions"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("erase_and_anonymize_regions({0:?})",
                                                    value) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("erase_and_anonymize_regions({:?})", value);
32        let value1 = value.fold_with(&mut RegionEraserAndAnonymizerVisitor { tcx: self });
33        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/f7575a9da8e4a4fca3b5668d5a2ea7476db44b3f/compiler/rustc_middle/src/ty/erase_regions.rs:33",
                        "rustc_middle::ty::erase_regions", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/f7575a9da8e4a4fca3b5668d5a2ea7476db44b3f/compiler/rustc_middle/src/ty/erase_regions.rs"),
                        ::tracing_core::__macro_support::Option::Some(33u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_middle::ty::erase_regions"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("erase_and_anonymize_regions = {0:?}",
                                                    value1) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("erase_and_anonymize_regions = {:?}", value1);
34        value1
35    }
36}
37
38struct RegionEraserAndAnonymizerVisitor<'tcx> {
39    tcx: TyCtxt<'tcx>,
40}
41
42impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RegionEraserAndAnonymizerVisitor<'tcx> {
43    fn cx(&self) -> TyCtxt<'tcx> {
44        self.tcx
45    }
46
47    fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
48        if !ty.has_type_flags(TypeFlags::HAS_BINDER_VARS | TypeFlags::HAS_FREE_REGIONS) {
49            ty
50        } else if ty.has_infer() {
51            ty.super_fold_with(self)
52        } else {
53            self.tcx.erase_and_anonymize_regions_ty(ty)
54        }
55    }
56
57    fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T>
58    where
59        T: TypeFoldable<TyCtxt<'tcx>>,
60    {
61        let u = self.tcx.anonymize_bound_vars(t);
62        u.super_fold_with(self)
63    }
64
65    fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
66        // We must not erase bound regions. `for<'a> fn(&'a ())` and
67        // `fn(&'free ())` are different types: they may implement different
68        // traits and have a different `TypeId`.
69        match r.kind() {
70            ty::ReBound(..) => r,
71            _ => self.tcx.lifetimes.re_erased,
72        }
73    }
74
75    fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
76        if ct.has_type_flags(TypeFlags::HAS_BINDER_VARS | TypeFlags::HAS_FREE_REGIONS) {
77            ct.super_fold_with(self)
78        } else {
79            ct
80        }
81    }
82
83    fn fold_predicate<P: PredicateProxy<TyCtxt<'tcx>>>(&mut self, p: P) -> P {
84        if p.has_type_flags(TypeFlags::HAS_BINDER_VARS | TypeFlags::HAS_FREE_REGIONS) {
85            p.super_fold_with(self)
86        } else {
87            p
88        }
89    }
90
91    fn fold_clauses(&mut self, c: ty::Clauses<'tcx>) -> ty::Clauses<'tcx> {
92        if c.has_type_flags(TypeFlags::HAS_BINDER_VARS | TypeFlags::HAS_FREE_REGIONS) {
93            c.super_fold_with(self)
94        } else {
95            c
96        }
97    }
98}