11use std:: borrow:: Cow ;
22
33use either:: Either ;
4+ use rustc_middle:: ty:: TyCtxt ;
45use tracing:: trace;
56
67use rustc_middle:: span_bug;
@@ -827,20 +828,19 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
827828 } ;
828829
829830 // Obtain the underlying trait we are working on, and the adjusted receiver argument.
830- let ( vptr , dyn_ty, adjusted_receiver ) = if let ty:: Dynamic ( data, _, ty:: DynStar ) =
831+ let ( dyn_trait , dyn_ty, adjusted_recv ) = if let ty:: Dynamic ( data, _, ty:: DynStar ) =
831832 receiver_place. layout . ty . kind ( )
832833 {
833- let ( recv, vptr) = self . unpack_dyn_star ( & receiver_place, data) ?;
834- let ( dyn_ty, _dyn_trait) = self . get_ptr_vtable ( vptr) ?;
834+ let recv = self . unpack_dyn_star ( & receiver_place, data) ?;
835835
836- ( vptr , dyn_ty , recv. ptr ( ) )
836+ ( data . principal ( ) , recv . layout . ty , recv. ptr ( ) )
837837 } else {
838838 // Doesn't have to be a `dyn Trait`, but the unsized tail must be `dyn Trait`.
839839 // (For that reason we also cannot use `unpack_dyn_trait`.)
840840 let receiver_tail = self
841841 . tcx
842842 . struct_tail_erasing_lifetimes ( receiver_place. layout . ty , self . param_env ) ;
843- let ty:: Dynamic ( data , _, ty:: Dyn ) = receiver_tail. kind ( ) else {
843+ let ty:: Dynamic ( receiver_trait , _, ty:: Dyn ) = receiver_tail. kind ( ) else {
844844 span_bug ! (
845845 self . cur_span( ) ,
846846 "dynamic call on non-`dyn` type {}" ,
@@ -851,25 +851,24 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
851851
852852 // Get the required information from the vtable.
853853 let vptr = receiver_place. meta ( ) . unwrap_meta ( ) . to_pointer ( self ) ?;
854- let ( dyn_ty, dyn_trait) = self . get_ptr_vtable ( vptr) ?;
855- if dyn_trait != data. principal ( ) {
856- throw_ub ! ( InvalidVTableTrait {
857- expected_trait: data,
858- vtable_trait: dyn_trait,
859- } ) ;
860- }
854+ let dyn_ty = self . get_ptr_vtable_ty ( vptr, Some ( receiver_trait) ) ?;
861855
862856 // It might be surprising that we use a pointer as the receiver even if this
863857 // is a by-val case; this works because by-val passing of an unsized `dyn
864858 // Trait` to a function is actually desugared to a pointer.
865- ( vptr , dyn_ty, receiver_place. ptr ( ) )
859+ ( receiver_trait . principal ( ) , dyn_ty, receiver_place. ptr ( ) )
866860 } ;
867861
868862 // Now determine the actual method to call. We can do that in two different ways and
869863 // compare them to ensure everything fits.
870- let Some ( ty:: VtblEntry :: Method ( fn_inst) ) =
871- self . get_vtable_entries ( vptr) ?. get ( idx) . copied ( )
872- else {
864+ let vtable_entries = if let Some ( dyn_trait) = dyn_trait {
865+ let trait_ref = dyn_trait. with_self_ty ( * self . tcx , dyn_ty) ;
866+ let trait_ref = self . tcx . erase_regions ( trait_ref) ;
867+ self . tcx . vtable_entries ( trait_ref)
868+ } else {
869+ TyCtxt :: COMMON_VTABLE_ENTRIES
870+ } ;
871+ let Some ( ty:: VtblEntry :: Method ( fn_inst) ) = vtable_entries. get ( idx) . copied ( ) else {
873872 // FIXME(fee1-dead) these could be variants of the UB info enum instead of this
874873 throw_ub_custom ! ( fluent:: const_eval_dyn_call_not_a_method) ;
875874 } ;
@@ -898,7 +897,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
898897 let receiver_ty = Ty :: new_mut_ptr ( self . tcx . tcx , dyn_ty) ;
899898 args[ 0 ] = FnArg :: Copy (
900899 ImmTy :: from_immediate (
901- Scalar :: from_maybe_pointer ( adjusted_receiver , self ) . into ( ) ,
900+ Scalar :: from_maybe_pointer ( adjusted_recv , self ) . into ( ) ,
902901 self . layout_of ( receiver_ty) ?,
903902 )
904903 . into ( ) ,
@@ -974,11 +973,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
974973 let place = match place. layout . ty . kind ( ) {
975974 ty:: Dynamic ( data, _, ty:: Dyn ) => {
976975 // Dropping a trait object. Need to find actual drop fn.
977- self . unpack_dyn_trait ( & place, data) ?. 0
976+ self . unpack_dyn_trait ( & place, data) ?
978977 }
979978 ty:: Dynamic ( data, _, ty:: DynStar ) => {
980979 // Dropping a `dyn*`. Need to find actual drop fn.
981- self . unpack_dyn_star ( & place, data) ?. 0
980+ self . unpack_dyn_star ( & place, data) ?
982981 }
983982 _ => {
984983 debug_assert_eq ! (
0 commit comments