@@ -16,6 +16,7 @@ use rustc_hir::LangItem;
1616use rustc_hir:: def_id:: DefId ;
1717use rustc_infer:: infer:: BoundRegionConversionTime :: { self , HigherRankedType } ;
1818use rustc_infer:: infer:: DefineOpaqueTypes ;
19+ use rustc_infer:: infer:: at:: ToTrace ;
1920use rustc_infer:: infer:: relate:: TypeRelation ;
2021use rustc_infer:: traits:: TraitObligation ;
2122use rustc_middle:: bug;
@@ -44,7 +45,7 @@ use super::{
4445 TraitQueryMode , const_evaluatable, project, util, wf,
4546} ;
4647use crate :: error_reporting:: InferCtxtErrorExt ;
47- use crate :: infer:: { InferCtxt , InferCtxtExt , InferOk , TypeFreshener } ;
48+ use crate :: infer:: { InferCtxt , InferOk , TypeFreshener } ;
4849use crate :: solve:: InferCtxtSelectExt as _;
4950use crate :: traits:: normalize:: { normalize_with_depth, normalize_with_depth_to} ;
5051use crate :: traits:: project:: { ProjectAndUnifyResult , ProjectionCacheKeyExt } ;
@@ -2579,16 +2580,32 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
25792580 // Check that a_ty's supertrait (upcast_principal) is compatible
25802581 // with the target (b_ty).
25812582 ty:: ExistentialPredicate :: Trait ( target_principal) => {
2583+ let hr_source_principal = upcast_principal. map_bound ( |trait_ref| {
2584+ ty:: ExistentialTraitRef :: erase_self_ty ( tcx, trait_ref)
2585+ } ) ;
2586+ let hr_target_principal = bound. rebind ( target_principal) ;
2587+
25822588 nested. extend (
25832589 self . infcx
2584- . at ( & obligation. cause , obligation. param_env )
2585- . sup (
2586- DefineOpaqueTypes :: Yes ,
2587- bound. rebind ( target_principal) ,
2588- upcast_principal. map_bound ( |trait_ref| {
2589- ty:: ExistentialTraitRef :: erase_self_ty ( tcx, trait_ref)
2590- } ) ,
2591- )
2590+ . enter_forall ( hr_target_principal, |target_principal| {
2591+ let source_principal =
2592+ self . infcx . instantiate_binder_with_fresh_vars (
2593+ obligation. cause . span ,
2594+ HigherRankedType ,
2595+ hr_source_principal,
2596+ ) ;
2597+ self . infcx . at ( & obligation. cause , obligation. param_env ) . eq_trace (
2598+ DefineOpaqueTypes :: Yes ,
2599+ ToTrace :: to_trace (
2600+ & obligation. cause ,
2601+ true ,
2602+ hr_target_principal,
2603+ hr_source_principal,
2604+ ) ,
2605+ target_principal,
2606+ source_principal,
2607+ )
2608+ } )
25922609 . map_err ( |_| SelectionError :: Unimplemented ) ?
25932610 . into_obligations ( ) ,
25942611 ) ;
@@ -2599,28 +2616,67 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
25992616 // return ambiguity. Otherwise, if exactly one matches, equate
26002617 // it with b_ty's projection.
26012618 ty:: ExistentialPredicate :: Projection ( target_projection) => {
2602- let target_projection = bound. rebind ( target_projection) ;
2619+ let hr_target_projection = bound. rebind ( target_projection) ;
2620+
26032621 let mut matching_projections =
2604- a_data. projection_bounds ( ) . filter ( |source_projection | {
2622+ a_data. projection_bounds ( ) . filter ( |& hr_source_projection | {
26052623 // Eager normalization means that we can just use can_eq
26062624 // here instead of equating and processing obligations.
2607- source_projection. item_def_id ( ) == target_projection. item_def_id ( )
2608- && self . infcx . can_eq (
2609- obligation. param_env ,
2610- * source_projection,
2611- target_projection,
2612- )
2625+ hr_source_projection. item_def_id ( ) == hr_target_projection. item_def_id ( )
2626+ && self . infcx . probe ( |_| {
2627+ self . infcx
2628+ . enter_forall ( hr_target_projection, |target_projection| {
2629+ let source_projection =
2630+ self . infcx . instantiate_binder_with_fresh_vars (
2631+ obligation. cause . span ,
2632+ HigherRankedType ,
2633+ hr_source_projection,
2634+ ) ;
2635+ self . infcx
2636+ . at ( & obligation. cause , obligation. param_env )
2637+ . eq_trace (
2638+ DefineOpaqueTypes :: Yes ,
2639+ ToTrace :: to_trace (
2640+ & obligation. cause ,
2641+ true ,
2642+ hr_target_projection,
2643+ hr_source_projection,
2644+ ) ,
2645+ target_projection,
2646+ source_projection,
2647+ )
2648+ } )
2649+ . is_ok ( )
2650+ } )
26132651 } ) ;
2614- let Some ( source_projection) = matching_projections. next ( ) else {
2652+
2653+ let Some ( hr_source_projection) = matching_projections. next ( ) else {
26152654 return Err ( SelectionError :: Unimplemented ) ;
26162655 } ;
26172656 if matching_projections. next ( ) . is_some ( ) {
26182657 return Ok ( None ) ;
26192658 }
26202659 nested. extend (
26212660 self . infcx
2622- . at ( & obligation. cause , obligation. param_env )
2623- . sup ( DefineOpaqueTypes :: Yes , target_projection, source_projection)
2661+ . enter_forall ( hr_target_projection, |target_projection| {
2662+ let source_projection =
2663+ self . infcx . instantiate_binder_with_fresh_vars (
2664+ obligation. cause . span ,
2665+ HigherRankedType ,
2666+ hr_source_projection,
2667+ ) ;
2668+ self . infcx . at ( & obligation. cause , obligation. param_env ) . eq_trace (
2669+ DefineOpaqueTypes :: Yes ,
2670+ ToTrace :: to_trace (
2671+ & obligation. cause ,
2672+ true ,
2673+ hr_target_projection,
2674+ hr_source_projection,
2675+ ) ,
2676+ target_projection,
2677+ source_projection,
2678+ )
2679+ } )
26242680 . map_err ( |_| SelectionError :: Unimplemented ) ?
26252681 . into_obligations ( ) ,
26262682 ) ;
0 commit comments