@@ -11,9 +11,9 @@ use ena::unify::UnifyKey;
11
11
12
12
use super :: { InferOk , InferResult , InferenceContext , TypeError } ;
13
13
use 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 ,
17
17
} ;
18
18
19
19
impl < ' a > InferenceContext < ' a > {
@@ -273,6 +273,16 @@ impl<'a> InferenceTable<'a> {
273
273
self . new_var ( TyVariableKind :: General , true )
274
274
}
275
275
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
+
276
286
pub ( crate ) fn resolve_with_fallback < T > (
277
287
& mut self ,
278
288
t : T ,
@@ -388,6 +398,76 @@ impl<'a> InferenceTable<'a> {
388
398
}
389
399
}
390
400
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
+
391
471
/// This checks whether any of the free variables in the `canonicalized`
392
472
/// have changed (either been unified with another variable, or with a
393
473
/// value). If this is not the case, we don't need to try to solve the goal
0 commit comments