rustc_infer/infer/
resolve.rs1use rustc_middle::ty::{
2 self, Const, DelayedMap, FallibleTypeFolder, InferConst, Ty, TyCtxt, TypeFoldable, TypeFolder,
3 TypeSuperFoldable, TypeVisitableExt,
4};
5use rustc_span::bug;
6use rustc_type_ir::PredicateProxy;
7
8use super::{FixupError, FixupResult, InferCtxt};
9use crate::infer::TyOrConstInferVar;
10
11pub struct DeepResolverIgnoringRegions<'a, 'tcx> {
20 infcx: &'a InferCtxt<'tcx>,
21 cache: DelayedMap<Ty<'tcx>, Ty<'tcx>>,
24}
25
26impl<'a, 'tcx> DeepResolverIgnoringRegions<'a, 'tcx> {
27 #[inline]
28 pub fn new(infcx: &'a InferCtxt<'tcx>) -> Self {
29 DeepResolverIgnoringRegions { infcx, cache: Default::default() }
30 }
31}
32
33impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for DeepResolverIgnoringRegions<'a, 'tcx> {
34 fn cx(&self) -> TyCtxt<'tcx> {
35 self.infcx.tcx
36 }
37
38 #[inline]
39 fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
40 if !t.has_non_region_infer() {
41 t } else if let Some(&ty) = self.cache.get(&t) {
43 ty
44 } else {
45 let shallow = self.infcx.shallow_resolve(t);
46 let res = shallow.super_fold_with(self);
47 if !self.cache.insert(t, res) {
::core::panicking::panic("assertion failed: self.cache.insert(t, res)")
};assert!(self.cache.insert(t, res));
48 res
49 }
50 }
51
52 fn fold_const(&mut self, ct: Const<'tcx>) -> Const<'tcx> {
53 if !ct.has_non_region_infer() {
54 ct } else {
56 let ct = self.infcx.shallow_resolve_const(ct);
57 ct.super_fold_with(self)
58 }
59 }
60
61 fn fold_predicate<P: PredicateProxy<TyCtxt<'tcx>>>(&mut self, p: P) -> P {
62 if !p.has_non_region_infer() { p } else { p.super_fold_with(self) }
63 }
64
65 fn fold_clauses(&mut self, c: ty::Clauses<'tcx>) -> ty::Clauses<'tcx> {
66 if !c.has_non_region_infer() { c } else { c.super_fold_with(self) }
67 }
68}
69
70pub fn deeply_resolve_via_region_graph<'tcx, T>(infcx: &InferCtxt<'tcx>, value: T) -> FixupResult<T>
77where
78 T: TypeFoldable<TyCtxt<'tcx>>,
79{
80 value.try_fold_with(&mut FullTypeResolver { infcx })
81}
82
83struct FullTypeResolver<'a, 'tcx> {
84 infcx: &'a InferCtxt<'tcx>,
85}
86
87impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for FullTypeResolver<'a, 'tcx> {
88 type Error = FixupError;
89
90 fn cx(&self) -> TyCtxt<'tcx> {
91 self.infcx.tcx
92 }
93
94 fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
95 if !t.has_infer() {
96 Ok(t) } else {
98 let t = self.infcx.shallow_resolve(t);
99 match *t.kind() {
100 ty::Infer(ty::TyVar(vid)) => {
101 Err(FixupError { unresolved: TyOrConstInferVar::Ty(vid) })
102 }
103 ty::Infer(ty::IntVar(vid)) => {
104 Err(FixupError { unresolved: TyOrConstInferVar::TyInt(vid) })
105 }
106 ty::Infer(ty::FloatVar(vid)) => {
107 Err(FixupError { unresolved: TyOrConstInferVar::TyFloat(vid) })
108 }
109 ty::Infer(_) => {
110 bug_impl(None,
format_args!("Unexpected type in full type resolver: {0:?}", t),
Location::caller());bug!("Unexpected type in full type resolver: {:?}", t);
111 }
112 _ => t.try_super_fold_with(self),
113 }
114 }
115 }
116
117 fn try_fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
118 match r.kind() {
119 ty::ReVar(_) => Ok(self
120 .infcx
121 .lexical_region_resolutions
122 .borrow()
123 .as_ref()
124 .expect("region resolution not performed")
125 .resolve_region(self.infcx.tcx, r)),
126 _ => Ok(r),
127 }
128 }
129
130 fn try_fold_const(&mut self, c: ty::Const<'tcx>) -> Result<ty::Const<'tcx>, Self::Error> {
131 if !c.has_infer() {
132 Ok(c) } else {
134 let c = self.infcx.shallow_resolve_const(c);
135 match c.kind() {
136 ty::ConstKind::Infer(InferConst::Var(vid)) => {
137 return Err(FixupError { unresolved: super::TyOrConstInferVar::Const(vid) });
138 }
139 ty::ConstKind::Infer(InferConst::Fresh(_)) => {
140 bug_impl(None,
format_args!("Unexpected const in full const resolver: {0:?}", c),
Location::caller());bug!("Unexpected const in full const resolver: {:?}", c);
141 }
142 _ => {}
143 }
144 c.try_super_fold_with(self)
145 }
146 }
147}