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