@@ -771,9 +771,15 @@ fn emit_vtable_methods<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
771
771
impl_id : ast:: DefId ,
772
772
substs : subst:: Substs < ' tcx > ,
773
773
param_substs : & ' tcx subst:: Substs < ' tcx > )
774
- -> Vec < ValueRef > {
774
+ -> Vec < ValueRef >
775
+ {
775
776
let tcx = ccx. tcx ( ) ;
776
777
778
+ debug ! ( "emit_vtable_methods(impl_id={}, substs={}, param_substs={})" ,
779
+ impl_id. repr( tcx) ,
780
+ substs. repr( tcx) ,
781
+ param_substs. repr( tcx) ) ;
782
+
777
783
let trt_id = match ty:: impl_trait_ref ( tcx, impl_id) {
778
784
Some ( t_id) => t_id. def_id ,
779
785
None => ccx. sess ( ) . bug ( "make_impl_vtable: don't know how to \
@@ -783,41 +789,66 @@ fn emit_vtable_methods<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
783
789
ty:: populate_implementations_for_trait_if_necessary ( tcx, trt_id) ;
784
790
785
791
let trait_item_def_ids = ty:: trait_item_def_ids ( tcx, trt_id) ;
786
- trait_item_def_ids. iter ( ) . flat_map ( |method_def_id| {
787
- let method_def_id = method_def_id. def_id ( ) ;
788
- let name = ty:: impl_or_trait_item ( tcx, method_def_id) . name ( ) ;
789
- // The substitutions we have are on the impl, so we grab
790
- // the method type from the impl to substitute into.
791
- let m_id = method_with_name ( ccx, impl_id, name) ;
792
- let ti = ty:: impl_or_trait_item ( tcx, m_id) ;
793
- match ti {
794
- ty:: MethodTraitItem ( m) => {
795
- debug ! ( "(making impl vtable) emitting method {} at subst {}" ,
796
- m. repr( tcx) ,
797
- substs. repr( tcx) ) ;
798
- if m. generics . has_type_params ( subst:: FnSpace ) ||
799
- ty:: type_has_self ( ty:: mk_bare_fn ( tcx, None , tcx. mk_bare_fn ( m. fty . clone ( ) ) ) )
800
- {
801
- debug ! ( "(making impl vtable) method has self or type \
802
- params: {}",
803
- token:: get_name( name) ) ;
804
- Some ( C_null ( Type :: nil ( ccx) . ptr_to ( ) ) ) . into_iter ( )
805
- } else {
806
- let fn_ref = trans_fn_ref_with_substs (
807
- ccx,
808
- m_id,
809
- ExprId ( 0 ) ,
810
- param_substs,
811
- substs. clone ( ) ) . val ;
812
-
813
- Some ( fn_ref) . into_iter ( )
814
- }
792
+ trait_item_def_ids
793
+ . iter ( )
794
+
795
+ // Filter out the associated types.
796
+ . filter_map ( |item_def_id| {
797
+ match * item_def_id {
798
+ ty:: MethodTraitItemId ( def_id) => Some ( def_id) ,
799
+ ty:: TypeTraitItemId ( _) => None ,
815
800
}
816
- ty:: TypeTraitItem ( _) => {
817
- None . into_iter ( )
801
+ } )
802
+
803
+ // Now produce pointers for each remaining method. If the
804
+ // method could never be called from this object, just supply
805
+ // null.
806
+ . map ( |trait_method_def_id| {
807
+ debug ! ( "emit_vtable_methods: trait_method_def_id={}" ,
808
+ trait_method_def_id. repr( tcx) ) ;
809
+
810
+ let trait_method_type = match ty:: impl_or_trait_item ( tcx, trait_method_def_id) {
811
+ ty:: MethodTraitItem ( m) => m,
812
+ ty:: TypeTraitItem ( _) => ccx. sess ( ) . bug ( "should be a method, not assoc type" )
813
+ } ;
814
+ let name = trait_method_type. name ;
815
+
816
+ debug ! ( "emit_vtable_methods: trait_method_type={}" ,
817
+ trait_method_type. repr( tcx) ) ;
818
+
819
+ // The substitutions we have are on the impl, so we grab
820
+ // the method type from the impl to substitute into.
821
+ let impl_method_def_id = method_with_name ( ccx, impl_id, name) ;
822
+ let impl_method_type = match ty:: impl_or_trait_item ( tcx, impl_method_def_id) {
823
+ ty:: MethodTraitItem ( m) => m,
824
+ ty:: TypeTraitItem ( _) => ccx. sess ( ) . bug ( "should be a method, not assoc type" )
825
+ } ;
826
+
827
+ debug ! ( "emit_vtable_methods: m={}" ,
828
+ impl_method_type. repr( tcx) ) ;
829
+
830
+ let nullptr = C_null ( Type :: nil ( ccx) . ptr_to ( ) ) ;
831
+
832
+ if impl_method_type. generics . has_type_params ( subst:: FnSpace ) {
833
+ debug ! ( "emit_vtable_methods: generic" ) ;
834
+ return nullptr;
818
835
}
819
- }
820
- } ) . collect ( )
836
+
837
+ let bare_fn_ty =
838
+ ty:: mk_bare_fn ( tcx, None , tcx. mk_bare_fn ( impl_method_type. fty . clone ( ) ) ) ;
839
+ if ty:: type_has_self ( bare_fn_ty) {
840
+ debug ! ( "emit_vtable_methods: type_has_self {}" ,
841
+ bare_fn_ty. repr( tcx) ) ;
842
+ return nullptr;
843
+ }
844
+
845
+ trans_fn_ref_with_substs ( ccx,
846
+ impl_method_def_id,
847
+ ExprId ( 0 ) ,
848
+ param_substs,
849
+ substs. clone ( ) ) . val
850
+ } )
851
+ . collect ( )
821
852
}
822
853
823
854
/// Generates the code to convert from a pointer (`Box<T>`, `&T`, etc) into an object
0 commit comments