@@ -11,9 +11,9 @@ use ena::unify::UnifyKey;
1111
1212use super :: { InferOk , InferResult , InferenceContext , TypeError } ;
1313use crate :: {
14- db:: HirDatabase , fold_tys, static_lifetime, AliasEq , AliasTy , BoundVar , Canonical ,
15- DebruijnIndex , GenericArg , Goal , Guidance , InEnvironment , InferenceVar , Interner , ProjectionTy ,
16- Scalar , Solution , Substitution , TraitEnvironment , Ty , TyKind , VariableKind ,
14+ db:: HirDatabase , fold_tys, static_lifetime, AliasEq , AliasTy , BoundVar , Canonical , Const ,
15+ DebruijnIndex , GenericArg , Goal , Guidance , InEnvironment , InferenceVar , Interner , Lifetime ,
16+ ProjectionTy , Scalar , Solution , Substitution , TraitEnvironment , Ty , TyKind , VariableKind ,
1717} ;
1818
1919impl < ' a > InferenceContext < ' a > {
@@ -273,6 +273,16 @@ impl<'a> InferenceTable<'a> {
273273 self . new_var ( TyVariableKind :: General , true )
274274 }
275275
276+ pub ( crate ) fn new_const_var ( & mut self , ty : Ty ) -> Const {
277+ let var = self . var_unification_table . new_variable ( UniverseIndex :: ROOT ) ;
278+ var. to_const ( & Interner , ty)
279+ }
280+
281+ pub ( crate ) fn new_lifetime_var ( & mut self ) -> Lifetime {
282+ let var = self . var_unification_table . new_variable ( UniverseIndex :: ROOT ) ;
283+ var. to_lifetime ( & Interner )
284+ }
285+
276286 pub ( crate ) fn resolve_with_fallback < T > (
277287 & mut self ,
278288 t : T ,
@@ -388,6 +398,76 @@ impl<'a> InferenceTable<'a> {
388398 }
389399 }
390400
401+ pub ( crate ) fn fudge_inference < T : Fold < Interner > > (
402+ & mut self ,
403+ f : impl FnOnce ( & mut Self ) -> T ,
404+ ) -> T :: Result {
405+ use chalk_ir:: fold:: Folder ;
406+ struct VarFudger < ' a , ' b > {
407+ table : & ' a mut InferenceTable < ' b > ,
408+ highest_known_var : InferenceVar ,
409+ }
410+ impl < ' a , ' b > Folder < ' static , Interner > for VarFudger < ' a , ' b > {
411+ fn as_dyn ( & mut self ) -> & mut dyn Folder < ' static , Interner > {
412+ self
413+ }
414+
415+ fn interner ( & self ) -> & ' static Interner {
416+ & Interner
417+ }
418+
419+ fn fold_inference_ty (
420+ & mut self ,
421+ var : chalk_ir:: InferenceVar ,
422+ kind : TyVariableKind ,
423+ _outer_binder : chalk_ir:: DebruijnIndex ,
424+ ) -> chalk_ir:: Fallible < chalk_ir:: Ty < Interner > > {
425+ Ok ( if var < self . highest_known_var {
426+ var. to_ty ( & Interner , kind)
427+ } else {
428+ self . table . new_type_var ( )
429+ } )
430+ }
431+
432+ fn fold_inference_lifetime (
433+ & mut self ,
434+ var : chalk_ir:: InferenceVar ,
435+ _outer_binder : chalk_ir:: DebruijnIndex ,
436+ ) -> chalk_ir:: Fallible < chalk_ir:: Lifetime < Interner > > {
437+ Ok ( if var < self . highest_known_var {
438+ var. to_lifetime ( & Interner )
439+ } else {
440+ self . table . new_lifetime_var ( )
441+ } )
442+ }
443+
444+ fn fold_inference_const (
445+ & mut self ,
446+ ty : chalk_ir:: Ty < Interner > ,
447+ var : chalk_ir:: InferenceVar ,
448+ _outer_binder : chalk_ir:: DebruijnIndex ,
449+ ) -> chalk_ir:: Fallible < chalk_ir:: Const < Interner > > {
450+ Ok ( if var < self . highest_known_var {
451+ var. to_const ( & Interner , ty)
452+ } else {
453+ self . table . new_const_var ( ty)
454+ } )
455+ }
456+ }
457+
458+ let snapshot = self . snapshot ( ) ;
459+ let highest_known_var =
460+ self . new_type_var ( ) . inference_var ( & Interner ) . expect ( "inference_var" ) ;
461+ let result = f ( self ) ;
462+ self . rollback_to ( snapshot) ;
463+
464+ let result = result
465+ . fold_with ( & mut VarFudger { table : self , highest_known_var } , DebruijnIndex :: INNERMOST )
466+ . expect ( "fold_with with VarFudger" ) ;
467+
468+ result
469+ }
470+
391471 /// This checks whether any of the free variables in the `canonicalized`
392472 /// have changed (either been unified with another variable, or with a
393473 /// value). If this is not the case, we don't need to try to solve the goal
0 commit comments