3131//! variable only once, and it does so as soon as it can, so it is reasonable to ask what the type
3232//! inferencer knows "so far".
3333
34+ use crate :: mir:: interpret:: ConstValue ;
3435use crate :: ty:: { self , Ty , TyCtxt , TypeFoldable } ;
3536use crate :: ty:: fold:: TypeFolder ;
3637use crate :: util:: nodemap:: FxHashMap ;
@@ -42,42 +43,74 @@ use super::unify_key::ToType;
4243
4344pub struct TypeFreshener < ' a , ' gcx : ' a +' tcx , ' tcx : ' a > {
4445 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 > > ,
4750}
4851
4952impl < ' a , ' gcx , ' tcx > TypeFreshener < ' a , ' gcx , ' tcx > {
5053 pub fn new ( infcx : & ' a InferCtxt < ' a , ' gcx , ' tcx > )
5154 -> TypeFreshener < ' a , ' gcx , ' tcx > {
5255 TypeFreshener {
5356 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 ( ) ,
5661 }
5762 }
5863
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
6471 F : FnOnce ( u32 ) -> ty:: InferTy ,
6572 {
6673 if let Some ( ty) = opt_ty {
6774 return ty. fold_with ( self ) ;
6875 }
6976
70- match self . freshen_map . entry ( key) {
77+ match self . ty_freshen_map . entry ( key) {
7178 Entry :: Occupied ( entry) => * entry. get ( ) ,
7279 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 ;
7582 let t = self . infcx . tcx . mk_ty_infer ( freshener ( index) ) ;
7683 entry. insert ( t) ;
7784 t
7885 }
7986 }
8087 }
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+ }
81114}
82115
83116impl < ' 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> {
124157 match t. sty {
125158 ty:: Infer ( ty:: TyVar ( v) ) => {
126159 let opt_ty = self . infcx . type_variables . borrow_mut ( ) . probe ( v) . known ( ) ;
127- self . freshen (
160+ self . freshen_ty (
128161 opt_ty,
129162 ty:: TyVar ( v) ,
130163 ty:: FreshTy )
131164 }
132165
133166 ty:: Infer ( ty:: IntVar ( v) ) => {
134- self . freshen (
167+ self . freshen_ty (
135168 self . infcx . int_unification_table . borrow_mut ( )
136169 . probe_value ( v)
137170 . map ( |v| v. to_type ( tcx) ) ,
@@ -140,22 +173,22 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
140173 }
141174
142175 ty:: Infer ( ty:: FloatVar ( v) ) => {
143- self . freshen (
176+ self . freshen_ty (
144177 self . infcx . float_unification_table . borrow_mut ( )
145178 . probe_value ( v)
146179 . map ( |v| v. to_type ( tcx) ) ,
147180 ty:: FloatVar ( v) ,
148181 ty:: FreshFloatTy )
149182 }
150183
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 {
155188 bug ! ( "Encountered a freshend type with id {} \
156189 but our counter is only at {}",
157- c ,
158- self . freshen_count ) ;
190+ ct ,
191+ self . ty_freshen_count ) ;
159192 }
160193 t
161194 }
@@ -194,6 +227,43 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
194227 }
195228
196229 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 )
198268 }
199269}
0 commit comments