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