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
8use crate::delegate::SolverDelegate;
9
10pub struct EagerResolver<'a, D, I = <D as SolverDelegate>::Interner>
15where
16 D: SolverDelegate<Interner = I>,
17 I: Interner,
18{
19 delegate: &'a D,
20 cache: DelayedMap<I::Ty, I::Ty>,
23}
24
25impl<'a, D: SolverDelegate> EagerResolver<'a, D> {
26 pub fn new(delegate: &'a D) -> Self {
27 EagerResolver { delegate, cache: Default::default() }
28 }
29}
30
31impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for EagerResolver<'_, D> {
32 fn cx(&self) -> I {
33 self.delegate.cx()
34 }
35
36 fn fold_ty(&mut self, t: I::Ty) -> I::Ty {
37 match t.kind() {
38 ty::Infer(ty::TyVar(vid)) => {
39 let resolved = self.delegate.opportunistic_resolve_ty_var(vid);
40 if t != resolved && resolved.has_infer() {
41 resolved.fold_with(self)
42 } else {
43 resolved
44 }
45 }
46 ty::Infer(ty::IntVar(vid)) => self.delegate.opportunistic_resolve_int_var(vid),
47 ty::Infer(ty::FloatVar(vid)) => self.delegate.opportunistic_resolve_float_var(vid),
48 _ => {
49 if t.has_infer() {
50 if let Some(&ty) = self.cache.get(&t) {
51 return ty;
52 }
53 let res = t.super_fold_with(self);
54 assert!(self.cache.insert(t, res));
55 res
56 } else {
57 t
58 }
59 }
60 }
61 }
62
63 fn fold_region(&mut self, r: I::Region) -> I::Region {
64 match r.kind() {
65 ty::ReVar(vid) => self.delegate.opportunistic_resolve_lt_var(vid),
66 _ => r,
67 }
68 }
69
70 fn fold_const(&mut self, c: I::Const) -> I::Const {
71 match c.kind() {
72 ty::ConstKind::Infer(ty::InferConst::Var(vid)) => {
73 let resolved = self.delegate.opportunistic_resolve_ct_var(vid);
74 if c != resolved && resolved.has_infer() {
75 resolved.fold_with(self)
76 } else {
77 resolved
78 }
79 }
80 _ => {
81 if c.has_infer() {
82 c.super_fold_with(self)
83 } else {
84 c
85 }
86 }
87 }
88 }
89}