@@ -49,6 +49,75 @@ mod optimise1;
4949/// An instance of our Java bytecode codegen backend.
5050struct MyBackend ;
5151
52+ /// Helper function to lower a closure definition to OOMIR
53+ ///
54+ /// This function is called when we encounter a closure call and need to ensure
55+ /// the closure's implementation is available in the OOMIR module.
56+ fn lower_closure_to_oomir < ' tcx > (
57+ tcx : TyCtxt < ' tcx > ,
58+ closure_def_id : rustc_hir:: def_id:: DefId ,
59+ oomir_module : & mut oomir:: Module ,
60+ ) {
61+ // Generate the closure function name
62+ let closure_name = lower1:: generate_closure_function_name ( tcx, closure_def_id) ;
63+
64+ // Check if we've already lowered this closure
65+ if oomir_module. functions . contains_key ( & closure_name) {
66+ breadcrumbs:: log!(
67+ breadcrumbs:: LogLevel :: Info ,
68+ "closure-lowering" ,
69+ format!( "Closure {} already lowered, skipping" , closure_name)
70+ ) ;
71+ return ;
72+ }
73+
74+ breadcrumbs:: log!(
75+ breadcrumbs:: LogLevel :: Info ,
76+ "closure-lowering" ,
77+ format!(
78+ "Lowering closure: {} (DefId: {:?})" ,
79+ closure_name, closure_def_id
80+ )
81+ ) ;
82+
83+ // Get the closure's MIR using expect_resolve with fully monomorphized typing environment
84+ // We use fully_monomorphized() since we've already filtered out closures with captures.
85+ use rustc_middle:: ty:: TypingEnv ;
86+ let typing_env = TypingEnv :: fully_monomorphized ( ) ;
87+ let generic_args = rustc_middle:: ty:: GenericArgs :: empty ( ) ;
88+
89+ let instance = rustc_middle:: ty:: Instance :: expect_resolve (
90+ tcx,
91+ typing_env,
92+ closure_def_id,
93+ generic_args,
94+ rustc_span:: DUMMY_SP ,
95+ ) ;
96+
97+ let mut mir = tcx. optimized_mir ( instance. def_id ( ) ) . clone ( ) ;
98+
99+ breadcrumbs:: log!(
100+ breadcrumbs:: LogLevel :: Info ,
101+ "closure-lowering" ,
102+ format!( "Closure MIR for {}: {:?}" , closure_name, mir)
103+ ) ;
104+
105+ // Lower the closure MIR to OOMIR, providing the closure name as an override
106+ // since closures don't have proper item names in rustc
107+ let ( oomir_function, data_types) =
108+ lower1:: mir_to_oomir ( tcx, instance, & mut mir, Some ( closure_name. clone ( ) ) ) ;
109+
110+ breadcrumbs:: log!(
111+ breadcrumbs:: LogLevel :: Info ,
112+ "closure-lowering" ,
113+ format!( "Successfully lowered closure: {}" , closure_name)
114+ ) ;
115+
116+ // Add the closure function to the module
117+ oomir_module. functions . insert ( closure_name, oomir_function) ;
118+ oomir_module. merge_data_types ( & data_types) ;
119+ }
120+
52121impl CodegenBackend for MyBackend {
53122 fn locale_resource ( & self ) -> & ' static str {
54123 ""
@@ -69,6 +138,10 @@ impl CodegenBackend for MyBackend {
69138 data_types : std:: collections:: HashMap :: new ( ) ,
70139 } ;
71140
141+ // Track closures we need to lower
142+ let mut closures_to_lower: std:: collections:: HashSet < rustc_hir:: def_id:: DefId > =
143+ std:: collections:: HashSet :: new ( ) ;
144+
72145 // Iterate through all items in the crate and find functions
73146 let module_items = tcx. hir_crate_items ( ( ) ) ;
74147
@@ -92,12 +165,45 @@ impl CodegenBackend for MyBackend {
92165 format!( "MIR for function {i}: {:?}" , mir)
93166 ) ;
94167
168+ // Collect closures from mentioned_items in the MIR
169+ if let Some ( mentioned_items) = & mir. mentioned_items {
170+ for mentioned in mentioned_items. iter ( ) {
171+ // Check if this mentioned item is a closure
172+ if let rustc_middle:: mir:: MentionedItem :: Fn ( fn_ty) = & mentioned. node {
173+ if let rustc_middle:: ty:: TyKind :: FnDef ( _fn_def_id, fn_args) =
174+ fn_ty. kind ( )
175+ {
176+ // Check the first argument to see if it's a closure type
177+ if let Some ( first_arg) = fn_args. get ( 0 ) {
178+ if let Some ( ty) = first_arg. as_type ( ) {
179+ if let rustc_middle:: ty:: TyKind :: Closure (
180+ closure_def_id,
181+ _,
182+ ) = ty. kind ( )
183+ {
184+ breadcrumbs:: log!(
185+ breadcrumbs:: LogLevel :: Info ,
186+ "closure-discovery" ,
187+ format!(
188+ "Found closure {:?} in function {}" ,
189+ closure_def_id, i
190+ )
191+ ) ;
192+ closures_to_lower. insert ( * closure_def_id) ;
193+ }
194+ }
195+ }
196+ }
197+ }
198+ }
199+ }
200+
95201 breadcrumbs:: log!(
96202 breadcrumbs:: LogLevel :: Info ,
97203 "mir-lowering" ,
98204 format!( "--- Starting MIR to OOMIR Lowering for function: {i} ---" )
99205 ) ;
100- let oomir_result = lower1:: mir_to_oomir ( tcx, instance, & mut mir) ;
206+ let oomir_result = lower1:: mir_to_oomir ( tcx, instance, & mut mir, None ) ;
101207 breadcrumbs:: log!(
102208 breadcrumbs:: LogLevel :: Info ,
103209 "mir-lowering" ,
@@ -167,12 +273,43 @@ impl CodegenBackend for MyBackend {
167273 format!( "MIR for function {i2}: {:?}" , mir)
168274 ) ;
169275
276+ // Collect closures from mentioned_items in the MIR
277+ if let Some ( mentioned_items) = & mir. mentioned_items {
278+ for mentioned in mentioned_items. iter ( ) {
279+ if let rustc_middle:: mir:: MentionedItem :: Fn ( fn_ty) = & mentioned. node {
280+ if let rustc_middle:: ty:: TyKind :: FnDef ( _fn_def_id, fn_args) =
281+ fn_ty. kind ( )
282+ {
283+ if let Some ( first_arg) = fn_args. get ( 0 ) {
284+ if let Some ( ty) = first_arg. as_type ( ) {
285+ if let rustc_middle:: ty:: TyKind :: Closure (
286+ closure_def_id,
287+ _,
288+ ) = ty. kind ( )
289+ {
290+ breadcrumbs:: log!(
291+ breadcrumbs:: LogLevel :: Info ,
292+ "closure-discovery" ,
293+ format!(
294+ "Found closure {:?} in impl method {}" ,
295+ closure_def_id, i2
296+ )
297+ ) ;
298+ closures_to_lower. insert ( * closure_def_id) ;
299+ }
300+ }
301+ }
302+ }
303+ }
304+ }
305+ }
306+
170307 breadcrumbs:: log!(
171308 breadcrumbs:: LogLevel :: Info ,
172309 "mir-lowering" ,
173310 format!( "--- Starting MIR to OOMIR Lowering for function: {i2} ---" )
174311 ) ;
175- let oomir_result = lower1:: mir_to_oomir ( tcx, instance, & mut mir) ;
312+ let oomir_result = lower1:: mir_to_oomir ( tcx, instance, & mut mir, None ) ;
176313 breadcrumbs:: log!(
177314 breadcrumbs:: LogLevel :: Info ,
178315 "mir-lowering" ,
@@ -566,6 +703,37 @@ impl CodegenBackend for MyBackend {
566703 }
567704 }
568705
706+ // Now lower all discovered closures
707+ breadcrumbs:: log!(
708+ breadcrumbs:: LogLevel :: Info ,
709+ "closure-lowering" ,
710+ format!(
711+ "Attempting to lower {} discovered closures" ,
712+ closures_to_lower. len( )
713+ )
714+ ) ;
715+
716+ for closure_def_id in closures_to_lower {
717+ // Check if this closure captures any variables (has upvars)
718+ // Closures that don't capture anything can be lowered with Instance::mono
719+ let upvars = tcx. upvars_mentioned ( closure_def_id) ;
720+
721+ if upvars. is_some ( ) && !upvars. unwrap ( ) . is_empty ( ) {
722+ breadcrumbs:: log!(
723+ breadcrumbs:: LogLevel :: Warn ,
724+ "closure-lowering" ,
725+ format!(
726+ "Closure {} captures variables ({} upvars), skipping for now" ,
727+ lower1:: generate_closure_function_name( tcx, closure_def_id) ,
728+ upvars. unwrap( ) . len( )
729+ )
730+ ) ;
731+ continue ;
732+ }
733+
734+ lower_closure_to_oomir ( tcx, closure_def_id, & mut oomir_module) ;
735+ }
736+
569737 breadcrumbs:: log!(
570738 breadcrumbs:: LogLevel :: Info ,
571739 "backend" ,
@@ -714,7 +882,7 @@ impl CodegenBackend for MyBackend {
714882
715883struct RustcCodegenJvmLogListener ;
716884
717- const LISTENING_CHANNELS : & [ & str ] = & [ "backend" ] ;
885+ const LISTENING_CHANNELS : & [ & str ] = & [ ] ;
718886
719887impl breadcrumbs:: LogListener for RustcCodegenJvmLogListener {
720888 fn on_log ( & mut self , log : breadcrumbs:: Log ) {
0 commit comments