1
1
use std:: borrow:: Cow ;
2
2
3
3
use either:: Either ;
4
+ use rustc_middle:: ty:: TyCtxt ;
4
5
use tracing:: trace;
5
6
6
7
use rustc_middle:: span_bug;
@@ -827,20 +828,19 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
827
828
} ;
828
829
829
830
// 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 ) =
831
832
receiver_place. layout . ty . kind ( )
832
833
{
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) ?;
835
835
836
- ( vptr , dyn_ty , recv. ptr ( ) )
836
+ ( data . principal ( ) , recv . layout . ty , recv. ptr ( ) )
837
837
} else {
838
838
// Doesn't have to be a `dyn Trait`, but the unsized tail must be `dyn Trait`.
839
839
// (For that reason we also cannot use `unpack_dyn_trait`.)
840
840
let receiver_tail = self
841
841
. tcx
842
842
. 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 {
844
844
span_bug ! (
845
845
self . cur_span( ) ,
846
846
"dynamic call on non-`dyn` type {}" ,
@@ -851,25 +851,24 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
851
851
852
852
// Get the required information from the vtable.
853
853
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) ) ?;
861
855
862
856
// It might be surprising that we use a pointer as the receiver even if this
863
857
// is a by-val case; this works because by-val passing of an unsized `dyn
864
858
// 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 ( ) )
866
860
} ;
867
861
868
862
// Now determine the actual method to call. We can do that in two different ways and
869
863
// 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 {
873
872
// FIXME(fee1-dead) these could be variants of the UB info enum instead of this
874
873
throw_ub_custom ! ( fluent:: const_eval_dyn_call_not_a_method) ;
875
874
} ;
@@ -898,7 +897,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
898
897
let receiver_ty = Ty :: new_mut_ptr ( self . tcx . tcx , dyn_ty) ;
899
898
args[ 0 ] = FnArg :: Copy (
900
899
ImmTy :: from_immediate (
901
- Scalar :: from_maybe_pointer ( adjusted_receiver , self ) . into ( ) ,
900
+ Scalar :: from_maybe_pointer ( adjusted_recv , self ) . into ( ) ,
902
901
self . layout_of ( receiver_ty) ?,
903
902
)
904
903
. into ( ) ,
@@ -974,11 +973,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
974
973
let place = match place. layout . ty . kind ( ) {
975
974
ty:: Dynamic ( data, _, ty:: Dyn ) => {
976
975
// 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) ?
978
977
}
979
978
ty:: Dynamic ( data, _, ty:: DynStar ) => {
980
979
// Dropping a `dyn*`. Need to find actual drop fn.
981
- self . unpack_dyn_star ( & place, data) ?. 0
980
+ self . unpack_dyn_star ( & place, data) ?
982
981
}
983
982
_ => {
984
983
debug_assert_eq ! (
0 commit comments