31
31
//! variable only once, and it does so as soon as it can, so it is reasonable to ask what the type
32
32
//! inferencer knows "so far".
33
33
34
+ use crate :: mir:: interpret:: ConstValue ;
34
35
use crate :: ty:: { self , Ty , TyCtxt , TypeFoldable } ;
35
36
use crate :: ty:: fold:: TypeFolder ;
36
37
use crate :: util:: nodemap:: FxHashMap ;
@@ -42,42 +43,74 @@ use super::unify_key::ToType;
42
43
43
44
pub struct TypeFreshener < ' a , ' gcx : ' a +' tcx , ' tcx : ' a > {
44
45
infcx : & ' a InferCtxt < ' a , ' gcx , ' tcx > ,
45
- freshen_count : u32 ,
46
- freshen_map : FxHashMap < ty:: InferTy , Ty < ' tcx > > ,
46
+ ty_freshen_count : u32 ,
47
+ const_freshen_count : u32 ,
48
+ ty_freshen_map : FxHashMap < ty:: InferTy , Ty < ' tcx > > ,
49
+ const_freshen_map : FxHashMap < ty:: InferConst < ' tcx > , & ' tcx ty:: LazyConst < ' tcx > > ,
47
50
}
48
51
49
52
impl < ' a , ' gcx , ' tcx > TypeFreshener < ' a , ' gcx , ' tcx > {
50
53
pub fn new ( infcx : & ' a InferCtxt < ' a , ' gcx , ' tcx > )
51
54
-> TypeFreshener < ' a , ' gcx , ' tcx > {
52
55
TypeFreshener {
53
56
infcx,
54
- freshen_count : 0 ,
55
- freshen_map : Default :: default ( ) ,
57
+ ty_freshen_count : 0 ,
58
+ const_freshen_count : 0 ,
59
+ ty_freshen_map : Default :: default ( ) ,
60
+ const_freshen_map : Default :: default ( ) ,
56
61
}
57
62
}
58
63
59
- fn freshen < F > ( & mut self ,
60
- opt_ty : Option < Ty < ' tcx > > ,
61
- key : ty:: InferTy ,
62
- freshener : F )
63
- -> Ty < ' tcx > where
64
+ fn freshen_ty < F > (
65
+ & mut self ,
66
+ opt_ty : Option < Ty < ' tcx > > ,
67
+ key : ty:: InferTy ,
68
+ freshener : F ,
69
+ ) -> Ty < ' tcx >
70
+ where
64
71
F : FnOnce ( u32 ) -> ty:: InferTy ,
65
72
{
66
73
if let Some ( ty) = opt_ty {
67
74
return ty. fold_with ( self ) ;
68
75
}
69
76
70
- match self . freshen_map . entry ( key) {
77
+ match self . ty_freshen_map . entry ( key) {
71
78
Entry :: Occupied ( entry) => * entry. get ( ) ,
72
79
Entry :: Vacant ( entry) => {
73
- let index = self . freshen_count ;
74
- self . freshen_count += 1 ;
80
+ let index = self . ty_freshen_count ;
81
+ self . ty_freshen_count += 1 ;
75
82
let t = self . infcx . tcx . mk_ty_infer ( freshener ( index) ) ;
76
83
entry. insert ( t) ;
77
84
t
78
85
}
79
86
}
80
87
}
88
+
89
+ fn freshen_const < F > (
90
+ & mut self ,
91
+ opt_ct : Option < & ' tcx ty:: LazyConst < ' tcx > > ,
92
+ key : ty:: InferConst < ' tcx > ,
93
+ freshener : F ,
94
+ ty : Ty < ' tcx > ,
95
+ ) -> & ' tcx ty:: LazyConst < ' tcx >
96
+ where
97
+ F : FnOnce ( u32 ) -> ty:: InferConst < ' tcx > ,
98
+ {
99
+ if let Some ( ct) = opt_ct {
100
+ return ct. fold_with ( self ) ;
101
+ }
102
+
103
+ match self . const_freshen_map . entry ( key) {
104
+ Entry :: Occupied ( entry) => * entry. get ( ) ,
105
+ Entry :: Vacant ( entry) => {
106
+ let index = self . const_freshen_count ;
107
+ self . const_freshen_count += 1 ;
108
+ let ct = self . infcx . tcx . mk_const_infer ( freshener ( index) , ty) ;
109
+ entry. insert ( ct) ;
110
+ ct
111
+ }
112
+ }
113
+ }
81
114
}
82
115
83
116
impl < ' a , ' gcx , ' tcx > TypeFolder < ' gcx , ' tcx > for TypeFreshener < ' a , ' gcx , ' tcx > {
@@ -124,14 +157,14 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
124
157
match t. sty {
125
158
ty:: Infer ( ty:: TyVar ( v) ) => {
126
159
let opt_ty = self . infcx . type_variables . borrow_mut ( ) . probe ( v) . known ( ) ;
127
- self . freshen (
160
+ self . freshen_ty (
128
161
opt_ty,
129
162
ty:: TyVar ( v) ,
130
163
ty:: FreshTy )
131
164
}
132
165
133
166
ty:: Infer ( ty:: IntVar ( v) ) => {
134
- self . freshen (
167
+ self . freshen_ty (
135
168
self . infcx . int_unification_table . borrow_mut ( )
136
169
. probe_value ( v)
137
170
. map ( |v| v. to_type ( tcx) ) ,
@@ -140,22 +173,22 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
140
173
}
141
174
142
175
ty:: Infer ( ty:: FloatVar ( v) ) => {
143
- self . freshen (
176
+ self . freshen_ty (
144
177
self . infcx . float_unification_table . borrow_mut ( )
145
178
. probe_value ( v)
146
179
. map ( |v| v. to_type ( tcx) ) ,
147
180
ty:: FloatVar ( v) ,
148
181
ty:: FreshFloatTy )
149
182
}
150
183
151
- ty:: Infer ( ty:: FreshTy ( c ) ) |
152
- ty:: Infer ( ty:: FreshIntTy ( c ) ) |
153
- ty:: Infer ( ty:: FreshFloatTy ( c ) ) => {
154
- if c >= self . freshen_count {
184
+ ty:: Infer ( ty:: FreshTy ( ct ) ) |
185
+ ty:: Infer ( ty:: FreshIntTy ( ct ) ) |
186
+ ty:: Infer ( ty:: FreshFloatTy ( ct ) ) => {
187
+ if ct >= self . ty_freshen_count {
155
188
bug ! ( "Encountered a freshend type with id {} \
156
189
but our counter is only at {}",
157
- c ,
158
- self . freshen_count ) ;
190
+ ct ,
191
+ self . ty_freshen_count ) ;
159
192
}
160
193
t
161
194
}
@@ -194,6 +227,43 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
194
227
}
195
228
196
229
fn fold_const ( & mut self , ct : & ' tcx ty:: LazyConst < ' tcx > ) -> & ' tcx ty:: LazyConst < ' tcx > {
197
- ct // FIXME(const_generics)
230
+ if let ty:: LazyConst :: Evaluated ( ty:: Const { val, ty } ) = ct {
231
+ match val {
232
+ ConstValue :: Infer ( ty:: InferConst :: Var ( v) ) => {
233
+ let opt_ct = self . infcx . const_unification_table
234
+ . borrow_mut ( )
235
+ . probe ( * v)
236
+ . known ( ) ;
237
+ return self . freshen_const (
238
+ opt_ct,
239
+ ty:: InferConst :: Var ( * v) ,
240
+ ty:: InferConst :: Fresh ,
241
+ ty,
242
+ ) ;
243
+ }
244
+ ConstValue :: Infer ( ty:: InferConst :: Fresh ( i) ) => {
245
+ if * i >= self . const_freshen_count {
246
+ bug ! (
247
+ "Encountered a freshend const with id {} \
248
+ but our counter is only at {}",
249
+ i,
250
+ self . const_freshen_count,
251
+ ) ;
252
+ }
253
+ return ct;
254
+ }
255
+
256
+ ConstValue :: Infer ( ty:: InferConst :: Canonical ( ..) ) => {
257
+ bug ! ( "unexpected const {:?}" , ct)
258
+ }
259
+
260
+ ConstValue :: Param ( _) |
261
+ ConstValue :: Scalar ( _) |
262
+ ConstValue :: Slice ( ..) |
263
+ ConstValue :: ByRef ( ..) => { }
264
+ }
265
+ }
266
+
267
+ ct. super_fold_with ( self )
198
268
}
199
269
}
0 commit comments