@@ -741,15 +741,15 @@ fn expand_cxx_function_shim(efn: &ExternFn, types: &Types) -> TokenStream {
741
741
#trampolines
742
742
#dispatch
743
743
} ) ;
744
- match & efn. receiver {
745
- None => {
744
+ match ( & efn. receiver , & efn . self_type ) {
745
+ ( None , None ) => {
746
746
quote ! {
747
747
#doc
748
748
#attrs
749
749
#visibility #unsafety #fn_token #ident #generics #arg_list #ret #fn_body
750
750
}
751
751
}
752
- Some ( receiver) => {
752
+ ( Some ( receiver) , None ) => {
753
753
let elided_generics;
754
754
let receiver_ident = & receiver. ty . rust ;
755
755
let resolve = types. resolve ( & receiver. ty ) ;
@@ -781,6 +781,39 @@ fn expand_cxx_function_shim(efn: &ExternFn, types: &Types) -> TokenStream {
781
781
}
782
782
}
783
783
}
784
+ ( None , Some ( self_type) ) => {
785
+ let elided_generics;
786
+ let resolve = types. resolve ( self_type) ;
787
+ let self_type_ident = & resolve. name . rust ;
788
+ let self_type_generics = if resolve. generics . lt_token . is_some ( ) {
789
+ & resolve. generics
790
+ } else {
791
+ elided_generics = Lifetimes {
792
+ lt_token : resolve. generics . lt_token ,
793
+ lifetimes : resolve
794
+ . generics
795
+ . lifetimes
796
+ . pairs ( )
797
+ . map ( |pair| {
798
+ let lifetime = Lifetime :: new ( "'_" , pair. value ( ) . apostrophe ) ;
799
+ let punct = pair. punct ( ) . map ( |& & comma| comma) ;
800
+ punctuated:: Pair :: new ( lifetime, punct)
801
+ } )
802
+ . collect ( ) ,
803
+ gt_token : resolve. generics . gt_token ,
804
+ } ;
805
+ & elided_generics
806
+ } ;
807
+ quote_spanned ! { ident. span( ) =>
808
+ #[ automatically_derived]
809
+ impl #generics #self_type_ident #self_type_generics {
810
+ #doc
811
+ #attrs
812
+ #visibility #unsafety #fn_token #ident #arg_list #ret #fn_body
813
+ }
814
+ }
815
+ }
816
+ _ => unreachable ! ( "receiver and self_type are mutually exclusive" ) ,
784
817
}
785
818
}
786
819
@@ -797,6 +830,7 @@ fn expand_function_pointer_trampoline(
797
830
let body_span = efn. semi_token . span ;
798
831
let shim = expand_rust_function_shim_impl (
799
832
sig,
833
+ & efn. self_type ,
800
834
types,
801
835
& r_trampoline,
802
836
local_name,
@@ -940,18 +974,34 @@ fn expand_forbid(impls: TokenStream) -> TokenStream {
940
974
941
975
fn expand_rust_function_shim ( efn : & ExternFn , types : & Types ) -> TokenStream {
942
976
let link_name = mangle:: extern_fn ( efn, types) ;
943
- let local_name = match & efn. receiver {
944
- None => format_ident ! ( "__{}" , efn. name. rust) ,
945
- Some ( receiver) => format_ident ! ( "__{}__{}" , receiver. ty. rust, efn. name. rust) ,
977
+ eprintln ! ( "link_name: {}" , link_name) ;
978
+ let local_name = match ( & efn. receiver , & efn. self_type ) {
979
+ ( None , None ) => format_ident ! ( "__{}" , efn. name. rust) ,
980
+ ( Some ( receiver) , None ) => format_ident ! ( "__{}__{}" , receiver. ty. rust, efn. name. rust) ,
981
+ ( None , Some ( self_type) ) => format_ident ! (
982
+ "__{}__{}" ,
983
+ types. resolve( self_type) . name. rust,
984
+ efn. name. rust
985
+ ) ,
986
+ _ => unreachable ! ( "receiver and self_type are mutually exclusive" ) ,
946
987
} ;
947
- let prevent_unwind_label = match & efn. receiver {
948
- None => format ! ( "::{}" , efn. name. rust) ,
949
- Some ( receiver) => format ! ( "::{}::{}" , receiver. ty. rust, efn. name. rust) ,
988
+ let prevent_unwind_label = match ( & efn. receiver , & efn. self_type ) {
989
+ ( None , None ) => format ! ( "::{}" , efn. name. rust) ,
990
+ ( Some ( receiver) , None ) => format ! ( "::{}::{}" , receiver. ty. rust, efn. name. rust) ,
991
+ ( None , Some ( self_type) ) => {
992
+ format ! (
993
+ "::{}::{}" ,
994
+ types. resolve( self_type) . name. rust,
995
+ efn. name. rust
996
+ )
997
+ }
998
+ _ => unreachable ! ( "receiver and self_type are mutually exclusive" ) ,
950
999
} ;
951
1000
let invoke = Some ( & efn. name . rust ) ;
952
1001
let body_span = efn. semi_token . span ;
953
1002
expand_rust_function_shim_impl (
954
1003
efn,
1004
+ & efn. self_type ,
955
1005
types,
956
1006
& link_name,
957
1007
local_name,
@@ -965,6 +1015,7 @@ fn expand_rust_function_shim(efn: &ExternFn, types: &Types) -> TokenStream {
965
1015
966
1016
fn expand_rust_function_shim_impl (
967
1017
sig : & Signature ,
1018
+ self_type : & Option < Ident > ,
968
1019
types : & Types ,
969
1020
link_name : & Symbol ,
970
1021
local_name : Ident ,
@@ -1057,7 +1108,8 @@ fn expand_rust_function_shim_impl(
1057
1108
} ) ;
1058
1109
let vars: Vec < _ > = receiver_var. into_iter ( ) . chain ( arg_vars) . collect ( ) ;
1059
1110
1060
- let wrap_super = invoke. map ( |invoke| expand_rust_function_shim_super ( sig, & local_name, invoke) ) ;
1111
+ let wrap_super = invoke
1112
+ . map ( |invoke| expand_rust_function_shim_super ( sig, self_type, types, & local_name, invoke) ) ;
1061
1113
1062
1114
let mut requires_closure;
1063
1115
let mut call = match invoke {
@@ -1182,6 +1234,8 @@ fn expand_rust_function_shim_impl(
1182
1234
// accurate unsafety declaration and no problematic elided lifetimes.
1183
1235
fn expand_rust_function_shim_super (
1184
1236
sig : & Signature ,
1237
+ self_type : & Option < Ident > ,
1238
+ types : & Types ,
1185
1239
local_name : & Ident ,
1186
1240
invoke : & Ident ,
1187
1241
) -> TokenStream {
@@ -1222,12 +1276,17 @@ fn expand_rust_function_shim_super(
1222
1276
let vars = receiver_var. iter ( ) . chain ( arg_vars) ;
1223
1277
1224
1278
let span = invoke. span ( ) ;
1225
- let call = match & sig. receiver {
1226
- None => quote_spanned ! ( span=> super :: #invoke) ,
1227
- Some ( receiver) => {
1279
+ let call = match ( & sig. receiver , & self_type ) {
1280
+ ( None , None ) => quote_spanned ! ( span=> super :: #invoke) ,
1281
+ ( Some ( receiver) , None ) => {
1228
1282
let receiver_type = & receiver. ty . rust ;
1229
1283
quote_spanned ! ( span=> #receiver_type:: #invoke)
1230
1284
}
1285
+ ( None , Some ( self_type) ) => {
1286
+ let self_type = & types. resolve ( self_type) . name . rust ;
1287
+ quote_spanned ! ( span=> #self_type:: #invoke)
1288
+ }
1289
+ _ => unreachable ! ( "receiver and self_type are mutually exclusive" ) ,
1231
1290
} ;
1232
1291
1233
1292
let mut body = quote_spanned ! ( span=> #call( #( #vars, ) * ) ) ;
0 commit comments