11use std:: convert:: TryFrom ;
2+ use std:: fmt;
23
34use crate :: mir:: interpret:: { alloc_range, AllocId , Allocation , Pointer , Scalar , ScalarMaybeUninit } ;
4- use crate :: ty:: fold:: TypeFoldable ;
5- use crate :: ty:: { self , DefId , PolyExistentialTraitRef , SubstsRef , Ty , TyCtxt } ;
5+ use crate :: ty:: { self , Instance , PolyTraitRef , Ty , TyCtxt } ;
66use rustc_ast:: Mutability ;
77
8- #[ derive( Clone , Copy , Debug , PartialEq , HashStable ) ]
8+ #[ derive( Clone , Copy , PartialEq , HashStable ) ]
99pub enum VtblEntry < ' tcx > {
1010 MetadataDropInPlace ,
1111 MetadataSize ,
1212 MetadataAlign ,
1313 Vacant ,
14- Method ( DefId , SubstsRef < ' tcx > ) ,
15- TraitVPtr ( PolyExistentialTraitRef < ' tcx > ) ,
14+ Method ( Instance < ' tcx > ) ,
15+ TraitVPtr ( PolyTraitRef < ' tcx > ) ,
16+ }
17+
18+ impl < ' tcx > fmt:: Debug for VtblEntry < ' tcx > {
19+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
20+ // We want to call `Display` on `Instance` and `PolyTraitRef`,
21+ // so we implement this manually.
22+ match self {
23+ VtblEntry :: MetadataDropInPlace => write ! ( f, "MetadataDropInPlace" ) ,
24+ VtblEntry :: MetadataSize => write ! ( f, "MetadataSize" ) ,
25+ VtblEntry :: MetadataAlign => write ! ( f, "MetadataAlign" ) ,
26+ VtblEntry :: Vacant => write ! ( f, "Vacant" ) ,
27+ VtblEntry :: Method ( instance) => write ! ( f, "Method({})" , instance) ,
28+ VtblEntry :: TraitVPtr ( trait_ref) => write ! ( f, "TraitVPtr({})" , trait_ref) ,
29+ }
30+ }
1631}
1732
1833pub const COMMON_VTABLE_ENTRIES : & [ VtblEntry < ' _ > ] =
@@ -37,11 +52,6 @@ impl<'tcx> TyCtxt<'tcx> {
3752 }
3853 drop ( vtables_cache) ;
3954
40- // See https://github.com/rust-lang/rust/pull/86475#discussion_r655162674
41- assert ! (
42- !ty. needs_subst( ) && !poly_trait_ref. map_or( false , |trait_ref| trait_ref. needs_subst( ) )
43- ) ;
44- let param_env = ty:: ParamEnv :: reveal_all ( ) ;
4555 let vtable_entries = if let Some ( poly_trait_ref) = poly_trait_ref {
4656 let trait_ref = poly_trait_ref. with_self_ty ( tcx, ty) ;
4757 let trait_ref = tcx. erase_regions ( trait_ref) ;
@@ -51,8 +61,9 @@ impl<'tcx> TyCtxt<'tcx> {
5161 COMMON_VTABLE_ENTRIES
5262 } ;
5363
54- let layout =
55- tcx. layout_of ( param_env. and ( ty) ) . expect ( "failed to build vtable representation" ) ;
64+ let layout = tcx
65+ . layout_of ( ty:: ParamEnv :: reveal_all ( ) . and ( ty) )
66+ . expect ( "failed to build vtable representation" ) ;
5667 assert ! ( !layout. is_unsized( ) , "can't create a vtable for an unsized type" ) ;
5768 let size = layout. size . bytes ( ) ;
5869 let align = layout. align . abi . bytes ( ) ;
@@ -80,21 +91,18 @@ impl<'tcx> TyCtxt<'tcx> {
8091 VtblEntry :: MetadataSize => Scalar :: from_uint ( size, ptr_size) . into ( ) ,
8192 VtblEntry :: MetadataAlign => Scalar :: from_uint ( align, ptr_size) . into ( ) ,
8293 VtblEntry :: Vacant => continue ,
83- VtblEntry :: Method ( def_id, substs) => {
84- // See https://github.com/rust-lang/rust/pull/86475#discussion_r655162674
85- assert ! ( !substs. needs_subst( ) ) ;
86-
94+ VtblEntry :: Method ( instance) => {
8795 // Prepare the fn ptr we write into the vtable.
88- let instance =
89- ty:: Instance :: resolve_for_vtable ( tcx, param_env, * def_id, substs)
90- . expect ( "resolution failed during building vtable representation" )
91- . polymorphize ( tcx) ;
96+ let instance = instance. polymorphize ( tcx) ;
9297 let fn_alloc_id = tcx. create_fn_alloc ( instance) ;
9398 let fn_ptr = Pointer :: from ( fn_alloc_id) ;
9499 ScalarMaybeUninit :: from_pointer ( fn_ptr, & tcx)
95100 }
96101 VtblEntry :: TraitVPtr ( trait_ref) => {
97- let supertrait_alloc_id = self . vtable_allocation ( ty, Some ( * trait_ref) ) ;
102+ let super_trait_ref = trait_ref. map_bound ( |trait_ref| {
103+ ty:: ExistentialTraitRef :: erase_self_ty ( tcx, trait_ref)
104+ } ) ;
105+ let supertrait_alloc_id = self . vtable_allocation ( ty, Some ( super_trait_ref) ) ;
98106 let vptr = Pointer :: from ( supertrait_alloc_id) ;
99107 ScalarMaybeUninit :: from_pointer ( vptr, & tcx)
100108 }
0 commit comments