]>
Commit | Line | Data |
---|---|---|
cdc7bbd5 | 1 | use crate::mir; |
dfeec247 | 2 | use crate::ty::fold::{TypeFoldable, TypeFolder}; |
9fa01778 | 3 | use crate::ty::{self, Ty, TyCtxt, TypeFlags}; |
abe05a73 | 4 | |
f035d41b | 5 | pub(super) fn provide(providers: &mut ty::query::Providers) { |
dfeec247 | 6 | *providers = ty::query::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 XL |
20 | where |
21 | T: TypeFoldable<'tcx>, | |
abe05a73 | 22 | { |
9fa01778 | 23 | // If there's nothing to erase avoid performing the query at all |
94222f64 XL |
24 | if !value |
25 | .has_type_flags(TypeFlags::HAS_RE_LATE_BOUND | TypeFlags::HAS_POTENTIAL_FREE_REGIONS) | |
26 | { | |
fc512014 | 27 | return value; |
9fa01778 | 28 | } |
fc512014 | 29 | debug!("erase_regions({:?})", value); |
abe05a73 | 30 | let value1 = value.fold_with(&mut RegionEraserVisitor { tcx: self }); |
fc512014 | 31 | debug!("erase_regions = {:?}", value1); |
abe05a73 XL |
32 | value1 |
33 | } | |
34 | } | |
35 | ||
dc9dc135 XL |
36 | struct RegionEraserVisitor<'tcx> { |
37 | tcx: TyCtxt<'tcx>, | |
abe05a73 XL |
38 | } |
39 | ||
a2a8927a | 40 | impl<'tcx> TypeFolder<'tcx> for RegionEraserVisitor<'tcx> { |
dc9dc135 | 41 | fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { |
abe05a73 XL |
42 | self.tcx |
43 | } | |
44 | ||
45 | fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { | |
ba9703b0 | 46 | if ty.needs_infer() { ty.super_fold_with(self) } else { self.tcx.erase_regions_ty(ty) } |
abe05a73 XL |
47 | } |
48 | ||
cdc7bbd5 | 49 | fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T> |
dfeec247 XL |
50 | where |
51 | T: TypeFoldable<'tcx>, | |
abe05a73 XL |
52 | { |
53 | let u = self.tcx.anonymize_late_bound_regions(t); | |
54 | u.super_fold_with(self) | |
55 | } | |
56 | ||
57 | fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { | |
58 | // because late-bound regions affect subtyping, we can't | |
59 | // erase the bound/free distinction, but we can replace | |
60 | // all free regions with 'erased. | |
61 | // | |
62 | // Note that we *CAN* replace early-bound regions -- the | |
63 | // type system never "sees" those, they get substituted | |
94b46f34 | 64 | // away. In codegen, they will always be erased to 'erased |
abe05a73 XL |
65 | // whenever a substitution occurs. |
66 | match *r { | |
67 | ty::ReLateBound(..) => r, | |
dfeec247 | 68 | _ => self.tcx.lifetimes.re_erased, |
abe05a73 XL |
69 | } |
70 | } | |
cdc7bbd5 XL |
71 | |
72 | fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> { | |
73 | c.super_fold_with(self) | |
74 | } | |
abe05a73 | 75 | } |