@@ -1020,16 +1020,20 @@ where
10201020 pub ( super ) fn unpack_dyn_trait (
10211021 & self ,
10221022 mplace : & MPlaceTy < ' tcx , M :: Provenance > ,
1023+ expected_trait : & ' tcx ty:: List < ty:: PolyExistentialPredicate < ' tcx > > ,
10231024 ) -> InterpResult < ' tcx , ( MPlaceTy < ' tcx , M :: Provenance > , Pointer < Option < M :: Provenance > > ) > {
10241025 assert ! (
10251026 matches!( mplace. layout. ty. kind( ) , ty:: Dynamic ( _, _, ty:: Dyn ) ) ,
10261027 "`unpack_dyn_trait` only makes sense on `dyn*` types"
10271028 ) ;
10281029 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+ }
10311034 // This is a kind of transmute, from a place with unsized type and metadata to
10321035 // a place with sized type and no metadata.
1036+ let layout = self . layout_of ( ty) ?;
10331037 let mplace =
10341038 MPlaceTy { mplace : MemPlace { meta : MemPlaceMeta :: None , ..mplace. mplace } , layout } ;
10351039 Ok ( ( mplace, vtable) )
@@ -1040,6 +1044,7 @@ where
10401044 pub ( super ) fn unpack_dyn_star < P : Projectable < ' tcx , M :: Provenance > > (
10411045 & self ,
10421046 val : & P ,
1047+ expected_trait : & ' tcx ty:: List < ty:: PolyExistentialPredicate < ' tcx > > ,
10431048 ) -> InterpResult < ' tcx , ( P , Pointer < Option < M :: Provenance > > ) > {
10441049 assert ! (
10451050 matches!( val. layout( ) . ty. kind( ) , ty:: Dynamic ( _, _, ty:: DynStar ) ) ,
@@ -1048,10 +1053,12 @@ where
10481053 let data = self . project_field ( val, 0 ) ?;
10491054 let vtable = self . project_field ( val, 1 ) ?;
10501055 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.
10521061 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.
10551062 let data = data. transmute ( layout, self ) ?;
10561063 Ok ( ( data, vtable) )
10571064 }
0 commit comments