@@ -23,6 +23,69 @@ pub fn ty_is_never<'tcx>(ty: Ty<'tcx>) -> bool {
2323 matches ! ( ty. kind( ) , TyKind :: Never )
2424}
2525
26+ pub fn fn_ptr_signature_from_ty < ' tcx > (
27+ ty : Ty < ' tcx > ,
28+ tcx : TyCtxt < ' tcx > ,
29+ data_types : & mut HashMap < String , oomir:: DataType > ,
30+ instance_context : rustc_middle:: ty:: Instance < ' tcx > ,
31+ ) -> oomir:: Signature {
32+ let sig = ty. fn_sig ( tcx) . skip_binder ( ) ;
33+ let params = sig
34+ . inputs ( )
35+ . iter ( )
36+ . enumerate ( )
37+ . map ( |( i, ty) | {
38+ (
39+ format ! ( "arg{}" , i) ,
40+ ty_to_oomir_type ( * ty, tcx, data_types, instance_context) ,
41+ )
42+ } )
43+ . collect ( ) ;
44+ let ret = ty_to_oomir_type ( sig. output ( ) , tcx, data_types, instance_context) ;
45+
46+ oomir:: Signature {
47+ params,
48+ ret : Box :: new ( ret) ,
49+ is_static : true ,
50+ }
51+ }
52+
53+ pub fn ensure_fn_ptr_interface (
54+ signature : & oomir:: Signature ,
55+ data_types : & mut HashMap < String , oomir:: DataType > ,
56+ ) -> String {
57+ let interface_name = signature. fn_ptr_interface_name ( ) ;
58+ let method_signature = signature. fn_ptr_interface_method_signature ( ) ;
59+
60+ match data_types. get_mut ( & interface_name) {
61+ Some ( oomir:: DataType :: Interface { methods } ) => {
62+ methods
63+ . entry ( "call" . to_string ( ) )
64+ . or_insert ( method_signature) ;
65+ }
66+ Some ( oomir:: DataType :: Class { .. } ) => {
67+ breadcrumbs:: log!(
68+ breadcrumbs:: LogLevel :: Warn ,
69+ "type-mapping" ,
70+ format!(
71+ "Function pointer interface name '{}' already exists as a class" ,
72+ interface_name
73+ )
74+ ) ;
75+ }
76+ None => {
77+ data_types. insert (
78+ interface_name. clone ( ) ,
79+ oomir:: DataType :: Interface {
80+ methods : HashMap :: from ( [ ( "call" . to_string ( ) , method_signature) ] ) ,
81+ } ,
82+ ) ;
83+ }
84+ }
85+
86+ interface_name
87+ }
88+
2689/// Converts a Rust MIR type (`Ty`) to an OOMIR type (`oomir::Type`).
2790pub fn ty_to_oomir_type < ' tcx > (
2891 ty : Ty < ' tcx > ,
@@ -359,12 +422,22 @@ pub fn ty_to_oomir_type<'tcx>(
359422 ExistentialPredicate :: Trait ( trait_ref) => {
360423 let trait_name = tcx. def_path_str ( trait_ref. def_id ) ;
361424 let safe_name = make_jvm_safe ( & trait_name) ;
425+ data_types. entry ( safe_name. clone ( ) ) . or_insert_with ( || {
426+ oomir:: DataType :: Interface {
427+ methods : HashMap :: new ( ) ,
428+ }
429+ } ) ;
362430 resolved_types. push ( oomir:: Type :: Interface ( safe_name) ) ;
363431 }
364432 ExistentialPredicate :: AutoTrait ( def_id) => {
365433 // Auto traits like Send/Sync — treat as interfaces as well.
366434 let trait_name = tcx. def_path_str ( def_id) ;
367435 let safe_name = make_jvm_safe ( & trait_name) ;
436+ data_types. entry ( safe_name. clone ( ) ) . or_insert_with ( || {
437+ oomir:: DataType :: Interface {
438+ methods : HashMap :: new ( ) ,
439+ }
440+ } ) ;
368441 resolved_types. push ( oomir:: Type :: Interface ( safe_name) ) ;
369442 }
370443 ExistentialPredicate :: Projection ( _) => {
@@ -428,6 +501,12 @@ pub fn ty_to_oomir_type<'tcx>(
428501 }
429502 oomir:: Type :: Class ( safe_name)
430503 }
504+ rustc_middle:: ty:: TyKind :: FnPtr ( _, _) => {
505+ let signature =
506+ fn_ptr_signature_from_ty ( resolved_ty, tcx, data_types, instance_context) ;
507+ let interface_name = ensure_fn_ptr_interface ( & signature, data_types) ;
508+ oomir:: Type :: Interface ( interface_name)
509+ }
431510 rustc_middle:: ty:: TyKind :: FnDef ( def_id, _args) => {
432511 // Named functions are Zero-Sized Types (ZSTs).
433512 // We generate a singleton class so generics like Map<Iter, MyFunc>
0 commit comments