@@ -1020,16 +1020,20 @@ where
1020
1020
pub ( super ) fn unpack_dyn_trait (
1021
1021
& self ,
1022
1022
mplace : & MPlaceTy < ' tcx , M :: Provenance > ,
1023
+ expected_trait : & ' tcx ty:: List < ty:: PolyExistentialPredicate < ' tcx > > ,
1023
1024
) -> InterpResult < ' tcx , ( MPlaceTy < ' tcx , M :: Provenance > , Pointer < Option < M :: Provenance > > ) > {
1024
1025
assert ! (
1025
1026
matches!( mplace. layout. ty. kind( ) , ty:: Dynamic ( _, _, ty:: Dyn ) ) ,
1026
1027
"`unpack_dyn_trait` only makes sense on `dyn*` types"
1027
1028
) ;
1028
1029
let vtable = mplace. meta ( ) . unwrap_meta ( ) . to_pointer ( self ) ?;
1029
- let ( ty, _) = self . get_ptr_vtable ( vtable) ?;
1030
- let layout = self . layout_of ( ty) ?;
1030
+ let ( ty, vtable_trait) = self . get_ptr_vtable ( vtable) ?;
1031
+ if expected_trait. principal ( ) != vtable_trait {
1032
+ throw_ub ! ( InvalidVTableTrait { expected_trait, vtable_trait } ) ;
1033
+ }
1031
1034
// This is a kind of transmute, from a place with unsized type and metadata to
1032
1035
// a place with sized type and no metadata.
1036
+ let layout = self . layout_of ( ty) ?;
1033
1037
let mplace =
1034
1038
MPlaceTy { mplace : MemPlace { meta : MemPlaceMeta :: None , ..mplace. mplace } , layout } ;
1035
1039
Ok ( ( mplace, vtable) )
@@ -1040,6 +1044,7 @@ where
1040
1044
pub ( super ) fn unpack_dyn_star < P : Projectable < ' tcx , M :: Provenance > > (
1041
1045
& self ,
1042
1046
val : & P ,
1047
+ expected_trait : & ' tcx ty:: List < ty:: PolyExistentialPredicate < ' tcx > > ,
1043
1048
) -> InterpResult < ' tcx , ( P , Pointer < Option < M :: Provenance > > ) > {
1044
1049
assert ! (
1045
1050
matches!( val. layout( ) . ty. kind( ) , ty:: Dynamic ( _, _, ty:: DynStar ) ) ,
@@ -1048,10 +1053,12 @@ where
1048
1053
let data = self . project_field ( val, 0 ) ?;
1049
1054
let vtable = self . project_field ( val, 1 ) ?;
1050
1055
let vtable = self . read_pointer ( & vtable. to_op ( self ) ?) ?;
1051
- let ( ty, _) = self . get_ptr_vtable ( vtable) ?;
1056
+ let ( ty, vtable_trait) = self . get_ptr_vtable ( vtable) ?;
1057
+ if expected_trait. principal ( ) != vtable_trait {
1058
+ throw_ub ! ( InvalidVTableTrait { expected_trait, vtable_trait } ) ;
1059
+ }
1060
+ // `data` is already the right thing but has the wrong type. So we transmute it.
1052
1061
let layout = self . layout_of ( ty) ?;
1053
- // `data` is already the right thing but has the wrong type. So we transmute it, by
1054
- // projecting with offset 0.
1055
1062
let data = data. transmute ( layout, self ) ?;
1056
1063
Ok ( ( data, vtable) )
1057
1064
}
0 commit comments