]>
Commit | Line | Data |
---|---|---|
49aad941 | 1 | use crate::query::Providers; |
923072b8 | 2 | use crate::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; |
9ffffee4 | 3 | use crate::ty::{self, Ty, TyCtxt, TypeFlags, TypeVisitableExt}; |
abe05a73 | 4 | |
49aad941 FG |
5 | pub(super) fn provide(providers: &mut Providers) { |
6 | *providers = Providers { erase_regions_ty, ..*providers }; | |
abe05a73 XL |
7 | } |
8 | ||
dc9dc135 | 9 | fn erase_regions_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { |
0731742a | 10 | // N.B., use `super_fold_with` here. If we used `fold_with`, it |
abe05a73 XL |
11 | // could invoke the `erase_regions_ty` query recursively. |
12 | ty.super_fold_with(&mut RegionEraserVisitor { tcx }) | |
13 | } | |
14 | ||
dc9dc135 | 15 | impl<'tcx> TyCtxt<'tcx> { |
abe05a73 XL |
16 | /// Returns an equivalent value with all free regions removed (note |
17 | /// that late-bound regions remain, because they are important for | |
18 | /// subtyping, but they are anonymized and normalized as well).. | |
fc512014 | 19 | pub fn erase_regions<T>(self, value: T) -> T |
dfeec247 | 20 | where |
9ffffee4 | 21 | T: TypeFoldable<TyCtxt<'tcx>>, |
abe05a73 | 22 | { |
9fa01778 | 23 | // If there's nothing to erase avoid performing the query at all |
9c376795 | 24 | if !value.has_type_flags(TypeFlags::HAS_LATE_BOUND | TypeFlags::HAS_FREE_REGIONS) { |
fc512014 | 25 | return value; |
9fa01778 | 26 | } |
fc512014 | 27 | debug!("erase_regions({:?})", value); |
abe05a73 | 28 | let value1 = value.fold_with(&mut RegionEraserVisitor { tcx: self }); |
fc512014 | 29 | debug!("erase_regions = {:?}", value1); |
abe05a73 XL |
30 | value1 |
31 | } | |
32 | } | |
33 | ||
dc9dc135 XL |
34 | struct RegionEraserVisitor<'tcx> { |
35 | tcx: TyCtxt<'tcx>, | |
abe05a73 XL |
36 | } |
37 | ||
9ffffee4 FG |
38 | impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RegionEraserVisitor<'tcx> { |
39 | fn interner(&self) -> TyCtxt<'tcx> { | |
abe05a73 XL |
40 | self.tcx |
41 | } | |
42 | ||
43 | fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { | |
49aad941 | 44 | if ty.has_infer() { ty.super_fold_with(self) } else { self.tcx.erase_regions_ty(ty) } |
abe05a73 XL |
45 | } |
46 | ||
cdc7bbd5 | 47 | fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T> |
dfeec247 | 48 | where |
9ffffee4 | 49 | T: TypeFoldable<TyCtxt<'tcx>>, |
abe05a73 | 50 | { |
064997fb | 51 | let u = self.tcx.anonymize_bound_vars(t); |
abe05a73 XL |
52 | u.super_fold_with(self) |
53 | } | |
54 | ||
55 | fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { | |
56 | // because late-bound regions affect subtyping, we can't | |
57 | // erase the bound/free distinction, but we can replace | |
58 | // all free regions with 'erased. | |
59 | // | |
60 | // Note that we *CAN* replace early-bound regions -- the | |
61 | // type system never "sees" those, they get substituted | |
94b46f34 | 62 | // away. In codegen, they will always be erased to 'erased |
abe05a73 XL |
63 | // whenever a substitution occurs. |
64 | match *r { | |
65 | ty::ReLateBound(..) => r, | |
dfeec247 | 66 | _ => self.tcx.lifetimes.re_erased, |
abe05a73 XL |
67 | } |
68 | } | |
69 | } |