rustc_next_trait_solver/
resolve.rs1use rustc_type_ir::data_structures::DelayedMap;
2use rustc_type_ir::inherent::*;
3use rustc_type_ir::{
4 self as ty, InferCtxtLike, Interner, TypeFoldable, TypeFolder, TypeSuperFoldable,
5 TypeVisitableExt,
6};
7
8struct EagerResolver<'a, D, I = <D as InferCtxtLike>::Interner>
13where
14 D: InferCtxtLike<Interner = I>,
15 I: Interner,
16{
17 delegate: &'a D,
18 cache: DelayedMap<I::Ty, I::Ty>,
21}
22
23pub fn eager_resolve_vars<Infcx: InferCtxtLike, T: TypeFoldable<Infcx::Interner>>(
24 infcx: &Infcx,
25 value: T,
26) -> T {
27 if value.has_infer() {
28 let mut folder = EagerResolver::new(infcx);
29 value.fold_with(&mut folder)
30 } else {
31 value
32 }
33}
34
35impl<'a, Infcx: InferCtxtLike> EagerResolver<'a, Infcx> {
36 fn new(delegate: &'a Infcx) -> Self {
37 EagerResolver { delegate, cache: Default::default() }
38 }
39}
40
41impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I> for EagerResolver<'_, Infcx> {
42 fn cx(&self) -> I {
43 self.delegate.cx()
44 }
45
46 fn fold_ty(&mut self, t: I::Ty) -> I::Ty {
47 match t.kind() {
48 ty::Infer(ty::TyVar(vid)) => {
49 let resolved = self.delegate.opportunistic_resolve_ty_var(vid);
50 if t != resolved && resolved.has_infer() {
51 resolved.fold_with(self)
52 } else {
53 resolved
54 }
55 }
56 ty::Infer(ty::IntVar(vid)) => self.delegate.opportunistic_resolve_int_var(vid),
57 ty::Infer(ty::FloatVar(vid)) => self.delegate.opportunistic_resolve_float_var(vid),
58 _ => {
59 if t.has_infer() {
60 if let Some(&ty) = self.cache.get(&t) {
61 return ty;
62 }
63 let res = t.super_fold_with(self);
64 if !self.cache.insert(t, res) {
::core::panicking::panic("assertion failed: self.cache.insert(t, res)")
};assert!(self.cache.insert(t, res));
65 res
66 } else {
67 t
68 }
69 }
70 }
71 }
72
73 fn fold_region(&mut self, r: I::Region) -> I::Region {
74 match r.kind() {
75 ty::ReVar(vid) => self.delegate.opportunistic_resolve_lt_var(vid),
76 _ => r,
77 }
78 }
79
80 fn fold_const(&mut self, c: I::Const) -> I::Const {
81 match c.kind() {
82 ty::ConstKind::Infer(ty::InferConst::Var(vid)) => {
83 let resolved = self.delegate.opportunistic_resolve_ct_var(vid);
84 if c != resolved && resolved.has_infer() {
85 resolved.fold_with(self)
86 } else {
87 resolved
88 }
89 }
90 _ => {
91 if c.has_infer() {
92 c.super_fold_with(self)
93 } else {
94 c
95 }
96 }
97 }
98 }
99
100 fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate {
101 if p.has_infer() { p.super_fold_with(self) } else { p }
102 }
103
104 fn fold_clauses(&mut self, c: I::Clauses) -> I::Clauses {
105 if c.has_infer() { c.super_fold_with(self) } else { c }
106 }
107}