@@ -2,6 +2,8 @@ use std::fmt::Debug;
22use std:: ops:: ControlFlow ;
33
44use rustc_hir:: def_id:: DefId ;
5+ use rustc_infer:: infer:: { BoundRegionConversionTime , TyCtxtInferExt } ;
6+ use rustc_infer:: traits:: ObligationCause ;
57use rustc_infer:: traits:: util:: PredicateSet ;
68use rustc_middle:: bug;
79use rustc_middle:: query:: Providers ;
@@ -13,7 +15,7 @@ use smallvec::{SmallVec, smallvec};
1315use tracing:: debug;
1416
1517use crate :: errors:: DumpVTableEntries ;
16- use crate :: traits:: { impossible_predicates, is_vtable_safe_method} ;
18+ use crate :: traits:: { ObligationCtxt , impossible_predicates, is_vtable_safe_method} ;
1719
1820#[ derive( Clone , Debug ) ]
1921pub enum VtblSegment < ' tcx > {
@@ -383,17 +385,37 @@ pub(crate) fn supertrait_vtable_slot<'tcx>(
383385 let ty:: Dynamic ( target, _, _) = * target. kind ( ) else {
384386 bug ! ( ) ;
385387 } ;
386- let target_principal = tcx
387- . normalize_erasing_regions ( ty:: ParamEnv :: reveal_all ( ) , target. principal ( ) ?)
388- . with_self_ty ( tcx, tcx. types . trait_object_dummy_self ) ;
388+ let target_principal = target. principal ( ) ?. with_self_ty ( tcx, tcx. types . trait_object_dummy_self ) ;
389389
390390 // Given that we have a target principal, it is a bug for there not to be a source principal.
391391 let ty:: Dynamic ( source, _, _) = * source. kind ( ) else {
392392 bug ! ( ) ;
393393 } ;
394- let source_principal = tcx
395- . normalize_erasing_regions ( ty:: ParamEnv :: reveal_all ( ) , source. principal ( ) . unwrap ( ) )
396- . with_self_ty ( tcx, tcx. types . trait_object_dummy_self ) ;
394+ let source_principal =
395+ source. principal ( ) . unwrap ( ) . with_self_ty ( tcx, tcx. types . trait_object_dummy_self ) ;
396+
397+ let infcx = tcx. infer_ctxt ( ) . build ( ) ;
398+ let param_env = ty:: ParamEnv :: reveal_all ( ) ;
399+ let trait_refs_are_compatible =
400+ |source : ty:: PolyTraitRef < ' tcx > , target : ty:: PolyTraitRef < ' tcx > | {
401+ infcx. probe ( |_| {
402+ let ocx = ObligationCtxt :: new ( & infcx) ;
403+ let source = ocx. normalize ( & ObligationCause :: dummy ( ) , param_env, source) ;
404+ let target = ocx. normalize ( & ObligationCause :: dummy ( ) , param_env, target) ;
405+ infcx. enter_forall ( target, |target| {
406+ let source = infcx. instantiate_binder_with_fresh_vars (
407+ DUMMY_SP ,
408+ BoundRegionConversionTime :: HigherRankedType ,
409+ source,
410+ ) ;
411+ let Ok ( ( ) ) = ocx. eq ( & ObligationCause :: dummy ( ) , param_env, target, source)
412+ else {
413+ return false ;
414+ } ;
415+ ocx. select_all_or_error ( ) . is_empty ( )
416+ } )
417+ } )
418+ } ;
397419
398420 let vtable_segment_callback = {
399421 let mut vptr_offset = 0 ;
@@ -404,9 +426,7 @@ pub(crate) fn supertrait_vtable_slot<'tcx>(
404426 }
405427 VtblSegment :: TraitOwnEntries { trait_ref, emit_vptr } => {
406428 vptr_offset += tcx. own_existential_vtable_entries ( trait_ref. def_id ( ) ) . len ( ) ;
407- if tcx. normalize_erasing_regions ( ty:: ParamEnv :: reveal_all ( ) , trait_ref)
408- == target_principal
409- {
429+ if trait_refs_are_compatible ( trait_ref, target_principal) {
410430 if emit_vptr {
411431 return ControlFlow :: Break ( Some ( vptr_offset) ) ;
412432 } else {
0 commit comments