@@ -741,15 +741,15 @@ fn expand_cxx_function_shim(efn: &ExternFn, types: &Types) -> TokenStream {
741741 #trampolines
742742 #dispatch
743743 } ) ;
744- match & efn. receiver {
745- None => {
744+ match ( & efn. receiver , & efn . self_type ) {
745+ ( None , None ) => {
746746 quote ! {
747747 #doc
748748 #attrs
749749 #visibility #unsafety #fn_token #ident #generics #arg_list #ret #fn_body
750750 }
751751 }
752- Some ( receiver) => {
752+ ( Some ( receiver) , None ) => {
753753 let elided_generics;
754754 let receiver_ident = & receiver. ty . rust ;
755755 let resolve = types. resolve ( & receiver. ty ) ;
@@ -781,6 +781,39 @@ fn expand_cxx_function_shim(efn: &ExternFn, types: &Types) -> TokenStream {
781781 }
782782 }
783783 }
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" ) ,
784817 }
785818}
786819
@@ -797,6 +830,7 @@ fn expand_function_pointer_trampoline(
797830 let body_span = efn. semi_token . span ;
798831 let shim = expand_rust_function_shim_impl (
799832 sig,
833+ & efn. self_type ,
800834 types,
801835 & r_trampoline,
802836 local_name,
@@ -940,18 +974,33 @@ fn expand_forbid(impls: TokenStream) -> TokenStream {
940974
941975fn expand_rust_function_shim ( efn : & ExternFn , types : & Types ) -> TokenStream {
942976 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+ let local_name = match ( & efn. receiver , & efn. self_type ) {
978+ ( None , None ) => format_ident ! ( "__{}" , efn. name. rust) ,
979+ ( Some ( receiver) , None ) => format_ident ! ( "__{}__{}" , receiver. ty. rust, efn. name. rust) ,
980+ ( None , Some ( self_type) ) => format_ident ! (
981+ "__{}__{}" ,
982+ types. resolve( self_type) . name. rust,
983+ efn. name. rust
984+ ) ,
985+ _ => unreachable ! ( "receiver and self_type are mutually exclusive" ) ,
946986 } ;
947- let prevent_unwind_label = match & efn. receiver {
948- None => format ! ( "::{}" , efn. name. rust) ,
949- Some ( receiver) => format ! ( "::{}::{}" , receiver. ty. rust, efn. name. rust) ,
987+ let prevent_unwind_label = match ( & efn. receiver , & efn. self_type ) {
988+ ( None , None ) => format ! ( "::{}" , efn. name. rust) ,
989+ ( Some ( receiver) , None ) => format ! ( "::{}::{}" , receiver. ty. rust, efn. name. rust) ,
990+ ( None , Some ( self_type) ) => {
991+ format ! (
992+ "::{}::{}" ,
993+ types. resolve( self_type) . name. rust,
994+ efn. name. rust
995+ )
996+ }
997+ _ => unreachable ! ( "receiver and self_type are mutually exclusive" ) ,
950998 } ;
951999 let invoke = Some ( & efn. name . rust ) ;
9521000 let body_span = efn. semi_token . span ;
9531001 expand_rust_function_shim_impl (
9541002 efn,
1003+ & efn. self_type ,
9551004 types,
9561005 & link_name,
9571006 local_name,
@@ -965,6 +1014,7 @@ fn expand_rust_function_shim(efn: &ExternFn, types: &Types) -> TokenStream {
9651014
9661015fn expand_rust_function_shim_impl (
9671016 sig : & Signature ,
1017+ self_type : & Option < Ident > ,
9681018 types : & Types ,
9691019 link_name : & Symbol ,
9701020 local_name : Ident ,
@@ -1057,7 +1107,8 @@ fn expand_rust_function_shim_impl(
10571107 } ) ;
10581108 let vars: Vec < _ > = receiver_var. into_iter ( ) . chain ( arg_vars) . collect ( ) ;
10591109
1060- let wrap_super = invoke. map ( |invoke| expand_rust_function_shim_super ( sig, & local_name, invoke) ) ;
1110+ let wrap_super = invoke
1111+ . map ( |invoke| expand_rust_function_shim_super ( sig, self_type, types, & local_name, invoke) ) ;
10611112
10621113 let mut requires_closure;
10631114 let mut call = match invoke {
@@ -1182,6 +1233,8 @@ fn expand_rust_function_shim_impl(
11821233// accurate unsafety declaration and no problematic elided lifetimes.
11831234fn expand_rust_function_shim_super (
11841235 sig : & Signature ,
1236+ self_type : & Option < Ident > ,
1237+ types : & Types ,
11851238 local_name : & Ident ,
11861239 invoke : & Ident ,
11871240) -> TokenStream {
@@ -1222,12 +1275,17 @@ fn expand_rust_function_shim_super(
12221275 let vars = receiver_var. iter ( ) . chain ( arg_vars) ;
12231276
12241277 let span = invoke. span ( ) ;
1225- let call = match & sig. receiver {
1226- None => quote_spanned ! ( span=> super :: #invoke) ,
1227- Some ( receiver) => {
1278+ let call = match ( & sig. receiver , & self_type ) {
1279+ ( None , None ) => quote_spanned ! ( span=> super :: #invoke) ,
1280+ ( Some ( receiver) , None ) => {
12281281 let receiver_type = & receiver. ty . rust ;
12291282 quote_spanned ! ( span=> #receiver_type:: #invoke)
12301283 }
1284+ ( None , Some ( self_type) ) => {
1285+ let self_type = & types. resolve ( self_type) . name . rust ;
1286+ quote_spanned ! ( span=> #self_type:: #invoke)
1287+ }
1288+ _ => unreachable ! ( "receiver and self_type are mutually exclusive" ) ,
12311289 } ;
12321290
12331291 let mut body = quote_spanned ! ( span=> #call( #( #vars, ) * ) ) ;
0 commit comments