11use rustc_data_structures:: fx:: FxHashMap ;
2- use rustc_hir:: { Movability , Mutability } ;
2+ use rustc_hir:: { def_id :: DefId , Movability , Mutability } ;
33use rustc_infer:: traits:: query:: NoSolution ;
44use rustc_middle:: ty:: { self , Ty , TyCtxt , TypeFoldable , TypeFolder , TypeSuperFoldable } ;
55
@@ -236,10 +236,12 @@ pub(crate) fn extract_tupled_inputs_and_output_from_callable<'tcx>(
236236}
237237
238238pub ( crate ) fn predicates_for_object_candidate < ' tcx > (
239- tcx : TyCtxt < ' tcx > ,
239+ ecx : & EvalCtxt < ' _ , ' tcx > ,
240+ param_env : ty:: ParamEnv < ' tcx > ,
240241 trait_ref : ty:: TraitRef < ' tcx > ,
241242 object_bound : & ' tcx ty:: List < ty:: PolyExistentialPredicate < ' tcx > > ,
242243) -> Vec < ty:: Predicate < ' tcx > > {
244+ let tcx = ecx. tcx ( ) ;
243245 let mut requirements = vec ! [ ] ;
244246 requirements. extend (
245247 tcx. super_predicates_of ( trait_ref. def_id ) . instantiate ( tcx, trait_ref. substs ) . predicates ,
@@ -252,13 +254,9 @@ pub(crate) fn predicates_for_object_candidate<'tcx>(
252254
253255 let mut replace_projection_with = FxHashMap :: default ( ) ;
254256 for bound in object_bound {
255- let bound = bound. no_bound_vars ( ) . expect ( "higher-ranked projections not supported, yet" ) ;
256- if let ty:: ExistentialPredicate :: Projection ( proj) = bound {
257+ if let ty:: ExistentialPredicate :: Projection ( proj) = bound. skip_binder ( ) {
257258 let proj = proj. with_self_ty ( tcx, trait_ref. self_ty ( ) ) ;
258- let old_ty = replace_projection_with. insert (
259- proj. projection_ty ,
260- proj. term . ty ( ) . expect ( "expected only types in dyn right now" ) ,
261- ) ;
259+ let old_ty = replace_projection_with. insert ( proj. def_id ( ) , bound. rebind ( proj) ) ;
262260 assert_eq ! (
263261 old_ty,
264262 None ,
@@ -270,24 +268,37 @@ pub(crate) fn predicates_for_object_candidate<'tcx>(
270268 }
271269 }
272270
273- requirements. fold_with ( & mut ReplaceProjectionWith { tcx, mapping : replace_projection_with } )
271+ requirements. fold_with ( & mut ReplaceProjectionWith {
272+ ecx,
273+ param_env,
274+ mapping : replace_projection_with,
275+ } )
274276}
275277
276- struct ReplaceProjectionWith < ' tcx > {
277- tcx : TyCtxt < ' tcx > ,
278- mapping : FxHashMap < ty:: AliasTy < ' tcx > , Ty < ' tcx > > ,
278+ struct ReplaceProjectionWith < ' a , ' tcx > {
279+ ecx : & ' a EvalCtxt < ' a , ' tcx > ,
280+ param_env : ty:: ParamEnv < ' tcx > ,
281+ mapping : FxHashMap < DefId , ty:: PolyProjectionPredicate < ' tcx > > ,
279282}
280283
281- impl < ' tcx > TypeFolder < TyCtxt < ' tcx > > for ReplaceProjectionWith < ' tcx > {
284+ impl < ' tcx > TypeFolder < TyCtxt < ' tcx > > for ReplaceProjectionWith < ' _ , ' tcx > {
282285 fn interner ( & self ) -> TyCtxt < ' tcx > {
283- self . tcx
286+ self . ecx . tcx ( )
284287 }
285288
286289 fn fold_ty ( & mut self , ty : Ty < ' tcx > ) -> Ty < ' tcx > {
287290 if let ty:: Alias ( ty:: Projection , alias_ty) = * ty. kind ( )
288- && let Some ( replacement) = self . mapping . get ( & alias_ty)
291+ && let Some ( replacement) = self . mapping . get ( & alias_ty. def_id )
289292 {
290- * replacement
293+ let proj = self . ecx . instantiate_binder_with_infer ( * replacement) ;
294+ // Technically this folder could be fallible?
295+ let nested = self
296+ . ecx
297+ . eq ( self . param_env , alias_ty, proj. projection_ty )
298+ . expect ( "expected to be able to unify goal projection with dyn's projection" ) ;
299+ // Technically we could register these too..
300+ assert ! ( nested. is_empty( ) , "did not expect unification to have any nested goals" ) ;
301+ proj. term . ty ( ) . unwrap ( )
291302 } else {
292303 ty. super_fold_with ( self )
293304 }
0 commit comments