1
- use crate :: ty:: { self , Ty , TyCtxt , TyVid , RegionVid } ;
1
+ use crate :: ty:: { self , Ty , TyCtxt , TyVid , IntVid , FloatVid , RegionVid } ;
2
2
use crate :: ty:: fold:: { TypeFoldable , TypeFolder } ;
3
3
4
4
use super :: InferCtxt ;
@@ -56,7 +56,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
56
56
{
57
57
debug ! ( "fudge_inference_if_ok(origin={:?})" , origin) ;
58
58
59
- let ( type_variables , region_vars, value) = self . probe ( |snapshot| {
59
+ let ( type_vars , int_vars , float_vars , region_vars, value) = self . probe ( |snapshot| {
60
60
match f ( ) {
61
61
Ok ( value) => {
62
62
let value = self . resolve_type_vars_if_possible ( & value) ;
@@ -67,14 +67,20 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
67
67
// going to be popped, so we will have to
68
68
// eliminate any references to them.
69
69
70
- let type_variables = self . type_variables . borrow_mut ( ) . vars_since_snapshot (
70
+ let type_vars = self . type_variables . borrow_mut ( ) . vars_since_snapshot (
71
71
& snapshot. type_snapshot ,
72
72
) ;
73
+ let int_vars = self . int_unification_table . borrow_mut ( ) . vars_since_snapshot (
74
+ & snapshot. int_snapshot ,
75
+ ) ;
76
+ let float_vars = self . float_unification_table . borrow_mut ( ) . vars_since_snapshot (
77
+ & snapshot. float_snapshot ,
78
+ ) ;
73
79
let region_vars = self . borrow_region_constraints ( ) . vars_since_snapshot (
74
80
& snapshot. region_constraints_snapshot ,
75
81
) ;
76
82
77
- Ok ( ( type_variables , region_vars, value) )
83
+ Ok ( ( type_vars , int_vars , float_vars , region_vars, value) )
78
84
}
79
85
Err ( e) => Err ( e) ,
80
86
}
@@ -87,13 +93,18 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
87
93
88
94
// Micro-optimization: if no variables have been created, then
89
95
// `value` can't refer to any of them. =) So we can just return it.
90
- if type_variables. is_empty ( ) && region_vars. is_empty ( ) {
96
+ if type_vars. is_empty ( ) &&
97
+ int_vars. is_empty ( ) &&
98
+ float_vars. is_empty ( ) &&
99
+ region_vars. is_empty ( ) {
91
100
return Ok ( value) ;
92
101
}
93
102
94
103
let mut fudger = InferenceFudger {
95
104
infcx : self ,
96
- type_variables : & type_variables,
105
+ type_vars : & type_vars,
106
+ int_vars : & int_vars,
107
+ float_vars : & float_vars,
97
108
region_vars : & region_vars,
98
109
origin,
99
110
} ;
@@ -104,7 +115,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
104
115
105
116
pub struct InferenceFudger < ' a , ' gcx : ' a +' tcx , ' tcx : ' a > {
106
117
infcx : & ' a InferCtxt < ' a , ' gcx , ' tcx > ,
107
- type_variables : & ' a Range < TyVid > ,
118
+ type_vars : & ' a Range < TyVid > ,
119
+ int_vars : & ' a Range < IntVid > ,
120
+ float_vars : & ' a Range < FloatVid > ,
108
121
region_vars : & ' a Range < RegionVid > ,
109
122
origin : & ' a RegionVariableOrigin ,
110
123
}
@@ -117,7 +130,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for InferenceFudger<'a, 'gcx, 'tcx>
117
130
fn fold_ty ( & mut self , ty : Ty < ' tcx > ) -> Ty < ' tcx > {
118
131
match ty. sty {
119
132
ty:: Infer ( ty:: InferTy :: TyVar ( vid) ) => {
120
- if self . type_variables . contains ( & vid) {
133
+ if self . type_vars . contains ( & vid) {
121
134
// This variable was created during the fudging.
122
135
// Recreate it with a fresh variable here.
123
136
let origin = self . infcx . type_variables . borrow ( ) . var_origin ( vid) . clone ( ) ;
@@ -134,6 +147,20 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for InferenceFudger<'a, 'gcx, 'tcx>
134
147
ty
135
148
}
136
149
}
150
+ ty:: Infer ( ty:: InferTy :: IntVar ( vid) ) => {
151
+ if self . int_vars . contains ( & vid) {
152
+ self . infcx . tcx . mk_int_var ( self . infcx . next_int_var_id ( ) )
153
+ } else {
154
+ ty
155
+ }
156
+ }
157
+ ty:: Infer ( ty:: InferTy :: FloatVar ( vid) ) => {
158
+ if self . float_vars . contains ( & vid) {
159
+ self . infcx . tcx . mk_float_var ( self . infcx . next_float_var_id ( ) )
160
+ } else {
161
+ ty
162
+ }
163
+ }
137
164
_ => ty. super_fold_with ( self ) ,
138
165
}
139
166
}
0 commit comments