@@ -787,34 +787,45 @@ impl<'tcx> GotocCtx<'tcx> {
787
787
( vt_size, vt_align)
788
788
}
789
789
790
- fn codegen_vtable ( & mut self , o : & Operand < ' tcx > , t : Ty < ' tcx > ) -> & Symbol {
791
- let ( binder_t, underlying_dynamic_type) = match t. kind ( ) {
792
- ty:: Ref ( _region_t, ty:: TyS { kind : ty:: Dynamic ( binder_t, _) , .. } , _) => ( binder_t, t) ,
793
- // For `Box<dyn trait>` generate the vtable for `dyn trait` and not `t`
794
- ty:: Adt ( adt_def, substs_ref) if adt_def. is_box ( ) => {
795
- let dyn_trait = substs_ref. first ( ) . unwrap ( ) . expect_ty ( ) ;
796
- match dyn_trait. kind ( ) {
797
- ty:: Dynamic ( binder_t, _) => ( binder_t, dyn_trait) ,
798
- _ => {
799
- unreachable ! ( "Cannot codegen_vtable for type: Box<{:?}>" , dyn_trait. kind( ) )
800
- }
801
- }
802
- }
803
- _ => unimplemented ! ( "Cannot codegen_vtable for type {:?}" , t. kind( ) ) ,
790
+ fn codegen_vtable ( & mut self , operand : & Operand < ' tcx > , dst_mir_type : Ty < ' tcx > ) -> & Symbol {
791
+ let src_mir_type = self . monomorphize ( self . operand_ty ( operand) ) ;
792
+ return self . codegen_vtable_from_types ( src_mir_type, dst_mir_type) ;
793
+ }
794
+
795
+ fn codegen_vtable_from_types (
796
+ & mut self ,
797
+ src_mir_type : Ty < ' tcx > ,
798
+ dst_mir_type : Ty < ' tcx > ,
799
+ ) -> & Symbol {
800
+ let trait_type = match dst_mir_type. kind ( ) {
801
+ // dst is pointer type
802
+ ty:: Ref ( _, pointee_type, ..) => pointee_type,
803
+ // dst is box type
804
+ ty:: Adt ( adt_def, adt_subst) if adt_def. is_box ( ) => {
805
+ adt_subst. first ( ) . unwrap ( ) . expect_ty ( )
806
+ }
807
+ // dst is dynamic type
808
+ ty:: Dynamic ( ..) => dst_mir_type,
809
+ _ => unimplemented ! ( "Cannot codegen_vtable for type {:?}" , dst_mir_type. kind( ) ) ,
804
810
} ;
805
- let operand_type = self . monomorphize ( self . operand_ty ( o) ) ;
806
- let operand_name = self . ty_mangled_name ( operand_type) ;
811
+ assert ! ( trait_type. is_trait( ) , "VTable trait type {} must be a trait type" , trait_type) ;
812
+ let binders = match trait_type. kind ( ) {
813
+ ty:: Dynamic ( binders, ..) => binders,
814
+ _ => unimplemented ! ( "Cannot codegen_vtable for type {:?}" , dst_mir_type. kind( ) ) ,
815
+ } ;
816
+
817
+ let src_name = self . ty_mangled_name ( src_mir_type) ;
807
818
// name needs to be the same as inserted in typ.rs
808
- let vtable_name = self . vtable_name ( underlying_dynamic_type ) ;
809
- let vtable_impl_name = format ! ( "{}_impl_for_{}" , vtable_name, operand_name ) ;
819
+ let vtable_name = self . vtable_name ( trait_type ) ;
820
+ let vtable_impl_name = format ! ( "{}_impl_for_{}" , vtable_name, src_name ) ;
810
821
811
822
self . ensure ( & vtable_impl_name, |ctx, _| {
812
823
// Build the vtable
813
824
let drop_irep = ctx. codegen_vtable_drop_in_place ( ) ;
814
- let ( vt_size, vt_align) = ctx. codegen_vtable_size_and_align ( & operand_type ) ;
825
+ let ( vt_size, vt_align) = ctx. codegen_vtable_size_and_align ( & src_mir_type ) ;
815
826
let mut vtable_fields = vec ! [ drop_irep, vt_size, vt_align] ;
816
- let trait_ref_t = binder_t . principal ( ) . unwrap ( ) . with_self_ty ( ctx. tcx , operand_type ) ;
817
- let mut methods = ctx. codegen_vtable_methods ( trait_ref_t , underlying_dynamic_type ) ;
827
+ let concrete_type = binders . principal ( ) . unwrap ( ) . with_self_ty ( ctx. tcx , src_mir_type ) ;
828
+ let mut methods = ctx. codegen_vtable_methods ( concrete_type , trait_type ) ;
818
829
vtable_fields. append ( & mut methods) ;
819
830
let vtable = Expr :: struct_expr_from_values (
820
831
Type :: struct_tag ( & vtable_name) ,
0 commit comments