33use rustc_data_structures:: fx:: FxHashMap ;
44use rustc_hir:: { def_id:: DefId , Movability , Mutability } ;
55use rustc_infer:: traits:: query:: NoSolution ;
6+ use rustc_middle:: traits:: solve:: Goal ;
67use rustc_middle:: ty:: {
78 self , Ty , TyCtxt , TypeFoldable , TypeFolder , TypeSuperFoldable , TypeVisitableExt ,
89} ;
@@ -345,7 +346,7 @@ pub(in crate::solve) fn predicates_for_object_candidate<'tcx>(
345346 param_env : ty:: ParamEnv < ' tcx > ,
346347 trait_ref : ty:: TraitRef < ' tcx > ,
347348 object_bound : & ' tcx ty:: List < ty:: PolyExistentialPredicate < ' tcx > > ,
348- ) -> Vec < ty:: Clause < ' tcx > > {
349+ ) -> Vec < Goal < ' tcx , ty:: Predicate < ' tcx > > > {
349350 let tcx = ecx. tcx ( ) ;
350351 let mut requirements = vec ! [ ] ;
351352 requirements. extend (
@@ -376,17 +377,22 @@ pub(in crate::solve) fn predicates_for_object_candidate<'tcx>(
376377 }
377378 }
378379
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 ( )
384389}
385390
386391struct ReplaceProjectionWith < ' a , ' tcx > {
387392 ecx : & ' a EvalCtxt < ' a , ' tcx > ,
388393 param_env : ty:: ParamEnv < ' tcx > ,
389394 mapping : FxHashMap < DefId , ty:: PolyProjectionPredicate < ' tcx > > ,
395+ nested : Vec < Goal < ' tcx , ty:: Predicate < ' tcx > > > ,
390396}
391397
392398impl < ' tcx > TypeFolder < TyCtxt < ' tcx > > for ReplaceProjectionWith < ' _ , ' tcx > {
@@ -402,13 +408,12 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceProjectionWith<'_, 'tcx> {
402408 // but the where clauses we instantiated are not. We can solve this by instantiating
403409 // the binder at the usage site.
404410 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+ ) ;
412417 proj. term . ty ( ) . unwrap ( )
413418 } else {
414419 ty. super_fold_with ( self )
0 commit comments