11use crate :: * ;
2- use std:: collections:: { HashMap , HashSet , VecDeque } ;
2+ use std:: collections:: HashMap ;
33
44/// Manages the monomorphization process, generating specialized versions
55/// of generic functions and structs.
@@ -12,12 +12,6 @@ pub struct MonomorphPass {
1212
1313 /// Newly generated specialized declarations
1414 specialized_decls : Vec < Decl > ,
15-
16- /// Work queue of functions that need to be processed
17- worklist : VecDeque < Name > ,
18-
19- /// Functions we've already processed (to avoid duplication)
20- processed : HashSet < Name > ,
2115}
2216
2317impl MonomorphPass {
@@ -26,8 +20,6 @@ impl MonomorphPass {
2620 instantiations : HashMap :: new ( ) ,
2721 recursion_detector : RecursionDetector :: new ( ) ,
2822 specialized_decls : Vec :: new ( ) ,
29- worklist : VecDeque :: new ( ) ,
30- processed : HashSet :: new ( ) ,
3123 }
3224 }
3325
@@ -42,28 +34,16 @@ impl MonomorphPass {
4234 decls : & DeclTable ,
4335 entry_point : Name ,
4436 ) -> Result < Vec < Decl > , String > {
45- // Start with the entry point
46- self . worklist . push_back ( entry_point) ;
47-
48- // Process the worklist until empty
49- while let Some ( func_name) = self . worklist . pop_front ( ) {
50- if self . processed . contains ( & func_name) {
51- continue ;
52- }
53- self . processed . insert ( func_name) ;
54-
55- // Find the function declaration
56- let func_decls = decls. find ( func_name) ;
57- if func_decls. is_empty ( ) {
58- // Built-in function or external function
59- continue ;
60- }
37+ // Find the entry point function declaration
38+ let func_decls = decls. find ( entry_point) ;
39+ if func_decls. is_empty ( ) {
40+ return Err ( format ! ( "Entry point function '{}' not found" , entry_point) ) ;
41+ }
6142
62- // Process each overload
63- for decl in func_decls {
64- if let Decl :: Func ( fdecl) = decl {
65- self . process_function ( fdecl, decls) ?;
66- }
43+ // Process each overload of the entry point
44+ for decl in func_decls {
45+ if let Decl :: Func ( fdecl) = decl {
46+ self . process_function ( fdecl, decls) ?;
6747 }
6848 }
6949
@@ -192,8 +172,8 @@ impl MonomorphPass {
192172 ) ?;
193173
194174 if !type_args. is_empty ( ) {
195- // Create a specialized version
196- self . instantiate_function ( * fn_name, type_args, target_fdecl) ?;
175+ // Create a specialized version and recursively process it
176+ self . instantiate_function ( * fn_name, type_args, target_fdecl, decls ) ?;
197177 }
198178 }
199179 }
@@ -258,7 +238,8 @@ impl MonomorphPass {
258238 & mut self ,
259239 name : Name ,
260240 type_args : Vec < TypeID > ,
261- generic_fdecl : & FuncDecl
241+ generic_fdecl : & FuncDecl ,
242+ decls : & DeclTable ,
262243 ) -> Result < Name , String > {
263244 let key = MonomorphKey :: new ( name, type_args. clone ( ) ) ;
264245
@@ -307,8 +288,8 @@ impl MonomorphPass {
307288 // Add to specialized decls
308289 self . specialized_decls . push ( Decl :: Func ( specialized. clone ( ) ) ) ;
309290
310- // Add to worklist to process its body
311- self . worklist . push_back ( mangled_name ) ;
291+ // Recursively process the specialized function's body immediately
292+ self . process_function ( & specialized , decls ) ? ;
312293
313294 self . recursion_detector . end_instantiation ( ) ;
314295
@@ -336,15 +317,18 @@ mod tests {
336317 use super :: * ;
337318
338319 fn mk_simple_func ( name : & str , typevars : Vec < & str > ) -> FuncDecl {
320+ let mut arena = ExprArena :: new ( ) ;
321+ let body_expr = arena. add ( Expr :: Int ( 0 ) , test_loc ( ) ) ;
322+
339323 FuncDecl {
340324 name : Name :: str ( name) ,
341325 typevars : typevars. iter ( ) . map ( |s| Name :: str ( s) ) . collect ( ) ,
342326 params : Vec :: new ( ) ,
343327 constraints : Vec :: new ( ) ,
344328 ret : mk_type ( Type :: Void ) ,
345- body : Some ( 0 ) ,
346- arena : ExprArena :: new ( ) ,
347- types : Vec :: new ( ) ,
329+ body : Some ( body_expr ) ,
330+ arena,
331+ types : vec ! [ mk_type ( Type :: Int32 ) ] ,
348332 loc : test_loc ( ) ,
349333 }
350334 }
@@ -360,12 +344,14 @@ mod tests {
360344 fn test_instantiate_simple_function ( ) {
361345 let mut pass = MonomorphPass :: new ( ) ;
362346 let generic_func = mk_simple_func ( "id" , vec ! [ "T" ] ) ;
347+ let decls = DeclTable :: new ( vec ! [ ] ) ;
363348
364349 let type_args = vec ! [ mk_type( Type :: Int32 ) ] ;
365350 let result = pass. instantiate_function (
366351 Name :: str ( "id" ) ,
367352 type_args,
368353 & generic_func,
354+ & decls,
369355 ) ;
370356
371357 assert ! ( result. is_ok( ) ) ;
@@ -378,6 +364,7 @@ mod tests {
378364 fn test_instantiate_same_function_twice ( ) {
379365 let mut pass = MonomorphPass :: new ( ) ;
380366 let generic_func = mk_simple_func ( "id" , vec ! [ "T" ] ) ;
367+ let decls = DeclTable :: new ( vec ! [ ] ) ;
381368
382369 let type_args = vec ! [ mk_type( Type :: Int32 ) ] ;
383370
@@ -386,6 +373,7 @@ mod tests {
386373 Name :: str ( "id" ) ,
387374 type_args. clone ( ) ,
388375 & generic_func,
376+ & decls,
389377 ) ;
390378 assert ! ( result1. is_ok( ) ) ;
391379
@@ -394,6 +382,7 @@ mod tests {
394382 Name :: str ( "id" ) ,
395383 type_args,
396384 & generic_func,
385+ & decls,
397386 ) ;
398387 assert ! ( result2. is_ok( ) ) ;
399388 assert_eq ! ( result1. unwrap( ) , result2. unwrap( ) ) ;
@@ -406,12 +395,14 @@ mod tests {
406395 fn test_instantiate_different_type_args ( ) {
407396 let mut pass = MonomorphPass :: new ( ) ;
408397 let generic_func = mk_simple_func ( "id" , vec ! [ "T" ] ) ;
398+ let decls = DeclTable :: new ( vec ! [ ] ) ;
409399
410400 // id<i32>
411401 let result1 = pass. instantiate_function (
412402 Name :: str ( "id" ) ,
413403 vec ! [ mk_type( Type :: Int32 ) ] ,
414404 & generic_func,
405+ & decls,
415406 ) ;
416407 assert ! ( result1. is_ok( ) ) ;
417408 assert_eq ! ( result1. unwrap( ) , Name :: str ( "id$i32" ) ) ;
@@ -421,6 +412,7 @@ mod tests {
421412 Name :: str ( "id" ) ,
422413 vec ! [ mk_type( Type :: Bool ) ] ,
423414 & generic_func,
415+ & decls,
424416 ) ;
425417 assert ! ( result2. is_ok( ) ) ;
426418 assert_eq ! ( result2. unwrap( ) , Name :: str ( "id$bool" ) ) ;
@@ -433,12 +425,14 @@ mod tests {
433425 fn test_instantiate_multiple_type_params ( ) {
434426 let mut pass = MonomorphPass :: new ( ) ;
435427 let generic_func = mk_simple_func ( "map" , vec ! [ "T0" , "T1" ] ) ;
428+ let decls = DeclTable :: new ( vec ! [ ] ) ;
436429
437430 let type_args = vec ! [ mk_type( Type :: Int32 ) , mk_type( Type :: Bool ) ] ;
438431 let result = pass. instantiate_function (
439432 Name :: str ( "map" ) ,
440433 type_args,
441434 & generic_func,
435+ & decls,
442436 ) ;
443437
444438 assert ! ( result. is_ok( ) ) ;
@@ -587,6 +581,7 @@ mod tests {
587581 fn test_get_instantiation ( ) {
588582 let mut pass = MonomorphPass :: new ( ) ;
589583 let generic_func = mk_simple_func ( "id" , vec ! [ "T" ] ) ;
584+ let decls = DeclTable :: new ( vec ! [ ] ) ;
590585
591586 let type_args = vec ! [ mk_type( Type :: Int32 ) ] ;
592587 let key = MonomorphKey :: new ( Name :: str ( "id" ) , type_args. clone ( ) ) ;
@@ -595,7 +590,7 @@ mod tests {
595590 assert ! ( pass. get_instantiation( & key) . is_none( ) ) ;
596591
597592 // After instantiation
598- pass. instantiate_function ( Name :: str ( "id" ) , type_args, & generic_func)
593+ pass. instantiate_function ( Name :: str ( "id" ) , type_args, & generic_func, & decls )
599594 . unwrap ( ) ;
600595 assert_eq ! ( pass. get_instantiation( & key) , Some ( Name :: str ( "id$i32" ) ) ) ;
601596 }
@@ -604,13 +599,15 @@ mod tests {
604599 fn test_specialized_declarations ( ) {
605600 let mut pass = MonomorphPass :: new ( ) ;
606601 let generic_func = mk_simple_func ( "id" , vec ! [ "T" ] ) ;
602+ let decls = DeclTable :: new ( vec ! [ ] ) ;
607603
608604 assert_eq ! ( pass. specialized_declarations( ) . len( ) , 0 ) ;
609605
610606 pass. instantiate_function (
611607 Name :: str ( "id" ) ,
612608 vec ! [ mk_type( Type :: Int32 ) ] ,
613609 & generic_func,
610+ & decls,
614611 ) . unwrap ( ) ;
615612
616613 assert_eq ! ( pass. specialized_declarations( ) . len( ) , 1 ) ;
@@ -619,6 +616,7 @@ mod tests {
619616 #[ test]
620617 fn test_type_substitution_in_specialized_func ( ) {
621618 let mut pass = MonomorphPass :: new ( ) ;
619+ let decls = DeclTable :: new ( vec ! [ ] ) ;
622620
623621 // Create a generic function id<T>(x: T) -> T
624622 let t_var = typevar ( "T" ) ;
@@ -634,6 +632,7 @@ mod tests {
634632 Name :: str ( "id" ) ,
635633 vec ! [ mk_type( Type :: Int32 ) ] ,
636634 & generic_func,
635+ & decls,
637636 ) . unwrap ( ) ;
638637
639638 // Check the specialized declaration
@@ -659,40 +658,16 @@ mod tests {
659658 let decls = DeclTable :: new ( vec ! [ ] ) ;
660659
661660 let result = pass. monomorphize ( & decls, Name :: str ( "main" ) ) ;
662- assert ! ( result. is_ok( ) ) ;
663- assert_eq ! ( result. unwrap( ) . len( ) , 0 ) ;
664- }
665-
666- #[ test]
667- fn test_worklist_processing ( ) {
668- let mut pass = MonomorphPass :: new ( ) ;
669-
670- // Add some items to worklist
671- pass. worklist . push_back ( Name :: str ( "func1" ) ) ;
672- pass. worklist . push_back ( Name :: str ( "func2" ) ) ;
673-
674- assert_eq ! ( pass. worklist. len( ) , 2 ) ;
675-
676- // Simulate processing
677- let func1 = pass. worklist . pop_front ( ) . unwrap ( ) ;
678- assert_eq ! ( func1, Name :: str ( "func1" ) ) ;
679- assert_eq ! ( pass. worklist. len( ) , 1 ) ;
661+ // Should fail because the entry point doesn't exist
662+ assert ! ( result. is_err( ) ) ;
663+ assert ! ( result. unwrap_err( ) . contains( "not found" ) ) ;
680664 }
681665
682- #[ test]
683- fn test_processed_tracking ( ) {
684- let mut pass = MonomorphPass :: new ( ) ;
685-
686- let name = Name :: str ( "test" ) ;
687- assert ! ( !pass. processed. contains( & name) ) ;
688-
689- pass. processed . insert ( name) ;
690- assert ! ( pass. processed. contains( & name) ) ;
691- }
692666
693667 #[ test]
694668 fn test_instantiate_with_nested_generic ( ) {
695669 let mut pass = MonomorphPass :: new ( ) ;
670+ let decls = DeclTable :: new ( vec ! [ ] ) ;
696671
697672 // Create a generic function that works with nested types
698673 let mut generic_func = mk_simple_func ( "process" , vec ! [ "T" ] ) ;
@@ -709,6 +684,7 @@ mod tests {
709684 Name :: str ( "process" ) ,
710685 vec ! [ mk_type( Type :: Int32 ) ] ,
711686 & generic_func,
687+ & decls,
712688 ) ;
713689
714690 assert ! ( result. is_ok( ) ) ;
@@ -730,6 +706,7 @@ mod tests {
730706 #[ test]
731707 fn test_multiple_instantiations_same_function ( ) {
732708 let mut pass = MonomorphPass :: new ( ) ;
709+ let decls = DeclTable :: new ( vec ! [ ] ) ;
733710
734711 let generic_func = mk_simple_func ( "id" , vec ! [ "T" ] ) ;
735712
@@ -745,6 +722,7 @@ mod tests {
745722 Name :: str ( "id" ) ,
746723 vec ! [ ty] ,
747724 & generic_func,
725+ & decls,
748726 ) . unwrap ( ) ;
749727 }
750728
@@ -792,6 +770,7 @@ mod tests {
792770 #[ test]
793771 fn test_instantiate_function_with_constraints ( ) {
794772 let mut pass = MonomorphPass :: new ( ) ;
773+ let decls = DeclTable :: new ( vec ! [ ] ) ;
795774
796775 // Create a generic function with interface constraints
797776 let mut generic_func = mk_simple_func ( "add" , vec ! [ "T" ] ) ;
@@ -804,6 +783,7 @@ mod tests {
804783 Name :: str ( "add" ) ,
805784 vec ! [ mk_type( Type :: Int32 ) ] ,
806785 & generic_func,
786+ & decls,
807787 ) ;
808788
809789 assert ! ( result. is_ok( ) ) ;
@@ -836,6 +816,7 @@ mod tests {
836816 #[ test]
837817 fn test_instantiation_deduplication ( ) {
838818 let mut pass = MonomorphPass :: new ( ) ;
819+ let decls = DeclTable :: new ( vec ! [ ] ) ;
839820
840821 let generic_func = mk_simple_func ( "id" , vec ! [ "T" ] ) ;
841822 let type_args = vec ! [ mk_type( Type :: Int32 ) ] ;
@@ -846,6 +827,7 @@ mod tests {
846827 Name :: str ( "id" ) ,
847828 type_args. clone ( ) ,
848829 & generic_func,
830+ & decls,
849831 ) . unwrap ( ) ;
850832
851833 assert_eq ! ( pass. specialized_decls. len( ) , 1 ) ;
@@ -855,6 +837,7 @@ mod tests {
855837 Name :: str ( "id" ) ,
856838 type_args. clone ( ) ,
857839 & generic_func,
840+ & decls,
858841 ) . unwrap ( ) ;
859842
860843 assert_eq ! ( pass. specialized_decls. len( ) , 1 ) ;
@@ -920,9 +903,6 @@ mod tests {
920903
921904 // Should have 1 decl (just main, no specializations)
922905 assert_eq ! ( all_decls. len( ) , 1 ) ;
923-
924- // The entry point should have been processed
925- assert ! ( pass. processed. contains( & Name :: str ( "main" ) ) ) ;
926906 }
927907
928908 #[ test]
@@ -1002,14 +982,8 @@ mod tests {
1002982 assert_eq ! ( * fdecl. ret, Type :: Int32 ) ;
1003983 // Name should start with "id$"
1004984 assert ! ( fdecl. name. to_string( ) . starts_with( "id$" ) ) ;
1005-
1006- // The specialized id function should be in the processed set
1007- assert ! ( pass. processed. contains( & fdecl. name) ) ;
1008985 } else {
1009986 panic ! ( "Expected function declaration" ) ;
1010987 }
1011-
1012- // Both main and the specialized id function should be processed
1013- assert ! ( pass. processed. contains( & Name :: str ( "main" ) ) ) ;
1014988 }
1015989}
0 commit comments