3
3
use rustc_data_structures:: fx:: FxHashMap ;
4
4
use rustc_hir:: { def_id:: DefId , Movability , Mutability } ;
5
5
use rustc_infer:: traits:: query:: NoSolution ;
6
+ use rustc_middle:: traits:: solve:: Goal ;
6
7
use rustc_middle:: ty:: {
7
8
self , Ty , TyCtxt , TypeFoldable , TypeFolder , TypeSuperFoldable , TypeVisitableExt ,
8
9
} ;
@@ -345,7 +346,7 @@ pub(in crate::solve) fn predicates_for_object_candidate<'tcx>(
345
346
param_env : ty:: ParamEnv < ' tcx > ,
346
347
trait_ref : ty:: TraitRef < ' tcx > ,
347
348
object_bound : & ' tcx ty:: List < ty:: PolyExistentialPredicate < ' tcx > > ,
348
- ) -> Vec < ty:: Clause < ' tcx > > {
349
+ ) -> Vec < Goal < ' tcx , ty:: Predicate < ' tcx > > > {
349
350
let tcx = ecx. tcx ( ) ;
350
351
let mut requirements = vec ! [ ] ;
351
352
requirements. extend (
@@ -376,17 +377,22 @@ pub(in crate::solve) fn predicates_for_object_candidate<'tcx>(
376
377
}
377
378
}
378
379
379
- requirements. fold_with ( & mut ReplaceProjectionWith {
380
- ecx,
381
- param_env,
382
- mapping : replace_projection_with,
383
- } )
380
+ let mut folder =
381
+ ReplaceProjectionWith { ecx, param_env, mapping : replace_projection_with, nested : vec ! [ ] } ;
382
+ let folded_requirements = requirements. fold_with ( & mut folder) ;
383
+
384
+ folder
385
+ . nested
386
+ . into_iter ( )
387
+ . chain ( folded_requirements. into_iter ( ) . map ( |clause| Goal :: new ( tcx, param_env, clause) ) )
388
+ . collect ( )
384
389
}
385
390
386
391
struct ReplaceProjectionWith < ' a , ' tcx > {
387
392
ecx : & ' a EvalCtxt < ' a , ' tcx > ,
388
393
param_env : ty:: ParamEnv < ' tcx > ,
389
394
mapping : FxHashMap < DefId , ty:: PolyProjectionPredicate < ' tcx > > ,
395
+ nested : Vec < Goal < ' tcx , ty:: Predicate < ' tcx > > > ,
390
396
}
391
397
392
398
impl < ' tcx > TypeFolder < TyCtxt < ' tcx > > for ReplaceProjectionWith < ' _ , ' tcx > {
@@ -402,13 +408,12 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceProjectionWith<'_, 'tcx> {
402
408
// but the where clauses we instantiated are not. We can solve this by instantiating
403
409
// the binder at the usage site.
404
410
let proj = self . ecx . instantiate_binder_with_infer ( * replacement) ;
405
- // FIXME: Technically this folder could be fallible?
406
- let nested = self
407
- . ecx
408
- . eq_and_get_goals ( self . param_env , alias_ty, proj. projection_ty )
409
- . expect ( "expected to be able to unify goal projection with dyn's projection" ) ;
410
- // FIXME: Technically we could register these too..
411
- assert ! ( nested. is_empty( ) , "did not expect unification to have any nested goals" ) ;
411
+ // FIXME: Technically this equate could be fallible...
412
+ self . nested . extend (
413
+ self . ecx
414
+ . eq_and_get_goals ( self . param_env , alias_ty, proj. projection_ty )
415
+ . expect ( "expected to be able to unify goal projection with dyn's projection" ) ,
416
+ ) ;
412
417
proj. term . ty ( ) . unwrap ( )
413
418
} else {
414
419
ty. super_fold_with ( self )
0 commit comments