11use crate :: inference:: { type_ann_to_type, InferenceContext } ;
22use crate :: parser:: {
3- BinaryOp , Block , ExportKind , Expr , ExprKind , ImportSpecifier , Literal , Param , Program , Stmt ,
4- StmtKind , TypeAnn , UnaryOp ,
3+ BinaryOp , Block , ExportKind , Expr , ExprKind , GenericParams , ImportSpecifier , Literal , Param ,
4+ Program , Stmt , StmtKind , TraitBound , TypeAnn , UnaryOp ,
55} ;
66use crate :: source:: Span ;
77use crate :: types:: Type ;
@@ -24,6 +24,8 @@ struct AnalysisContext {
2424 _in_const_function : bool ,
2525 /// Whether we're currently in an async function
2626 in_async_function : bool ,
27+ /// Generic parameters in the current scope (maps name to bounds)
28+ generic_params : HashMap < String , Vec < TraitBound > > ,
2729}
2830
2931impl AnalysisContext {
@@ -33,6 +35,7 @@ impl AnalysisContext {
3335 in_loop : false ,
3436 _in_const_function : false ,
3537 in_async_function : false ,
38+ generic_params : HashMap :: new ( ) ,
3639 }
3740 }
3841}
@@ -193,6 +196,7 @@ impl SemanticAnalyzer {
193196 return_type : Type :: Unknown , // void
194197 is_const : false ,
195198 is_async : false ,
199+ generic_params : vec ! [ ] ,
196200 } ;
197201 self . symbol_table
198202 . define_function (
@@ -214,6 +218,7 @@ impl SemanticAnalyzer {
214218 return_type : Type :: I32 ,
215219 is_const : true ,
216220 is_async : false ,
221+ generic_params : vec ! [ ] ,
217222 } ;
218223 self . symbol_table
219224 . define_function (
@@ -257,10 +262,11 @@ impl SemanticAnalyzer {
257262 ret_type,
258263 body,
259264 is_async,
260- generic_params : _ ,
265+ generic_params,
261266 } => {
262267 self . analyze_function_with_attributes (
263268 name,
269+ generic_params. as_ref ( ) ,
264270 params,
265271 ret_type. as_ref ( ) ,
266272 body,
@@ -394,6 +400,7 @@ impl SemanticAnalyzer {
394400 fn analyze_function (
395401 & mut self ,
396402 name : & str ,
403+ generic_params : Option < & GenericParams > ,
397404 params : & [ Param ] ,
398405 ret_type : Option < & TypeAnn > ,
399406 body : & Block ,
@@ -422,6 +429,7 @@ impl SemanticAnalyzer {
422429 return_type : return_type. clone ( ) ,
423430 is_const : false , // Legacy method - const handled in new method
424431 is_async,
432+ generic_params : vec ! [ ] , // TODO: Implement generic parameter conversion
425433 } ;
426434
427435 // Define the function
@@ -445,14 +453,25 @@ impl SemanticAnalyzer {
445453 self . symbol_table . enter_scope ( ) ;
446454 self . inference_ctx . push_scope ( ) ;
447455
448- // Push function context
456+ // Push function context with generic parameters
449457 // For async functions, we need to check returns against the unwrapped type
450- let func_context = AnalysisContext {
458+ let mut func_context = AnalysisContext {
451459 current_function_return : Some ( base_return_type) ,
452460 in_loop : false ,
453461 _in_const_function : false , // TODO: Support @const
454462 in_async_function : is_async,
463+ generic_params : HashMap :: new ( ) ,
455464 } ;
465+
466+ // Extract generic parameters if present
467+ if let Some ( generics) = generic_params {
468+ for param in & generics. params {
469+ func_context
470+ . generic_params
471+ . insert ( param. name . clone ( ) , param. bounds . clone ( ) ) ;
472+ }
473+ }
474+
456475 self . push_context ( func_context) ;
457476
458477 // Define parameters
@@ -493,6 +512,7 @@ impl SemanticAnalyzer {
493512 fn analyze_function_with_attributes (
494513 & mut self ,
495514 name : & str ,
515+ generic_params : Option < & GenericParams > ,
496516 params : & [ Param ] ,
497517 ret_type : Option < & TypeAnn > ,
498518 body : & Block ,
@@ -527,6 +547,7 @@ impl SemanticAnalyzer {
527547 return_type : return_type. clone ( ) ,
528548 is_const,
529549 is_async,
550+ generic_params : vec ! [ ] , // TODO: Implement generic parameter conversion
530551 } ;
531552
532553 // Define the function
@@ -550,13 +571,24 @@ impl SemanticAnalyzer {
550571 self . symbol_table . enter_scope ( ) ;
551572 self . inference_ctx . push_scope ( ) ;
552573
553- // Push function context with const flag
554- let func_context = AnalysisContext {
574+ // Push function context with const flag and generic parameters
575+ let mut func_context = AnalysisContext {
555576 current_function_return : Some ( base_return_type) ,
556577 in_loop : false ,
557578 _in_const_function : is_const,
558579 in_async_function : is_async,
580+ generic_params : HashMap :: new ( ) ,
559581 } ;
582+
583+ // Extract generic parameters if present
584+ if let Some ( generics) = generic_params {
585+ for param in & generics. params {
586+ func_context
587+ . generic_params
588+ . insert ( param. name . clone ( ) , param. bounds . clone ( ) ) ;
589+ }
590+ }
591+
560592 self . push_context ( func_context) ;
561593
562594 // Define parameters
@@ -787,7 +819,15 @@ impl SemanticAnalyzer {
787819 is_async,
788820 } => {
789821 // Analyze the function first
790- self . analyze_function ( name, params, ret_type. as_ref ( ) , body, * is_async, span) ?;
822+ self . analyze_function (
823+ name,
824+ None ,
825+ params,
826+ ret_type. as_ref ( ) ,
827+ body,
828+ * is_async,
829+ span,
830+ ) ?;
791831
792832 // Then mark it as exported
793833 if let Err ( err) = self . symbol_table . process_export ( kind, span) {
@@ -915,6 +955,13 @@ impl SemanticAnalyzer {
915955
916956 /// Analyze an identifier
917957 fn analyze_identifier ( & mut self , name : & str , span : crate :: source:: Span ) -> Result < Type > {
958+ // First check if it's a type parameter in the current generic context
959+ let ctx = self . current_context ( ) ;
960+ if ctx. generic_params . contains_key ( name) {
961+ // This is a type parameter reference
962+ return Ok ( Type :: TypeParam ( name. to_string ( ) ) ) ;
963+ }
964+
918965 // Use module-aware lookup
919966 if let Some ( symbol) = self . symbol_table . lookup_with_modules ( name) {
920967 let symbol_id = symbol. id ;
0 commit comments