@@ -2,6 +2,8 @@ use std::fmt::Debug;
2
2
use std:: ops:: ControlFlow ;
3
3
4
4
use rustc_hir:: def_id:: DefId ;
5
+ use rustc_infer:: infer:: { BoundRegionConversionTime , TyCtxtInferExt } ;
6
+ use rustc_infer:: traits:: ObligationCause ;
5
7
use rustc_infer:: traits:: util:: PredicateSet ;
6
8
use rustc_middle:: bug;
7
9
use rustc_middle:: query:: Providers ;
@@ -13,7 +15,7 @@ use smallvec::{SmallVec, smallvec};
13
15
use tracing:: debug;
14
16
15
17
use crate :: errors:: DumpVTableEntries ;
16
- use crate :: traits:: { impossible_predicates, is_vtable_safe_method} ;
18
+ use crate :: traits:: { ObligationCtxt , impossible_predicates, is_vtable_safe_method} ;
17
19
18
20
#[ derive( Clone , Debug ) ]
19
21
pub enum VtblSegment < ' tcx > {
@@ -383,17 +385,37 @@ pub(crate) fn supertrait_vtable_slot<'tcx>(
383
385
let ty:: Dynamic ( target, _, _) = * target. kind ( ) else {
384
386
bug ! ( ) ;
385
387
} ;
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 ) ;
389
389
390
390
// Given that we have a target principal, it is a bug for there not to be a source principal.
391
391
let ty:: Dynamic ( source, _, _) = * source. kind ( ) else {
392
392
bug ! ( ) ;
393
393
} ;
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
+ } ;
397
419
398
420
let vtable_segment_callback = {
399
421
let mut vptr_offset = 0 ;
@@ -404,9 +426,7 @@ pub(crate) fn supertrait_vtable_slot<'tcx>(
404
426
}
405
427
VtblSegment :: TraitOwnEntries { trait_ref, emit_vptr } => {
406
428
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) {
410
430
if emit_vptr {
411
431
return ControlFlow :: Break ( Some ( vptr_offset) ) ;
412
432
} else {
0 commit comments