@@ -16,6 +16,7 @@ use rustc_hir::LangItem;
16
16
use rustc_hir:: def_id:: DefId ;
17
17
use rustc_infer:: infer:: BoundRegionConversionTime :: { self , HigherRankedType } ;
18
18
use rustc_infer:: infer:: DefineOpaqueTypes ;
19
+ use rustc_infer:: infer:: at:: ToTrace ;
19
20
use rustc_infer:: infer:: relate:: TypeRelation ;
20
21
use rustc_infer:: traits:: TraitObligation ;
21
22
use rustc_middle:: bug;
@@ -44,7 +45,7 @@ use super::{
44
45
TraitQueryMode , const_evaluatable, project, util, wf,
45
46
} ;
46
47
use crate :: error_reporting:: InferCtxtErrorExt ;
47
- use crate :: infer:: { InferCtxt , InferCtxtExt , InferOk , TypeFreshener } ;
48
+ use crate :: infer:: { InferCtxt , InferOk , TypeFreshener } ;
48
49
use crate :: solve:: InferCtxtSelectExt as _;
49
50
use crate :: traits:: normalize:: { normalize_with_depth, normalize_with_depth_to} ;
50
51
use crate :: traits:: project:: { ProjectAndUnifyResult , ProjectionCacheKeyExt } ;
@@ -2579,16 +2580,32 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
2579
2580
// Check that a_ty's supertrait (upcast_principal) is compatible
2580
2581
// with the target (b_ty).
2581
2582
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
+
2582
2588
nested. extend (
2583
2589
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
+ } )
2592
2609
. map_err ( |_| SelectionError :: Unimplemented ) ?
2593
2610
. into_obligations ( ) ,
2594
2611
) ;
@@ -2599,28 +2616,67 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
2599
2616
// return ambiguity. Otherwise, if exactly one matches, equate
2600
2617
// it with b_ty's projection.
2601
2618
ty:: ExistentialPredicate :: Projection ( target_projection) => {
2602
- let target_projection = bound. rebind ( target_projection) ;
2619
+ let hr_target_projection = bound. rebind ( target_projection) ;
2620
+
2603
2621
let mut matching_projections =
2604
- a_data. projection_bounds ( ) . filter ( |source_projection | {
2622
+ a_data. projection_bounds ( ) . filter ( |& hr_source_projection | {
2605
2623
// Eager normalization means that we can just use can_eq
2606
2624
// 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
+ } )
2613
2651
} ) ;
2614
- let Some ( source_projection) = matching_projections. next ( ) else {
2652
+
2653
+ let Some ( hr_source_projection) = matching_projections. next ( ) else {
2615
2654
return Err ( SelectionError :: Unimplemented ) ;
2616
2655
} ;
2617
2656
if matching_projections. next ( ) . is_some ( ) {
2618
2657
return Ok ( None ) ;
2619
2658
}
2620
2659
nested. extend (
2621
2660
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
+ } )
2624
2680
. map_err ( |_| SelectionError :: Unimplemented ) ?
2625
2681
. into_obligations ( ) ,
2626
2682
) ;
0 commit comments