Coverage Report

Created: 2025-09-05 15:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/home/noah/src/ruchy/src/middleend/infer.rs
Line
Count
Source
1
//! Type inference engine using Algorithm W
2
3
use crate::frontend::ast::{BinaryOp, Expr, ExprKind, Literal, Param, Pattern, TypeKind, UnaryOp};
4
use crate::middleend::environment::TypeEnv;
5
use crate::middleend::types::{MonoType, TyVar, TyVarGenerator, TypeScheme};
6
use crate::middleend::unify::Unifier;
7
use anyhow::{bail, Result};
8
9
/// Type inference context with enhanced constraint solving
10
pub struct InferenceContext {
11
    /// Type variable generator
12
    gen: TyVarGenerator,
13
    /// Unification engine
14
    unifier: Unifier,
15
    /// Type environment
16
    env: TypeEnv,
17
    /// Deferred constraints for later resolution
18
    constraints: Vec<(TyVar, TyVar)>,
19
    /// Enhanced constraint queue for complex type relationships
20
    type_constraints: Vec<TypeConstraint>,
21
    /// Recursion depth tracker for safety
22
    recursion_depth: usize,
23
}
24
25
/// Enhanced constraint types for self-hosting compiler patterns
26
#[derive(Debug, Clone)]
27
pub enum TypeConstraint {
28
    /// Two types must unify
29
    Unify(MonoType, MonoType),
30
    /// Type must be a function with specific arity
31
    FunctionArity(MonoType, usize),
32
    /// Type must support method call
33
    MethodCall(MonoType, String, Vec<MonoType>),
34
    /// Type must be iterable
35
    Iterable(MonoType, MonoType),
36
}
37
38
impl InferenceContext {
39
    #[must_use]
40
40
    pub fn new() -> Self {
41
40
        InferenceContext {
42
40
            gen: TyVarGenerator::new(),
43
40
            unifier: Unifier::new(),
44
40
            env: TypeEnv::standard(),
45
40
            constraints: Vec::new(),
46
40
            type_constraints: Vec::new(),
47
40
            recursion_depth: 0,
48
40
        }
49
40
    }
50
51
    #[must_use]
52
0
    pub fn with_env(env: TypeEnv) -> Self {
53
0
        InferenceContext {
54
0
            gen: TyVarGenerator::new(),
55
0
            unifier: Unifier::new(),
56
0
            env,
57
0
            constraints: Vec::new(),
58
0
            type_constraints: Vec::new(),
59
0
            recursion_depth: 0,
60
0
        }
61
0
    }
62
63
    /// Infer the type of an expression with enhanced constraint solving
64
    ///
65
    /// # Errors
66
    ///
67
    /// Returns an error if type inference fails (type error, undefined variable, etc.)
68
40
    pub fn infer(&mut self, expr: &Expr) -> Result<MonoType> {
69
        // Check recursion depth to prevent infinite loops
70
40
        if self.recursion_depth > 100 {
71
0
            bail!("Type inference recursion limit exceeded");
72
40
        }
73
        
74
40
        self.recursion_depth += 1;
75
40
        let result = self.infer_expr(expr);
76
40
        self.recursion_depth -= 1;
77
        
78
40
        let 
inferred_type37
= result
?3
;
79
        
80
        // Solve all accumulated constraints
81
37
        self.solve_all_constraints()
?0
;
82
        
83
        // Apply final substitutions
84
37
        Ok(self.unifier.apply(&inferred_type))
85
40
    }
86
87
    /// Solve all accumulated constraints (enhanced for self-hosting)
88
37
    fn solve_all_constraints(&mut self) -> Result<()> {
89
        // First solve simple variable constraints
90
37
        self.solve_constraints();
91
        
92
        // Then solve complex type constraints
93
43
        while let Some(
constraint6
) = self.type_constraints.pop() {
94
6
            self.solve_type_constraint(constraint)
?0
;
95
        }
96
        
97
37
        Ok(())
98
37
    }
99
    
100
    /// Solve deferred constraints
101
37
    fn solve_constraints(&mut self) {
102
37
        while let Some((
a0
,
b0
)) = self.constraints.pop() {
103
0
            // Convert TyVar to MonoType for unification
104
0
            let ty_a = MonoType::Var(a);
105
0
            let ty_b = MonoType::Var(b);
106
0
            // Ignore failures for now - this is a simplified implementation
107
0
            let _ = self.unifier.unify(&ty_a, &ty_b);
108
0
        }
109
37
    }
110
    
111
    /// Solve complex type constraints for advanced patterns
112
6
    fn solve_type_constraint(&mut self, constraint: TypeConstraint) -> Result<()> {
113
6
        match constraint {
114
0
            TypeConstraint::Unify(t1, t2) => {
115
0
                self.unifier.unify(&t1, &t2)?;
116
            }
117
0
            TypeConstraint::FunctionArity(func_ty, expected_arity) => {
118
                // Verify function has correct number of parameters
119
0
                let mut current_ty = &func_ty;
120
0
                let mut arity = 0;
121
                
122
0
                while let MonoType::Function(_, ret) = current_ty {
123
0
                    arity += 1;
124
0
                    current_ty = ret;
125
0
                }
126
                
127
0
                if arity != expected_arity {
128
0
                    bail!(
129
0
                        "Function arity mismatch: expected {}, found {}",
130
                        expected_arity,
131
                        arity
132
                    );
133
0
                }
134
            }
135
6
            TypeConstraint::MethodCall(receiver_ty, method_name, arg_types) => {
136
                // Verify receiver type supports the method call
137
6
                self.check_method_call_constraint(&receiver_ty, &method_name, &arg_types)
?0
;
138
            }
139
0
            TypeConstraint::Iterable(collection_ty, element_ty) => {
140
                // Ensure collection_ty is a valid iterable containing element_ty
141
0
                match collection_ty {
142
0
                    MonoType::List(inner) => {
143
0
                        self.unifier.unify(&inner, &element_ty)?;
144
                    }
145
                    MonoType::String => {
146
                        // String iterates over characters
147
0
                        self.unifier.unify(&element_ty, &MonoType::Char)?;
148
                    }
149
0
                    _ => bail!("Type {} is not iterable", collection_ty),
150
                }
151
            }
152
        }
153
6
        Ok(())
154
6
    }
155
    
156
    /// Check method call constraints for compiler patterns
157
6
    fn check_method_call_constraint(
158
6
        &mut self,
159
6
        receiver_ty: &MonoType,
160
6
        method_name: &str,
161
6
        _arg_types: &[MonoType],
162
6
    ) -> Result<()> {
163
6
        match (method_name, receiver_ty) {
164
            // List methods
165
2
            ("map" | "filter" | "reduce", MonoType::List(_)) => 
Ok(())0
,
166
6
            ("len" | 
"length"4
, MonoType::List(_) | MonoType::String) =>
Ok(())2
,
167
4
            ("push", MonoType::List(_)) => 
Ok(())0
,
168
            
169
            // DataFrame methods
170
3
            ("filter" | 
"groupby"2
|
"agg"2
|
"select"2
|
"col"2
, MonoType::DataFrame(_)) => Ok(()),
171
0
            ("filter" | "groupby" | "agg" | "select" | "col", MonoType::Named(name))
172
0
                if name == "DataFrame" => Ok(()),
173
            
174
            // Series methods
175
1
            ("mean" | 
"std"0
|
"sum"0
|
"count"0
, MonoType::Series(_) | MonoType::DataFrame(_)) => Ok(()),
176
0
            ("mean" | "std" | "sum" | "count", MonoType::Named(name))
177
0
                if name == "Series" || name == "DataFrame" => Ok(()),
178
            
179
            // HashMap methods (for compiler symbol tables)
180
0
            ("insert" | "get" | "contains_key", MonoType::Named(name)) 
181
0
                if name.starts_with("HashMap") => Ok(()),
182
                
183
            // String methods
184
0
            ("chars" | "trim" | "to_upper" | "to_lower", MonoType::String) => Ok(()),
185
            
186
            // For testing purposes, be more permissive with unknown methods
187
            _ => {
188
                // In a production implementation, this would be stricter
189
                // For self-hosting development, we allow more flexibility
190
0
                Ok(())
191
            }
192
        }
193
6
    }
194
195
    /// Core type inference dispatcher with complexity <10
196
    /// 
197
    /// Delegates to specialized handlers for each expression category
198
    /// 
199
    /// # Example Usage
200
    /// This method infers types for expressions by delegating to specialized handlers.
201
    /// For example, literals get their type directly, while function calls check argument types.
202
189
    fn infer_expr(&mut self, expr: &Expr) -> Result<MonoType> {
203
189
        match &expr.kind {
204
            // Literals and identifiers
205
77
            ExprKind::Literal(lit) => Ok(Self::infer_literal(lit)),
206
29
            ExprKind::Identifier(name) => self.infer_identifier(name),
207
0
            ExprKind::QualifiedName { module: _, name } => self.infer_identifier(name),
208
            
209
            // Control flow and pattern matching  
210
            ExprKind::If { condition: _, then_branch: _, else_branch: _ } => {
211
4
                self.infer_control_flow_expr(expr)
212
            }
213
0
            ExprKind::Match { expr, arms } => self.infer_match(expr, arms),
214
            ExprKind::IfLet { .. } | ExprKind::WhileLet { .. } => {
215
0
                self.infer_control_flow_expr(expr)
216
            }
217
            
218
            // Functions and lambdas
219
            ExprKind::Function { .. } | ExprKind::Lambda { .. } => {
220
13
                self.infer_function_expr(expr)
221
            }
222
            
223
            // Collections and data structures
224
            ExprKind::List(..) | ExprKind::Tuple(..) | ExprKind::ListComprehension { .. } => {
225
7
                self.infer_collection_expr(expr)
226
            }
227
            
228
            // Operations and method calls
229
            ExprKind::Binary { .. } | ExprKind::Unary { .. } | ExprKind::Call { .. } | ExprKind::MethodCall { .. } => {
230
32
                self.infer_operation_expr(expr)
231
            }
232
            
233
            // All other expressions
234
27
            _ => self.infer_other_expr(expr),
235
        }
236
189
    }
237
238
77
    fn infer_literal(lit: &Literal) -> MonoType {
239
77
        match lit {
240
55
            Literal::Integer(_) => MonoType::Int,
241
3
            Literal::Float(_) => MonoType::Float,
242
10
            Literal::String(_) => MonoType::String,
243
9
            Literal::Bool(_) => MonoType::Bool,
244
0
            Literal::Char(_) => MonoType::Char,
245
0
            Literal::Unit => MonoType::Unit,
246
        }
247
77
    }
248
249
29
    fn infer_identifier(&mut self, name: &str) -> Result<MonoType> {
250
29
        match self.env.lookup(name) {
251
29
            Some(scheme) => Ok(self.env.instantiate(scheme, &mut self.gen)),
252
0
            None => bail!("Undefined variable: {}", name),
253
        }
254
29
    }
255
256
19
    fn infer_binary(&mut self, left: &Expr, op: BinaryOp, right: &Expr) -> Result<MonoType> {
257
19
        let left_ty = self.infer_expr(left)
?0
;
258
19
        let right_ty = self.infer_expr(right)
?0
;
259
260
19
        match op {
261
            // Arithmetic operators
262
            BinaryOp::Add
263
            | BinaryOp::Subtract
264
            | BinaryOp::Multiply
265
            | BinaryOp::Divide
266
            | BinaryOp::Modulo => {
267
                // Both operands must be numeric and same type
268
14
                self.unifier.unify(&left_ty, &right_ty)
?1
;
269
                // For now, assume Int (could be Float too)
270
13
                self.unifier.unify(&left_ty, &MonoType::Int)
?0
;
271
13
                Ok(MonoType::Int)
272
            }
273
            BinaryOp::Power => {
274
0
                self.unifier.unify(&left_ty, &MonoType::Int)?;
275
0
                self.unifier.unify(&right_ty, &MonoType::Int)?;
276
0
                Ok(MonoType::Int)
277
            }
278
            // Comparison operators
279
            BinaryOp::Equal
280
            | BinaryOp::NotEqual
281
            | BinaryOp::Less
282
            | BinaryOp::LessEqual
283
            | BinaryOp::Greater
284
            | BinaryOp::GreaterEqual => {
285
                // Operands must have same type
286
5
                self.unifier.unify(&left_ty, &right_ty)
?0
;
287
5
                Ok(MonoType::Bool)
288
            }
289
            // Boolean operators
290
            BinaryOp::And | BinaryOp::Or => {
291
0
                self.unifier.unify(&left_ty, &MonoType::Bool)?;
292
0
                self.unifier.unify(&right_ty, &MonoType::Bool)?;
293
0
                Ok(MonoType::Bool)
294
            }
295
            // Null coalescing operator: return type is union of operand types
296
            BinaryOp::NullCoalesce => {
297
                // Type is the union of left and right, but return the more specific non-null type
298
0
                Ok(right_ty) // For now, assume right type (could be improved with union types)
299
            }
300
            // Bitwise operators
301
            BinaryOp::BitwiseAnd
302
            | BinaryOp::BitwiseOr
303
            | BinaryOp::BitwiseXor
304
            | BinaryOp::LeftShift => {
305
0
                self.unifier.unify(&left_ty, &MonoType::Int)?;
306
0
                self.unifier.unify(&right_ty, &MonoType::Int)?;
307
0
                Ok(MonoType::Int)
308
            }
309
        }
310
19
    }
311
312
0
    fn infer_unary(&mut self, op: UnaryOp, operand: &Expr) -> Result<MonoType> {
313
0
        let operand_ty = self.infer_expr(operand)?;
314
315
0
        match op {
316
            UnaryOp::Not => {
317
0
                self.unifier.unify(&operand_ty, &MonoType::Bool)?;
318
0
                Ok(MonoType::Bool)
319
            }
320
            UnaryOp::Negate => {
321
                // Can negate Int or Float
322
0
                self.unifier.unify(&operand_ty, &MonoType::Int)?;
323
0
                Ok(MonoType::Int)
324
            }
325
            UnaryOp::BitwiseNot => {
326
0
                self.unifier.unify(&operand_ty, &MonoType::Int)?;
327
0
                Ok(MonoType::Int)
328
            }
329
            UnaryOp::Reference => {
330
                // Reference operator &x: T -> &T
331
0
                Ok(MonoType::Reference(Box::new(operand_ty)))
332
            }
333
        }
334
0
    }
335
336
337
0
    fn infer_throw(&mut self, expr: &Expr) -> Result<MonoType> {
338
        // Infer the type of the expression being thrown
339
0
        let _expr_ty = self.infer_expr(expr)?;
340
341
        // The expression must implement Error trait
342
        // For now, we'll just ensure it's a valid type
343
        // In a more complete implementation, we'd check Error trait bounds
344
345
        // The throw expression itself has the Never type (!)
346
        // But we'll represent it as a generic type for now
347
0
        Ok(MonoType::Var(self.gen.fresh()))
348
0
    }
349
350
0
    fn infer_await(&mut self, expr: &Expr) -> Result<MonoType> {
351
        // The expression must be a Future<Output = T>
352
0
        let expr_ty = self.infer_expr(expr)?;
353
354
        // For now, we'll just return the inner type
355
        // In a full implementation, we'd check for Future trait
356
0
        if let MonoType::Named(name) = &expr_ty {
357
0
            if name.starts_with("Future") {
358
                // Extract the output type
359
0
                return Ok(MonoType::Var(self.gen.fresh()));
360
0
            }
361
0
        }
362
363
        // For now, just return a fresh type variable
364
0
        Ok(MonoType::Var(self.gen.fresh()))
365
0
    }
366
367
4
    fn infer_if(
368
4
        &mut self,
369
4
        condition: &Expr,
370
4
        then_branch: &Expr,
371
4
        else_branch: Option<&Expr>,
372
4
    ) -> Result<MonoType> {
373
        // Condition must be Bool
374
4
        let cond_ty = self.infer_expr(condition)
?0
;
375
4
        self.unifier.unify(&cond_ty, &MonoType::Bool)
?1
;
376
377
3
        let then_ty = self.infer_expr(then_branch)
?0
;
378
379
3
        if let Some(else_expr) = else_branch {
380
3
            let else_ty = self.infer_expr(else_expr)
?0
;
381
            // Both branches must have same type
382
3
            self.unifier.unify(&then_ty, &else_ty)
?0
;
383
3
            Ok(self.unifier.apply(&then_ty))
384
        } else {
385
            // No else branch means Unit type
386
0
            self.unifier.unify(&then_ty, &MonoType::Unit)?;
387
0
            Ok(MonoType::Unit)
388
        }
389
4
    }
390
391
11
    fn infer_let(
392
11
        &mut self,
393
11
        name: &str,
394
11
        value: &Expr,
395
11
        body: &Expr,
396
11
        _is_mutable: bool,
397
11
    ) -> Result<MonoType> {
398
        // Infer type of value
399
11
        let value_ty = self.infer_expr(value)
?0
;
400
401
        // Generalize the value type
402
11
        let scheme = self.env.generalize(value_ty);
403
404
        // Extend environment and infer body
405
11
        let old_env = self.env.clone();
406
11
        self.env = self.env.extend(name, scheme);
407
11
        let body_ty = self.infer_expr(body)
?0
;
408
11
        self.env = old_env;
409
410
11
        Ok(body_ty)
411
11
    }
412
413
2
    fn infer_function(
414
2
        &mut self,
415
2
        name: &str,
416
2
        params: &[Param],
417
2
        body: &Expr,
418
2
        _return_type: Option<&crate::frontend::ast::Type>,
419
2
        _is_async: bool,
420
2
    ) -> Result<MonoType> {
421
        // Create fresh type variables for parameters
422
2
        let mut param_types = Vec::new();
423
2
        let old_env = self.env.clone();
424
425
5
        for 
param3
in params {
426
3
            let param_ty =
427
3
                if param.ty.kind == crate::frontend::ast::TypeKind::Named("Any".to_string()) {
428
                    // Untyped parameter - create fresh type variable
429
0
                    MonoType::Var(self.gen.fresh())
430
                } else {
431
                    // Convert AST type to MonoType
432
3
                    Self::ast_type_to_mono_static(&param.ty)
?0
433
                };
434
3
            param_types.push(param_ty.clone());
435
3
            self.env = self.env.extend(param.name(), TypeScheme::mono(param_ty));
436
        }
437
438
        // Add function itself to environment for recursion
439
2
        let result_var = MonoType::Var(self.gen.fresh());
440
2
        let func_type = param_types
441
2
            .iter()
442
2
            .rev()
443
3
            .
fold2
(
result_var2
.
clone2
(), |acc, param_ty| {
444
3
                MonoType::Function(Box::new(param_ty.clone()), Box::new(acc))
445
3
            });
446
2
        self.env = self.env.extend(name, TypeScheme::mono(func_type.clone()));
447
448
        // Infer body type
449
2
        let body_ty = self.infer_expr(body)
?0
;
450
2
        self.unifier.unify(&result_var, &body_ty)
?0
;
451
452
2
        self.env = old_env;
453
454
2
        let final_type = self.unifier.apply(&func_type);
455
456
        // Always return the function type for type inference
457
        // The distinction between statements and expressions should be handled at a higher level
458
2
        Ok(final_type)
459
2
    }
460
461
11
    fn infer_lambda(&mut self, params: &[Param], body: &Expr) -> Result<MonoType> {
462
11
        let old_env = self.env.clone();
463
464
        // Create type variables for parameters
465
11
        let mut param_types = Vec::new();
466
25
        for 
param14
in params {
467
14
            let param_ty = match &param.ty.kind {
468
14
                TypeKind::Named(name) if name == "Any" || name == "_" => {
469
                    // Untyped parameter - create fresh type variable
470
14
                    MonoType::Var(self.gen.fresh())
471
                }
472
                _ => {
473
                    // Convert AST type to MonoType
474
0
                    Self::ast_type_to_mono_static(&param.ty)?
475
                }
476
            };
477
14
            param_types.push(param_ty.clone());
478
14
            self.env = self.env.extend(param.name(), TypeScheme::mono(param_ty));
479
        }
480
481
        // Infer body type
482
11
        let body_ty = self.infer_expr(body)
?0
;
483
484
        // Restore environment
485
11
        self.env = old_env;
486
487
        // Build function type from parameters and body
488
14
        let 
lambda_type11
=
param_types.iter()11
.
rev11
().
fold11
(
body_ty11
, |acc, param_ty| {
489
14
            MonoType::Function(Box::new(param_ty.clone()), Box::new(acc))
490
14
        });
491
492
11
        Ok(self.unifier.apply(&lambda_type))
493
11
    }
494
495
7
    fn infer_call(&mut self, func: &Expr, args: &[Expr]) -> Result<MonoType> {
496
7
        let func_ty = self.infer_expr(func)
?0
;
497
498
        // Create type for the function we expect
499
7
        let result_ty = MonoType::Var(self.gen.fresh());
500
7
        let mut expected_func_ty = result_ty.clone();
501
502
8
        for arg in 
args7
.
iter7
().
rev7
() {
503
8
            let arg_ty = self.infer_expr(arg)
?0
;
504
8
            expected_func_ty = MonoType::Function(Box::new(arg_ty), Box::new(expected_func_ty));
505
        }
506
507
        // Unify with actual function type
508
7
        self.unifier.unify(&func_ty, &expected_func_ty)
?0
;
509
510
7
        Ok(self.unifier.apply(&result_ty))
511
7
    }
512
513
0
    fn infer_macro(&mut self, name: &str, args: &[Expr]) -> Result<MonoType> {
514
        // Type check the arguments first
515
0
        for arg in args {
516
0
            self.infer_expr(arg)?;
517
        }
518
519
        // Determine the return type based on the macro name
520
0
        match name {
521
0
            "println" => Ok(MonoType::Unit), // println! returns unit
522
0
            "vec" => {
523
                // vec! returns a vector of the element type
524
0
                if args.is_empty() {
525
                    // Empty vec! needs type annotation or we use a generic type
526
0
                    Ok(MonoType::List(Box::new(MonoType::Var(self.gen.fresh()))))
527
                } else {
528
                    // Infer element type from first argument
529
0
                    let elem_ty = self.infer_expr(&args[0])?;
530
0
                    Ok(MonoType::List(Box::new(elem_ty)))
531
                }
532
            }
533
0
            _ => bail!("Unknown macro: {}", name),
534
        }
535
0
    }
536
537
    /// REFACTORED FOR COMPLEXITY REDUCTION
538
    /// Original: 41 cyclomatic complexity, Target: <20
539
    /// Strategy: Extract method-category specific handlers
540
6
    pub fn infer_method_call(
541
6
        &mut self,
542
6
        receiver: &Expr,
543
6
        method: &str,
544
6
        args: &[Expr],
545
6
    ) -> Result<MonoType> {
546
6
        let receiver_ty = self.infer_expr(receiver)
?0
;
547
6
        self.add_method_constraint(&receiver_ty, method, args)
?0
;
548
        
549
        // Dispatch based on receiver type category (complexity: delegated)
550
0
        match &receiver_ty {
551
2
            MonoType::List(_) => self.infer_list_method(&receiver_ty, method, args),
552
0
            MonoType::String => self.infer_string_method(&receiver_ty, method, args),
553
            MonoType::DataFrame(_) | MonoType::Series(_) => {
554
4
                self.infer_dataframe_method(&receiver_ty, method, args)
555
            }
556
0
            MonoType::Named(name) if name == "DataFrame" || name == "Series" => {
557
0
                self.infer_dataframe_method(&receiver_ty, method, args)
558
            }
559
0
            _ => self.infer_generic_method(&receiver_ty, method, args),
560
        }
561
6
    }
562
    
563
    /// Extract method constraint addition (complexity ~3)
564
6
    fn add_method_constraint(
565
6
        &mut self, 
566
6
        receiver_ty: &MonoType, 
567
6
        method: &str, 
568
6
        args: &[Expr]
569
6
    ) -> Result<()> {
570
6
        let arg_types: Result<Vec<_>> = args.iter().map(|arg| 
self3
.
infer_expr3
(
arg3
)).collect();
571
6
        let arg_types = arg_types
?0
;
572
        
573
6
        self.type_constraints.push(TypeConstraint::MethodCall(
574
6
            receiver_ty.clone(),
575
6
            method.to_string(),
576
6
            arg_types,
577
6
        ));
578
6
        Ok(())
579
6
    }
580
    
581
    /// Extract list method handling (complexity ~10)
582
2
    fn infer_list_method(
583
2
        &mut self, 
584
2
        receiver_ty: &MonoType, 
585
2
        method: &str, 
586
2
        args: &[Expr]
587
2
    ) -> Result<MonoType> {
588
2
        if let MonoType::List(elem_ty) = receiver_ty {
589
2
            match method {
590
2
                "len" | 
"length"0
=> {
591
2
                    self.validate_no_args(method, args)
?0
;
592
2
                    Ok(MonoType::Int)
593
                }
594
0
                "push" => {
595
0
                    self.validate_single_arg(method, args)?;
596
0
                    let arg_ty = self.infer_expr(&args[0])?;
597
0
                    self.unifier.unify(&arg_ty, elem_ty)?;
598
0
                    Ok(MonoType::Unit)
599
                }
600
0
                "pop" => {
601
0
                    self.validate_no_args(method, args)?;
602
0
                    Ok(MonoType::Optional(elem_ty.clone()))
603
                }
604
0
                "sorted" | "reversed" | "unique" => {
605
0
                    self.validate_no_args(method, args)?;
606
0
                    Ok(MonoType::List(elem_ty.clone()))
607
                }
608
0
                "sum" => {
609
0
                    self.validate_no_args(method, args)?;
610
0
                    Ok(*elem_ty.clone())
611
                }
612
0
                "min" | "max" => {
613
0
                    self.validate_no_args(method, args)?;
614
0
                    Ok(MonoType::Optional(elem_ty.clone()))
615
                }
616
0
                _ => self.infer_generic_method(receiver_ty, method, args),
617
            }
618
        } else {
619
0
            self.infer_generic_method(receiver_ty, method, args)
620
        }
621
2
    }
622
    
623
    /// Extract string method handling (complexity ~5)
624
0
    fn infer_string_method(
625
0
        &mut self, 
626
0
        receiver_ty: &MonoType, 
627
0
        method: &str, 
628
0
        args: &[Expr]
629
0
    ) -> Result<MonoType> {
630
0
        match method {
631
0
            "len" | "length" => {
632
0
                self.validate_no_args(method, args)?;
633
0
                Ok(MonoType::Int)
634
            }
635
0
            "chars" => {
636
0
                self.validate_no_args(method, args)?;
637
0
                Ok(MonoType::List(Box::new(MonoType::String)))
638
            }
639
0
            _ => self.infer_generic_method(receiver_ty, method, args),
640
        }
641
0
    }
642
    
643
    /// Extract dataframe method handling (complexity ~8)
644
4
    fn infer_dataframe_method(
645
4
        &mut self, 
646
4
        receiver_ty: &MonoType, 
647
4
        method: &str, 
648
4
        args: &[Expr]
649
4
    ) -> Result<MonoType> {
650
4
        match method {
651
4
            "filter" | 
"groupby"3
|
"agg"3
|
"select"3
=> {
652
0
                match receiver_ty {
653
1
                    MonoType::DataFrame(columns) => Ok(MonoType::DataFrame(columns.clone())),
654
0
                    MonoType::Named(name) if name == "DataFrame" => {
655
0
                        Ok(MonoType::Named("DataFrame".to_string()))
656
                    }
657
0
                    _ => Ok(MonoType::Named("DataFrame".to_string())),
658
                }
659
            }
660
3
            "mean" | 
"std"2
|
"sum"2
|
"count"2
=>
Ok(MonoType::Float)1
,
661
2
            "col" => self.infer_column_selection(receiver_ty, args),
662
0
            _ => self.infer_generic_method(receiver_ty, method, args),
663
        }
664
4
    }
665
    
666
    /// Extract column selection logic (complexity ~5)
667
2
    fn infer_column_selection(
668
2
        &mut self, 
669
2
        receiver_ty: &MonoType, 
670
2
        args: &[Expr]
671
2
    ) -> Result<MonoType> {
672
2
        if let MonoType::DataFrame(columns) = receiver_ty {
673
2
            if let Some(arg) = args.first() {
674
2
                if let ExprKind::Literal(Literal::String(col_name)) = &arg.kind {
675
2
                    if let Some((_, col_type)) = columns.iter().find(|(name, _)| name == col_name) {
676
2
                        return Ok(MonoType::Series(Box::new(col_type.clone())));
677
0
                    }
678
0
                }
679
0
            }
680
0
            Ok(MonoType::Series(Box::new(MonoType::Var(self.gen.fresh()))))
681
        } else {
682
0
            Ok(MonoType::Series(Box::new(MonoType::Var(self.gen.fresh()))))
683
        }
684
2
    }
685
    
686
    /// Extract generic method handling (complexity ~8)
687
0
    fn infer_generic_method(
688
0
        &mut self, 
689
0
        receiver_ty: &MonoType, 
690
0
        method: &str, 
691
0
        args: &[Expr]
692
0
    ) -> Result<MonoType> {
693
0
        if let Some(scheme) = self.env.lookup(method) {
694
0
            let method_ty = self.env.instantiate(scheme, &mut self.gen);
695
0
            let result_ty = MonoType::Var(self.gen.fresh());
696
0
            let expected_func_ty = self.build_method_function_type(receiver_ty, args, result_ty.clone())?;
697
            
698
0
            self.unifier.unify(&method_ty, &expected_func_ty)?;
699
0
            Ok(self.unifier.apply(&result_ty))
700
        } else {
701
0
            Ok(MonoType::Var(self.gen.fresh()))
702
        }
703
0
    }
704
    
705
    /// Extract function type construction (complexity ~4)
706
0
    fn build_method_function_type(
707
0
        &mut self, 
708
0
        receiver_ty: &MonoType, 
709
0
        args: &[Expr], 
710
0
        result_ty: MonoType
711
0
    ) -> Result<MonoType> {
712
0
        let mut expected_func_ty = result_ty;
713
        
714
0
        for arg in args.iter().rev() {
715
0
            let arg_ty = self.infer_expr(arg)?;
716
0
            expected_func_ty = MonoType::Function(Box::new(arg_ty), Box::new(expected_func_ty));
717
        }
718
        
719
        // Add receiver as first argument
720
0
        expected_func_ty = MonoType::Function(Box::new(receiver_ty.clone()), Box::new(expected_func_ty));
721
0
        Ok(expected_func_ty)
722
0
    }
723
    
724
    /// Helper methods for argument validation (complexity ~3 each)
725
2
    fn validate_no_args(&self, method: &str, args: &[Expr]) -> Result<()> {
726
2
        if !args.is_empty() {
727
0
            bail!("Method {} takes no arguments", method);
728
2
        }
729
2
        Ok(())
730
2
    }
731
    
732
0
    fn validate_single_arg(&self, method: &str, args: &[Expr]) -> Result<()> {
733
0
        if args.len() != 1 {
734
0
            bail!("Method {} takes exactly one argument", method);
735
0
        }
736
0
        Ok(())
737
0
    }
738
739
8
    fn infer_block(&mut self, exprs: &[Expr]) -> Result<MonoType> {
740
8
        if exprs.is_empty() {
741
0
            return Ok(MonoType::Unit);
742
8
        }
743
744
8
        let mut last_ty = MonoType::Unit;
745
16
        for 
expr8
in exprs {
746
8
            last_ty = self.infer_expr(expr)
?0
;
747
        }
748
749
8
        Ok(last_ty)
750
8
    }
751
752
7
    fn infer_list(&mut self, elements: &[Expr]) -> Result<MonoType> {
753
7
        if elements.is_empty() {
754
            // Empty list with fresh type variable
755
0
            let elem_ty = MonoType::Var(self.gen.fresh());
756
0
            return Ok(MonoType::List(Box::new(elem_ty)));
757
7
        }
758
759
        // All elements must have same type
760
7
        let first_ty = self.infer_expr(&elements[0])
?0
;
761
12
        for elem in &
elements[1..]7
{
762
12
            let elem_ty = self.infer_expr(elem)
?0
;
763
12
            self.unifier.unify(&first_ty, &elem_ty)
?1
;
764
        }
765
766
6
        Ok(MonoType::List(Box::new(self.unifier.apply(&first_ty))))
767
7
    }
768
769
0
    fn infer_list_comprehension(
770
0
        &mut self,
771
0
        element: &Expr,
772
0
        variable: &str,
773
0
        iterable: &Expr,
774
0
        condition: Option<&Expr>,
775
0
    ) -> Result<MonoType> {
776
        // Type check the iterable - must be a list
777
0
        let iterable_ty = self.infer_expr(iterable)?;
778
0
        let elem_ty = MonoType::Var(self.gen.fresh());
779
0
        self.unifier
780
0
            .unify(&iterable_ty, &MonoType::List(Box::new(elem_ty.clone())))?;
781
782
        // Save the old environment and add the loop variable
783
0
        let old_env = self.env.clone();
784
0
        self.env = self
785
0
            .env
786
0
            .extend(variable, TypeScheme::mono(self.unifier.apply(&elem_ty)));
787
788
        // Type check the optional condition (must be bool)
789
0
        if let Some(cond) = condition {
790
0
            let cond_ty = self.infer_expr(cond)?;
791
0
            self.unifier.unify(&cond_ty, &MonoType::Bool)?;
792
0
        }
793
794
        // Type check the element expression
795
0
        let result_elem_ty = self.infer_expr(element)?;
796
797
        // Restore the environment
798
0
        self.env = old_env;
799
800
        // Return List<T> where T is the type of the element expression
801
0
        Ok(MonoType::List(Box::new(
802
0
            self.unifier.apply(&result_elem_ty),
803
0
        )))
804
0
    }
805
806
0
    fn infer_match(
807
0
        &mut self,
808
0
        expr: &Expr,
809
0
        arms: &[crate::frontend::ast::MatchArm],
810
0
    ) -> Result<MonoType> {
811
0
        let expr_ty = self.infer_expr(expr)?;
812
813
0
        if arms.is_empty() {
814
0
            bail!("Match expression must have at least one arm");
815
0
        }
816
817
        // All arms must return same type
818
0
        let result_ty = MonoType::Var(self.gen.fresh());
819
820
0
        for arm in arms {
821
            // Infer pattern and bind variables
822
0
            let old_env = self.env.clone();
823
0
            self.infer_pattern(&arm.pattern, &expr_ty)?;
824
825
            // Guards have been removed from the grammar
826
827
            // Infer body type
828
0
            let body_ty = self.infer_expr(&arm.body)?;
829
0
            self.unifier.unify(&result_ty, &body_ty)?;
830
831
0
            self.env = old_env;
832
        }
833
834
0
        Ok(self.unifier.apply(&result_ty))
835
0
    }
836
837
0
    fn infer_pattern(&mut self, pattern: &Pattern, expected_ty: &MonoType) -> Result<()> {
838
0
        match pattern {
839
0
            Pattern::Wildcard => Ok(()),
840
0
            Pattern::Literal(lit) => {
841
0
                let lit_ty = Self::infer_literal(lit);
842
0
                self.unifier.unify(expected_ty, &lit_ty)
843
            }
844
0
            Pattern::Identifier(name) => {
845
                // Bind the identifier to the expected type
846
0
                self.env = self.env.extend(name, TypeScheme::mono(expected_ty.clone()));
847
0
                Ok(())
848
            }
849
0
            Pattern::QualifiedName(_path) => {
850
                // Qualified names in patterns should match against specific enum variants
851
                // For now, assume it's valid
852
0
                Ok(())
853
            }
854
0
            Pattern::List(patterns) => {
855
0
                let elem_ty = MonoType::Var(self.gen.fresh());
856
0
                self.unifier
857
0
                    .unify(expected_ty, &MonoType::List(Box::new(elem_ty.clone())))?;
858
859
0
                for pat in patterns {
860
0
                    self.infer_pattern(pat, &elem_ty)?;
861
                }
862
0
                Ok(())
863
            }
864
0
            Pattern::Ok(inner) => {
865
                // Expected type should be Result<T, E>, extract T for inner pattern
866
0
                if let MonoType::Result(ok_ty, _) = expected_ty {
867
0
                    self.infer_pattern(inner, ok_ty)
868
                } else {
869
                    // Create a fresh Result type
870
0
                    let error_ty = MonoType::Var(self.gen.fresh());
871
0
                    let inner_ty = MonoType::Var(self.gen.fresh());
872
0
                    let result_ty =
873
0
                        MonoType::Result(Box::new(inner_ty.clone()), Box::new(error_ty));
874
0
                    self.unifier.unify(expected_ty, &result_ty)?;
875
0
                    self.infer_pattern(inner, &inner_ty)
876
                }
877
            }
878
0
            Pattern::Err(inner) => {
879
                // Expected type should be Result<T, E>, extract E for inner pattern
880
0
                if let MonoType::Result(_, err_ty) = expected_ty {
881
0
                    self.infer_pattern(inner, err_ty)
882
                } else {
883
                    // Create a fresh Result type
884
0
                    let ok_ty = MonoType::Var(self.gen.fresh());
885
0
                    let inner_ty = MonoType::Var(self.gen.fresh());
886
0
                    let result_ty = MonoType::Result(Box::new(ok_ty), Box::new(inner_ty.clone()));
887
0
                    self.unifier.unify(expected_ty, &result_ty)?;
888
0
                    self.infer_pattern(inner, &inner_ty)
889
                }
890
            }
891
0
            Pattern::Some(inner) => {
892
                // Expected type should be Option<T>, extract T for inner pattern
893
0
                if let MonoType::Optional(inner_ty) = expected_ty {
894
0
                    self.infer_pattern(inner, inner_ty)
895
                } else {
896
                    // Create a fresh Option type
897
0
                    let inner_ty = MonoType::Var(self.gen.fresh());
898
0
                    let option_ty = MonoType::Optional(Box::new(inner_ty.clone()));
899
0
                    self.unifier.unify(expected_ty, &option_ty)?;
900
0
                    self.infer_pattern(inner, &inner_ty)
901
                }
902
            }
903
            Pattern::None => {
904
                // None pattern matches Option<T> where T can be any type
905
0
                let type_var = MonoType::Var(self.gen.fresh());
906
0
                let option_ty = MonoType::Optional(Box::new(type_var));
907
0
                self.unifier.unify(expected_ty, &option_ty)
908
            }
909
0
            Pattern::Tuple(patterns) => {
910
                // Create tuple type with each pattern's inferred type
911
0
                let mut elem_types = Vec::new();
912
0
                for pat in patterns {
913
0
                    let elem_ty = MonoType::Var(self.gen.fresh());
914
0
                    self.infer_pattern(pat, &elem_ty)?;
915
0
                    elem_types.push(elem_ty);
916
                }
917
0
                let tuple_ty = MonoType::Tuple(elem_types);
918
0
                self.unifier.unify(expected_ty, &tuple_ty)
919
            }
920
0
            Pattern::Struct { name, fields, has_rest: _ } => {
921
                // For now, treat struct patterns as a named type
922
                // In a more complete implementation, we'd look up the struct definition
923
0
                let struct_ty = MonoType::Named(name.clone());
924
0
                self.unifier.unify(expected_ty, &struct_ty)?;
925
926
                // Infer field patterns (simplified approach)
927
0
                for field in fields {
928
0
                    if let Some(pattern) = &field.pattern {
929
0
                        let field_ty = MonoType::Var(self.gen.fresh());
930
0
                        self.infer_pattern(pattern, &field_ty)?;
931
0
                    }
932
                }
933
0
                Ok(())
934
            }
935
0
            Pattern::Range { start, end, .. } => {
936
                // Range patterns should match numeric types
937
0
                let start_ty = MonoType::Var(self.gen.fresh());
938
0
                let end_ty = MonoType::Var(self.gen.fresh());
939
0
                self.infer_pattern(start, &start_ty)?;
940
0
                self.infer_pattern(end, &end_ty)?;
941
942
                // Unify start and end types, and with expected type
943
0
                self.unifier.unify(&start_ty, &end_ty)?;
944
0
                self.unifier.unify(expected_ty, &start_ty)
945
            }
946
0
            Pattern::Or(patterns) => {
947
                // All patterns in an OR must have the same type
948
0
                for pat in patterns {
949
0
                    self.infer_pattern(pat, expected_ty)?;
950
                }
951
0
                Ok(())
952
            }
953
            Pattern::Rest => {
954
                // Rest patterns don't bind to specific types
955
0
                Ok(())
956
            }
957
0
            Pattern::RestNamed(name) => {
958
                // Named rest patterns bind the remaining elements to the name
959
                // For arrays [first, ..rest], rest should be array type
960
0
                self.env = self.env.extend(name, TypeScheme::mono(expected_ty.clone()));
961
0
                Ok(())
962
            }
963
        }
964
0
    }
965
966
0
    fn infer_for(&mut self, var: &str, iter: &Expr, body: &Expr) -> Result<MonoType> {
967
0
        let iter_ty = self.infer_expr(iter)?;
968
969
        // Iterator should be a list
970
0
        let elem_ty = MonoType::Var(self.gen.fresh());
971
0
        self.unifier
972
0
            .unify(&iter_ty, &MonoType::List(Box::new(elem_ty.clone())))?;
973
974
        // Bind loop variable and infer body
975
0
        let old_env = self.env.clone();
976
0
        self.env = self.env.extend(var, TypeScheme::mono(elem_ty));
977
0
        let _body_ty = self.infer_expr(body)?;
978
0
        self.env = old_env;
979
980
        // For loops always return Unit regardless of body type
981
0
        Ok(MonoType::Unit)
982
0
    }
983
984
0
    fn infer_while(&mut self, condition: &Expr, body: &Expr) -> Result<MonoType> {
985
        // Condition must be Bool
986
0
        let cond_ty = self.infer_expr(condition)?;
987
0
        self.unifier.unify(&cond_ty, &MonoType::Bool)?;
988
989
        // Type check body
990
0
        let body_ty = self.infer_expr(body)?;
991
0
        self.unifier.unify(&body_ty, &MonoType::Unit)?;
992
993
        // While loops return unit
994
0
        Ok(MonoType::Unit)
995
0
    }
996
997
0
    fn infer_loop(&mut self, body: &Expr) -> Result<MonoType> {
998
        // Type check body
999
0
        let body_ty = self.infer_expr(body)?;
1000
0
        self.unifier.unify(&body_ty, &MonoType::Unit)?;
1001
1002
        // Loop expressions return unit
1003
0
        Ok(MonoType::Unit)
1004
0
    }
1005
1006
0
    fn infer_range(&mut self, start: &Expr, end: &Expr) -> Result<MonoType> {
1007
0
        let start_ty = self.infer_expr(start)?;
1008
0
        let end_ty = self.infer_expr(end)?;
1009
1010
        // Both must be integers
1011
0
        self.unifier.unify(&start_ty, &MonoType::Int)?;
1012
0
        self.unifier.unify(&end_ty, &MonoType::Int)?;
1013
1014
        // Range produces a list of integers
1015
0
        Ok(MonoType::List(Box::new(MonoType::Int)))
1016
0
    }
1017
1018
0
    fn infer_pipeline(
1019
0
        &mut self,
1020
0
        expr: &Expr,
1021
0
        stages: &[crate::frontend::ast::PipelineStage],
1022
0
    ) -> Result<MonoType> {
1023
0
        let mut current_ty = self.infer_expr(expr)?;
1024
1025
0
        for stage in stages {
1026
            // Each stage is a function applied to current value
1027
0
            let stage_ty = self.infer_expr(&stage.op)?;
1028
1029
            // Create expected function type
1030
0
            let result_ty = MonoType::Var(self.gen.fresh());
1031
0
            let expected_func =
1032
0
                MonoType::Function(Box::new(current_ty.clone()), Box::new(result_ty.clone()));
1033
1034
0
            self.unifier.unify(&stage_ty, &expected_func)?;
1035
0
            current_ty = self.unifier.apply(&result_ty);
1036
        }
1037
1038
0
        Ok(current_ty)
1039
0
    }
1040
1041
0
    fn infer_assign(&mut self, target: &Expr, value: &Expr) -> Result<MonoType> {
1042
        // Infer the type of the value being assigned
1043
0
        let value_ty = self.infer_expr(value)?;
1044
1045
        // Infer the type of the target (lvalue)
1046
0
        let target_ty = self.infer_expr(target)?;
1047
1048
        // Target and value must have compatible types
1049
0
        self.unifier.unify(&target_ty, &value_ty)?;
1050
1051
        // Assignment expressions return Unit
1052
0
        Ok(MonoType::Unit)
1053
0
    }
1054
1055
0
    fn infer_compound_assign(
1056
0
        &mut self,
1057
0
        target: &Expr,
1058
0
        op: BinaryOp,
1059
0
        value: &Expr,
1060
0
    ) -> Result<MonoType> {
1061
        // Infer the types of target and value
1062
0
        let target_ty = self.infer_expr(target)?;
1063
0
        let value_ty = self.infer_expr(value)?;
1064
1065
        // For compound assignment, we need to ensure the operation is valid
1066
        // This is equivalent to: target = target op value
1067
0
        let result_ty = self.infer_binary_op_type(op, &target_ty, &value_ty)?;
1068
1069
        // The result type must be compatible with the target type
1070
0
        self.unifier.unify(&target_ty, &result_ty)?;
1071
1072
        // Compound assignment expressions return Unit
1073
0
        Ok(MonoType::Unit)
1074
0
    }
1075
1076
0
    fn infer_binary_op_type(
1077
0
        &mut self,
1078
0
        op: BinaryOp,
1079
0
        left_ty: &MonoType,
1080
0
        right_ty: &MonoType,
1081
0
    ) -> Result<MonoType> {
1082
0
        match op {
1083
            BinaryOp::Add
1084
            | BinaryOp::Subtract
1085
            | BinaryOp::Multiply
1086
            | BinaryOp::Divide
1087
            | BinaryOp::Modulo => {
1088
                // Arithmetic operations: both operands should be numbers, result is same type
1089
                // Try Int first, then Float
1090
0
                if let Ok(()) = self.unifier.unify(left_ty, &MonoType::Int) {
1091
0
                    if let Ok(()) = self.unifier.unify(right_ty, &MonoType::Int) {
1092
0
                        return Ok(MonoType::Int);
1093
0
                    }
1094
0
                }
1095
                // Fall back to Float
1096
0
                self.unifier.unify(left_ty, &MonoType::Float)?;
1097
0
                self.unifier.unify(right_ty, &MonoType::Float)?;
1098
0
                Ok(MonoType::Float)
1099
            }
1100
            BinaryOp::Power => {
1101
                // Power operation: base and exponent are numbers, result is same as base
1102
0
                self.unifier.unify(left_ty, right_ty)?;
1103
0
                if let Ok(()) = self.unifier.unify(left_ty, &MonoType::Int) {
1104
0
                    Ok(MonoType::Int)
1105
                } else {
1106
0
                    self.unifier.unify(left_ty, &MonoType::Float)?;
1107
0
                    Ok(MonoType::Float)
1108
                }
1109
            }
1110
            BinaryOp::Equal
1111
            | BinaryOp::NotEqual
1112
            | BinaryOp::Less
1113
            | BinaryOp::LessEqual
1114
            | BinaryOp::Greater
1115
            | BinaryOp::GreaterEqual => {
1116
                // Comparison operations: operands must be same type, result is Bool
1117
0
                self.unifier.unify(left_ty, right_ty)?;
1118
0
                Ok(MonoType::Bool)
1119
            }
1120
            BinaryOp::And | BinaryOp::Or => {
1121
                // Logical operations: both operands must be Bool, result is Bool
1122
0
                self.unifier.unify(left_ty, &MonoType::Bool)?;
1123
0
                self.unifier.unify(right_ty, &MonoType::Bool)?;
1124
0
                Ok(MonoType::Bool)
1125
            }
1126
            BinaryOp::NullCoalesce => {
1127
                // Null coalescing: return type should be the non-null operand type
1128
                // For now, return right_ty (could be improved with proper union types)
1129
0
                Ok(right_ty.clone())
1130
            }
1131
            BinaryOp::BitwiseAnd
1132
            | BinaryOp::BitwiseOr
1133
            | BinaryOp::BitwiseXor
1134
            | BinaryOp::LeftShift => {
1135
                // Bitwise operations: both operands must be Int, result is Int
1136
0
                self.unifier.unify(left_ty, &MonoType::Int)?;
1137
0
                self.unifier.unify(right_ty, &MonoType::Int)?;
1138
0
                Ok(MonoType::Int)
1139
            }
1140
        }
1141
0
    }
1142
1143
0
    fn infer_increment_decrement(&mut self, target: &Expr) -> Result<MonoType> {
1144
        // Infer the type of the target
1145
0
        let target_ty = self.infer_expr(target)?;
1146
1147
        // Target must be a numeric type (Int or Float)
1148
        // Try Int first, then Float
1149
0
        if let Ok(()) = self.unifier.unify(&target_ty, &MonoType::Int) {
1150
0
            Ok(MonoType::Int)
1151
        } else {
1152
0
            self.unifier.unify(&target_ty, &MonoType::Float)?;
1153
0
            Ok(MonoType::Float)
1154
        }
1155
0
    }
1156
1157
3
    fn ast_type_to_mono_static(ty: &crate::frontend::ast::Type) -> Result<MonoType> {
1158
        use crate::frontend::ast::TypeKind;
1159
1160
3
        Ok(match &ty.kind {
1161
3
            TypeKind::Named(name) => match name.as_str() {
1162
3
                "i32" | 
"i64"0
=> MonoType::Int,
1163
0
                "f32" | "f64" => MonoType::Float,
1164
0
                "bool" => MonoType::Bool,
1165
0
                "String" | "str" => MonoType::String,
1166
0
                "Any" => MonoType::Var(TyVarGenerator::new().fresh()),
1167
0
                _ => MonoType::Named(name.clone()),
1168
            },
1169
0
            TypeKind::Generic { base, params } => {
1170
                // For now, treat generic types as their base type
1171
                // Full generic inference will be implemented later
1172
0
                match base.as_str() {
1173
0
                    "Vec" | "List" => {
1174
0
                        if let Some(first_param) = params.first() {
1175
0
                            MonoType::List(Box::new(Self::ast_type_to_mono_static(first_param)?))
1176
                        } else {
1177
0
                            MonoType::List(Box::new(MonoType::Var(TyVarGenerator::new().fresh())))
1178
                        }
1179
                    }
1180
0
                    "Option" => {
1181
0
                        if let Some(first_param) = params.first() {
1182
0
                            MonoType::Optional(Box::new(Self::ast_type_to_mono_static(
1183
0
                                first_param,
1184
0
                            )?))
1185
                        } else {
1186
0
                            MonoType::Optional(Box::new(MonoType::Var(
1187
0
                                TyVarGenerator::new().fresh(),
1188
0
                            )))
1189
                        }
1190
                    }
1191
0
                    _ => MonoType::Named(base.clone()),
1192
                }
1193
            }
1194
0
            TypeKind::Optional(inner) => {
1195
0
                MonoType::Optional(Box::new(Self::ast_type_to_mono_static(inner)?))
1196
            }
1197
0
            TypeKind::List(inner) => {
1198
0
                MonoType::List(Box::new(Self::ast_type_to_mono_static(inner)?))
1199
            }
1200
0
            TypeKind::Function { params, ret } => {
1201
0
                let ret_ty = Self::ast_type_to_mono_static(ret)?;
1202
0
                let result: Result<MonoType> =
1203
0
                    params.iter().rev().try_fold(ret_ty, |acc, param| {
1204
                        Ok(MonoType::Function(
1205
0
                            Box::new(Self::ast_type_to_mono_static(param)?),
1206
0
                            Box::new(acc),
1207
                        ))
1208
0
                    });
1209
0
                result?
1210
            }
1211
0
            TypeKind::DataFrame { columns } => {
1212
0
                let mut col_types = Vec::new();
1213
0
                for (name, ty) in columns {
1214
0
                    col_types.push((name.clone(), Self::ast_type_to_mono_static(ty)?));
1215
                }
1216
0
                MonoType::DataFrame(col_types)
1217
            }
1218
0
            TypeKind::Series { dtype } => {
1219
0
                MonoType::Series(Box::new(Self::ast_type_to_mono_static(dtype)?))
1220
            }
1221
0
            TypeKind::Tuple(types) => {
1222
0
                let mono_types: Result<Vec<_>> = types
1223
0
                    .iter()
1224
0
                    .map(Self::ast_type_to_mono_static)
1225
0
                    .collect();
1226
0
                MonoType::Tuple(mono_types?)
1227
            }
1228
0
            TypeKind::Reference { inner, .. } => {
1229
                // For type inference, treat references the same as the inner type
1230
0
                Self::ast_type_to_mono_static(inner)?
1231
            }
1232
        })
1233
3
    }
1234
1235
    /// Get the final inferred type for a type variable
1236
    #[must_use]
1237
0
    pub fn solve(&self, var: &crate::middleend::types::TyVar) -> MonoType {
1238
0
        self.unifier.solve(var)
1239
0
    }
1240
1241
    /// Apply current substitution to a type
1242
    #[must_use]
1243
0
    pub fn apply(&self, ty: &MonoType) -> MonoType {
1244
0
        self.unifier.apply(ty)
1245
0
    }
1246
1247
    /// Infer types for control flow expressions (if, match, loops)
1248
    /// 
1249
    /// # Example Usage
1250
    /// Handles type inference for control flow constructs.
1251
    /// For if expressions, ensures both branches have compatible types.
1252
    /// For match expressions, checks pattern compatibility and branch types.
1253
4
    fn infer_control_flow_expr(&mut self, expr: &Expr) -> Result<MonoType> {
1254
4
        match &expr.kind {
1255
4
            ExprKind::If { condition, then_branch, else_branch } => {
1256
4
                self.infer_if(condition, then_branch, else_branch.as_deref())
1257
            }
1258
0
            ExprKind::For { var, iter, body, .. } => self.infer_for(var, iter, body),
1259
0
            ExprKind::While { condition, body } => self.infer_while(condition, body),
1260
0
            ExprKind::Loop { body } => self.infer_loop(body),
1261
0
            ExprKind::IfLet { pattern: _, expr, then_branch, else_branch } => {
1262
0
                let _expr_ty = self.infer_expr(expr)?;
1263
0
                let then_ty = self.infer_expr(then_branch)?;
1264
0
                let else_ty = if let Some(else_expr) = else_branch {
1265
0
                    self.infer_expr(else_expr)?
1266
                } else {
1267
0
                    MonoType::Unit
1268
                };
1269
0
                self.unifier.unify(&then_ty, &else_ty)?;
1270
0
                Ok(then_ty)
1271
            }
1272
0
            ExprKind::WhileLet { pattern: _, expr, body } => {
1273
0
                let _expr_ty = self.infer_expr(expr)?;
1274
0
                let _body_ty = self.infer_expr(body)?;
1275
0
                Ok(MonoType::Unit)
1276
            }
1277
0
            _ => bail!("Unexpected expression type in control flow handler"),
1278
        }
1279
4
    }
1280
    
1281
    /// Infer types for function and lambda expressions
1282
13
    fn infer_function_expr(&mut self, expr: &Expr) -> Result<MonoType> {
1283
13
        match &expr.kind {
1284
2
            ExprKind::Function { name, params, body, return_type, is_async, .. } => {
1285
2
                self.infer_function(name, params, body, return_type.as_ref(), *is_async)
1286
            }
1287
11
            ExprKind::Lambda { params, body } => self.infer_lambda(params, body),
1288
0
            _ => bail!("Unexpected expression type in function handler"),
1289
        }
1290
13
    }
1291
    
1292
    /// Infer types for collection expressions (lists, tuples, comprehensions)
1293
7
    fn infer_collection_expr(&mut self, expr: &Expr) -> Result<MonoType> {
1294
7
        match &expr.kind {
1295
7
            ExprKind::List(elements) => self.infer_list(elements),
1296
0
            ExprKind::Tuple(elements) => {
1297
0
                let element_types: Result<Vec<_>> = elements.iter().map(|e| self.infer_expr(e)).collect();
1298
0
                Ok(MonoType::Tuple(element_types?))
1299
            }
1300
0
            ExprKind::ListComprehension { element, variable, iterable, condition } => {
1301
0
                self.infer_list_comprehension(element, variable, iterable, condition.as_deref())
1302
            }
1303
0
            _ => bail!("Unexpected expression type in collection handler"),
1304
        }
1305
7
    }
1306
    
1307
    /// Infer types for operations and method calls
1308
32
    fn infer_operation_expr(&mut self, expr: &Expr) -> Result<MonoType> {
1309
32
        match &expr.kind {
1310
19
            ExprKind::Binary { left, op, right } => self.infer_binary(left, *op, right),
1311
0
            ExprKind::Unary { op, operand } => self.infer_unary(*op, operand),
1312
7
            ExprKind::Call { func, args } => self.infer_call(func, args),
1313
6
            ExprKind::MethodCall { receiver, method, args } => {
1314
6
                self.infer_method_call(receiver, method, args)
1315
            }
1316
0
            _ => bail!("Unexpected expression type in operation handler"),
1317
        }
1318
32
    }
1319
    
1320
    /// REFACTORED FOR COMPLEXITY REDUCTION
1321
    /// Original: 38 cyclomatic complexity, Target: <20
1322
    /// Strategy: Group related expression types into category handlers
1323
27
    pub fn infer_other_expr(&mut self, expr: &Expr) -> Result<MonoType> {
1324
27
        match &expr.kind {
1325
            // Special cases that need specific handling
1326
0
            ExprKind::StringInterpolation { parts } => self.infer_string_interpolation(parts),
1327
0
            ExprKind::Throw { expr } => self.infer_throw(expr),
1328
0
            ExprKind::Ok { value } => self.infer_result_ok(value),
1329
0
            ExprKind::Err { error } => self.infer_result_err(error),
1330
            
1331
            // Control flow expressions (all return Unit)
1332
            ExprKind::Break { .. } | ExprKind::Continue { .. } | ExprKind::Return { .. } => {
1333
0
                self.infer_other_control_flow_expr(expr)
1334
            }
1335
            
1336
            // Definition expressions (all return Unit)
1337
            ExprKind::Struct { .. } | ExprKind::Enum { .. } | ExprKind::Trait { .. } | 
1338
            ExprKind::Impl { .. } | ExprKind::Extension { .. } | ExprKind::Actor { .. } |
1339
            ExprKind::Import { .. } | ExprKind::Export { .. } => {
1340
2
                self.infer_other_definition_expr(expr)
1341
            }
1342
            
1343
            // Literal and access expressions
1344
            ExprKind::StructLiteral { .. } | ExprKind::ObjectLiteral { .. } | 
1345
            ExprKind::FieldAccess { .. } | ExprKind::IndexAccess { .. } | ExprKind::Slice { .. } => {
1346
0
                self.infer_other_literal_access_expr(expr)
1347
            }
1348
            
1349
            // Option expressions
1350
0
            ExprKind::Some { .. } | ExprKind::None => self.infer_other_option_expr(expr),
1351
            
1352
            // Async expressions
1353
            ExprKind::Await { .. } | ExprKind::AsyncBlock { .. } | ExprKind::Try { .. } => {
1354
0
                self.infer_other_async_expr(expr)
1355
            }
1356
            
1357
            // Actor expressions
1358
            ExprKind::Send { .. } | ExprKind::ActorSend { .. } | ExprKind::Ask { .. } | 
1359
            ExprKind::ActorQuery { .. } => {
1360
0
                self.infer_other_actor_expr(expr)
1361
            }
1362
            
1363
            // Assignment expressions
1364
            ExprKind::Assign { .. } | ExprKind::CompoundAssign { .. } |
1365
            ExprKind::PreIncrement { .. } | ExprKind::PostIncrement { .. } |
1366
            ExprKind::PreDecrement { .. } | ExprKind::PostDecrement { .. } => {
1367
0
                self.infer_other_assignment_expr(expr)
1368
            }
1369
            
1370
            // Remaining expressions
1371
25
            _ => self.infer_remaining_expr(expr),
1372
        }
1373
27
    }
1374
    
1375
    /// Extract control flow handling (complexity ~1)
1376
0
    fn infer_other_control_flow_expr(&mut self, _expr: &Expr) -> Result<MonoType> {
1377
0
        Ok(MonoType::Unit)  // All control flow returns Unit
1378
0
    }
1379
    
1380
    /// Extract definition handling (complexity ~1)  
1381
2
    fn infer_other_definition_expr(&mut self, _expr: &Expr) -> Result<MonoType> {
1382
2
        Ok(MonoType::Unit)  // All definitions return Unit
1383
2
    }
1384
    
1385
    /// Extract literal/access handling (complexity ~8)
1386
0
    fn infer_other_literal_access_expr(&mut self, expr: &Expr) -> Result<MonoType> {
1387
0
        match &expr.kind {
1388
0
            ExprKind::StructLiteral { name, .. } => Ok(MonoType::Named(name.clone())),
1389
0
            ExprKind::ObjectLiteral { fields } => self.infer_object_literal(fields),
1390
0
            ExprKind::FieldAccess { object, .. } => self.infer_field_access(object),
1391
0
            ExprKind::IndexAccess { object, index } => self.infer_index_access(object, index),
1392
0
            ExprKind::Slice { object, .. } => self.infer_slice(object),
1393
0
            _ => bail!("Unexpected literal/access expression"),
1394
        }
1395
0
    }
1396
    
1397
    /// Extract option handling (complexity ~5)
1398
0
    fn infer_other_option_expr(&mut self, expr: &Expr) -> Result<MonoType> {
1399
0
        match &expr.kind {
1400
0
            ExprKind::Some { value } => {
1401
0
                let inner_type = self.infer_expr(value)?;
1402
0
                Ok(MonoType::Optional(Box::new(inner_type)))
1403
            }
1404
            ExprKind::None => {
1405
0
                let type_var = MonoType::Var(self.gen.fresh());
1406
0
                Ok(MonoType::Optional(Box::new(type_var)))
1407
            }
1408
0
            _ => bail!("Unexpected option expression"),
1409
        }
1410
0
    }
1411
    
1412
    /// Extract async handling (complexity ~5)
1413
0
    fn infer_other_async_expr(&mut self, expr: &Expr) -> Result<MonoType> {
1414
0
        match &expr.kind {
1415
0
            ExprKind::Await { expr } => self.infer_await(expr),
1416
0
            ExprKind::AsyncBlock { body } => self.infer_async_block(body),
1417
0
            ExprKind::Try { expr } => {
1418
0
                let expr_type = self.infer(expr)?;
1419
0
                Ok(expr_type)
1420
            }
1421
0
            _ => bail!("Unexpected async expression"),
1422
        }
1423
0
    }
1424
    
1425
    /// Extract actor handling (complexity ~6)
1426
0
    fn infer_other_actor_expr(&mut self, expr: &Expr) -> Result<MonoType> {
1427
0
        match &expr.kind {
1428
0
            ExprKind::Send { actor, message } | ExprKind::ActorSend { actor, message } => {
1429
0
                self.infer_send(actor, message)
1430
            }
1431
0
            ExprKind::Ask { actor, message, timeout } => {
1432
0
                self.infer_ask(actor, message, timeout.as_deref())
1433
            }
1434
0
            ExprKind::ActorQuery { actor, message } => self.infer_ask(actor, message, None),
1435
0
            _ => bail!("Unexpected actor expression"),
1436
        }
1437
0
    }
1438
    
1439
    /// Extract assignment handling (complexity ~6)
1440
0
    fn infer_other_assignment_expr(&mut self, expr: &Expr) -> Result<MonoType> {
1441
0
        match &expr.kind {
1442
0
            ExprKind::Assign { target, value } => self.infer_assign(target, value),
1443
0
            ExprKind::CompoundAssign { target, op, value } => {
1444
0
                self.infer_compound_assign(target, *op, value)
1445
            }
1446
0
            ExprKind::PreIncrement { target } | ExprKind::PostIncrement { target } |
1447
0
            ExprKind::PreDecrement { target } | ExprKind::PostDecrement { target } => {
1448
0
                self.infer_increment_decrement(target)
1449
            }
1450
0
            _ => bail!("Unexpected assignment expression"),
1451
        }
1452
0
    }
1453
    
1454
    /// Extract remaining expressions (complexity ~8)
1455
25
    fn infer_remaining_expr(&mut self, expr: &Expr) -> Result<MonoType> {
1456
25
        match &expr.kind {
1457
11
            ExprKind::Let { name, value, body, is_mutable, .. } => {
1458
11
                self.infer_let(name, value, body, *is_mutable)
1459
            }
1460
8
            ExprKind::Block(exprs) => self.infer_block(exprs),
1461
0
            ExprKind::Range { start, end, .. } => self.infer_range(start, end),
1462
0
            ExprKind::Pipeline { expr, stages } => self.infer_pipeline(expr, stages),
1463
0
            ExprKind::Module { body, .. } => self.infer_expr(body),
1464
5
            ExprKind::DataFrame { columns } => self.infer_dataframe(columns),
1465
0
            ExprKind::Command { .. } => Ok(MonoType::String),
1466
0
            ExprKind::Macro { name, args } => self.infer_macro(name, args),
1467
1
            ExprKind::DataFrameOperation { source, operation } => {
1468
1
                self.infer_dataframe_operation(source, operation)
1469
            }
1470
0
            _ => bail!("Unknown expression type in inference"),
1471
        }
1472
25
    }
1473
    
1474
    /// Helper methods for complex expression groups
1475
0
    fn infer_string_interpolation(
1476
0
        &mut self,
1477
0
        parts: &[crate::frontend::ast::StringPart],
1478
0
    ) -> Result<MonoType> {
1479
0
        for part in parts {
1480
0
            if let crate::frontend::ast::StringPart::Expr(expr) = part {
1481
0
                let _ = self.infer_expr(expr)?;
1482
0
            }
1483
        }
1484
0
        Ok(MonoType::Named("String".to_string()))
1485
0
    }
1486
1487
0
    fn infer_result_ok(&mut self, value: &Expr) -> Result<MonoType> {
1488
0
        let value_type = self.infer_expr(value)?;
1489
0
        let error_type = MonoType::Var(self.gen.fresh());
1490
0
        Ok(MonoType::Result(Box::new(value_type), Box::new(error_type)))
1491
0
    }
1492
1493
0
    fn infer_result_err(&mut self, error: &Expr) -> Result<MonoType> {
1494
0
        let error_type = self.infer_expr(error)?;
1495
0
        let value_type = MonoType::Var(self.gen.fresh());
1496
0
        Ok(MonoType::Result(Box::new(value_type), Box::new(error_type)))
1497
0
    }
1498
1499
0
    fn infer_object_literal(
1500
0
        &mut self,
1501
0
        fields: &[crate::frontend::ast::ObjectField],
1502
0
    ) -> Result<MonoType> {
1503
0
        for field in fields {
1504
0
            match field {
1505
0
                crate::frontend::ast::ObjectField::KeyValue { value, .. } => {
1506
0
                    let _ = self.infer_expr(value)?;
1507
                }
1508
0
                crate::frontend::ast::ObjectField::Spread { expr } => {
1509
0
                    let _ = self.infer_expr(expr)?;
1510
                }
1511
            }
1512
        }
1513
0
        Ok(MonoType::Named("Object".to_string()))
1514
0
    }
1515
1516
0
    fn infer_field_access(&mut self, object: &Expr) -> Result<MonoType> {
1517
0
        let _object_ty = self.infer_expr(object)?;
1518
0
        Ok(MonoType::Var(self.gen.fresh()))
1519
0
    }
1520
1521
0
    fn infer_index_access(&mut self, object: &Expr, index: &Expr) -> Result<MonoType> {
1522
0
        let object_ty = self.infer_expr(object)?;
1523
0
        let index_ty = self.infer_expr(index)?;
1524
        
1525
        // Check if the index is a range (which results in slicing)
1526
0
        if let MonoType::List(inner_ty) = &index_ty {
1527
0
            if matches!(**inner_ty, MonoType::Int) {
1528
                // This is a range (List of integers), so return the same collection type
1529
0
                return Ok(object_ty);
1530
0
            }
1531
0
        }
1532
        
1533
        // Regular integer indexing - return the element type
1534
0
        match object_ty {
1535
0
            MonoType::List(element_ty) => {
1536
                // Ensure index is an integer
1537
0
                self.unifier.unify(&index_ty, &MonoType::Int)?;
1538
0
                Ok(*element_ty)
1539
            }
1540
            MonoType::String => {
1541
                // Ensure index is an integer
1542
0
                self.unifier.unify(&index_ty, &MonoType::Int)?;
1543
0
                Ok(MonoType::String)
1544
            }
1545
0
            _ => Ok(MonoType::Var(self.gen.fresh())),
1546
        }
1547
0
    }
1548
1549
0
    fn infer_slice(&mut self, object: &Expr) -> Result<MonoType> {
1550
0
        let object_ty = self.infer_expr(object)?;
1551
        // Slicing returns the same type as the original collection
1552
        // (a slice of a list is still a list, a slice of a string is still a string)
1553
0
        Ok(object_ty)
1554
0
    }
1555
1556
0
    fn infer_send(&mut self, actor: &Expr, message: &Expr) -> Result<MonoType> {
1557
0
        let _actor_ty = self.infer_expr(actor)?;
1558
0
        let _message_ty = self.infer_expr(message)?;
1559
0
        Ok(MonoType::Unit)
1560
0
    }
1561
1562
0
    fn infer_ask(
1563
0
        &mut self,
1564
0
        actor: &Expr,
1565
0
        message: &Expr,
1566
0
        timeout: Option<&Expr>,
1567
0
    ) -> Result<MonoType> {
1568
0
        let _actor_ty = self.infer_expr(actor)?;
1569
0
        let _message_ty = self.infer_expr(message)?;
1570
0
        if let Some(t) = timeout {
1571
0
            let timeout_ty = self.infer_expr(t)?;
1572
0
            self.unifier.unify(&timeout_ty, &MonoType::Int)?;
1573
0
        }
1574
0
        Ok(MonoType::Var(self.gen.fresh()))
1575
0
    }
1576
1577
5
    fn infer_dataframe(
1578
5
        &mut self,
1579
5
        columns: &[crate::frontend::ast::DataFrameColumn],
1580
5
    ) -> Result<MonoType> {
1581
5
        let mut column_types = Vec::new();
1582
1583
12
        for 
col7
in columns {
1584
            // Infer the type of the first value to determine column type
1585
7
            let col_type = if col.values.is_empty() {
1586
0
                MonoType::Var(self.gen.fresh())
1587
            } else {
1588
7
                let first_ty = self.infer_expr(&col.values[0])
?0
;
1589
                // Verify all values in the column have the same type
1590
7
                for value in &col.values[1..] {
1591
7
                    let value_ty = self.infer_expr(value)
?0
;
1592
7
                    self.unifier.unify(&first_ty, &value_ty)
?0
;
1593
                }
1594
7
                first_ty
1595
            };
1596
7
            column_types.push((col.name.clone(), col_type));
1597
        }
1598
1599
5
        Ok(MonoType::DataFrame(column_types))
1600
5
    }
1601
1602
1
    fn infer_dataframe_operation(
1603
1
        &mut self,
1604
1
        source: &Expr,
1605
1
        operation: &crate::frontend::ast::DataFrameOp,
1606
1
    ) -> Result<MonoType> {
1607
        use crate::frontend::ast::DataFrameOp;
1608
1609
1
        let source_ty = self.infer_expr(source)
?0
;
1610
1611
        // Ensure source is a DataFrame
1612
0
        match &source_ty {
1613
1
            MonoType::DataFrame(columns) => {
1614
1
                match operation {
1615
                    DataFrameOp::Filter(_) => {
1616
                        // Filter preserves the DataFrame structure
1617
0
                        Ok(source_ty.clone())
1618
                    }
1619
1
                    DataFrameOp::Select(selected_cols) => {
1620
                        // Select creates a new DataFrame with only the selected columns
1621
1
                        let mut new_columns = Vec::new();
1622
2
                        for 
col_name1
in selected_cols {
1623
1
                            if let Some((_, ty)) = columns.iter().find(|(name, _)| name == col_name)
1624
1
                            {
1625
1
                                new_columns.push((col_name.clone(), ty.clone()));
1626
1
                            
}0
1627
                        }
1628
1
                        Ok(MonoType::DataFrame(new_columns))
1629
                    }
1630
                    DataFrameOp::GroupBy(_) => {
1631
                        // GroupBy returns a grouped DataFrame (for now, same type)
1632
0
                        Ok(source_ty.clone())
1633
                    }
1634
                    DataFrameOp::Aggregate(_) => {
1635
                        // Aggregation returns a DataFrame with aggregated values
1636
0
                        Ok(source_ty.clone())
1637
                    }
1638
                    DataFrameOp::Join { .. } => {
1639
                        // Join returns a DataFrame (simplified for now)
1640
0
                        Ok(source_ty.clone())
1641
                    }
1642
                    DataFrameOp::Sort { .. } => {
1643
                        // Sort preserves the DataFrame structure
1644
0
                        Ok(source_ty.clone())
1645
                    }
1646
                    DataFrameOp::Limit(_) | DataFrameOp::Head(_) | DataFrameOp::Tail(_) => {
1647
                        // These operations preserve the DataFrame structure
1648
0
                        Ok(source_ty.clone())
1649
                    }
1650
                }
1651
            }
1652
0
            MonoType::Named(name) if name == "DataFrame" => {
1653
                // Fallback for untyped DataFrames
1654
0
                Ok(MonoType::Named("DataFrame".to_string()))
1655
            }
1656
0
            _ => bail!("DataFrame operation on non-DataFrame type: {}", source_ty),
1657
        }
1658
1
    }
1659
1660
0
    fn infer_async_block(&mut self, body: &Expr) -> Result<MonoType> {
1661
        // Infer the body type
1662
0
        let body_ty = self.infer_expr(body)?;
1663
1664
        // Async blocks return Future<Output = body_type>
1665
0
        Ok(MonoType::Named(format!("Future<{body_ty}>")))
1666
0
    }
1667
}
1668
1669
impl Default for InferenceContext {
1670
0
    fn default() -> Self {
1671
0
        Self::new()
1672
0
    }
1673
}
1674
1675
#[cfg(test)]
1676
#[allow(clippy::unwrap_used)]
1677
#[allow(clippy::panic)]
1678
mod tests {
1679
    use super::*;
1680
    use crate::frontend::parser::Parser;
1681
1682
40
    fn infer_str(input: &str) -> Result<MonoType> {
1683
40
        let mut parser = Parser::new(input);
1684
40
        let expr = parser.parse()
?0
;
1685
40
        let mut ctx = InferenceContext::new();
1686
40
        ctx.infer(&expr)
1687
40
    }
1688
1689
    #[test]
1690
1
    fn test_infer_literals() {
1691
1
        assert_eq!(infer_str("42").unwrap(), MonoType::Int);
1692
1
        assert_eq!(infer_str("3.14").unwrap(), MonoType::Float);
1693
1
        assert_eq!(infer_str("true").unwrap(), MonoType::Bool);
1694
1
        assert_eq!(infer_str("\"hello\"").unwrap(), MonoType::String);
1695
1
    }
1696
1697
    #[test]
1698
1
    fn test_infer_arithmetic() {
1699
1
        assert_eq!(infer_str("1 + 2").unwrap(), MonoType::Int);
1700
1
        assert_eq!(infer_str("3 * 4").unwrap(), MonoType::Int);
1701
1
        assert_eq!(infer_str("5 - 2").unwrap(), MonoType::Int);
1702
1
    }
1703
1704
    #[test]
1705
1
    fn test_infer_comparison() {
1706
1
        assert_eq!(infer_str("1 < 2").unwrap(), MonoType::Bool);
1707
1
        assert_eq!(infer_str("3 == 3").unwrap(), MonoType::Bool);
1708
1
        assert_eq!(infer_str("true != false").unwrap(), MonoType::Bool);
1709
1
    }
1710
1711
    #[test]
1712
1
    fn test_infer_if() {
1713
1
        assert_eq!(
1714
1
            infer_str("if true { 1 } else { 2 }").unwrap(),
1715
            MonoType::Int
1716
        );
1717
1
        assert_eq!(
1718
1
            infer_str("if false { \"yes\" } else { \"no\" }").unwrap(),
1719
            MonoType::String
1720
        );
1721
1
    }
1722
1723
    #[test]
1724
1
    fn test_infer_let() {
1725
1
        assert_eq!(infer_str("let x = 42 in x + 1").unwrap(), MonoType::Int);
1726
1
        assert_eq!(
1727
1
            infer_str("let f = 3.14 in let g = 2.71 in f").unwrap(),
1728
            MonoType::Float
1729
        );
1730
1
    }
1731
1732
    #[test]
1733
1
    fn test_infer_list() {
1734
1
        assert_eq!(
1735
1
            infer_str("[1, 2, 3]").unwrap(),
1736
1
            MonoType::List(Box::new(MonoType::Int))
1737
        );
1738
1
        assert_eq!(
1739
1
            infer_str("[true, false]").unwrap(),
1740
1
            MonoType::List(Box::new(MonoType::Bool))
1741
        );
1742
1
    }
1743
1744
    #[test]
1745
1
    fn test_infer_dataframe() {
1746
1
        let df_str = r#"df![
1747
1
            age => [25, 30, 35],
1748
1
            name => ["Alice", "Bob", "Charlie"]
1749
1
        ]"#;
1750
1751
1
        let result = infer_str(df_str).unwrap();
1752
1
        match result {
1753
1
            MonoType::DataFrame(columns) => {
1754
1
                assert_eq!(columns.len(), 2);
1755
1
                assert_eq!(columns[0].0, "age");
1756
1
                assert!(
matches!0
(columns[0].1, MonoType::Int));
1757
1
                assert_eq!(columns[1].0, "name");
1758
1
                assert!(
matches!0
(columns[1].1, MonoType::String));
1759
            }
1760
0
            _ => panic!("Expected DataFrame type, got {result:?}"),
1761
        }
1762
1
    }
1763
1764
    #[test]
1765
1
    fn test_infer_dataframe_operations() {
1766
        // Test filter operation with simpler pattern
1767
1
        let filter_str = r"df![age => [25, 30]].filter(|x| x > 25)";
1768
1
        let result = infer_str(filter_str).unwrap();
1769
1
        assert!(
matches!0
(result, MonoType::DataFrame(_)));
1770
1771
        // Test select operation
1772
1
        let select_str = r#"df![age => [25], name => ["Alice"]].select(["age"])"#;
1773
1
        let result = infer_str(select_str).unwrap();
1774
1
        match result {
1775
1
            MonoType::DataFrame(columns) => {
1776
1
                assert_eq!(columns.len(), 1);
1777
1
                assert_eq!(columns[0].0, "age");
1778
            }
1779
0
            _ => panic!("Expected DataFrame type, got {result:?}"),
1780
        }
1781
1
    }
1782
1783
    #[test]
1784
1
    fn test_infer_series() {
1785
        // Test column selection returns Series
1786
1
        let col_str = r#"df![age => [25, 30]].col("age")"#;
1787
1
        let result = infer_str(col_str).unwrap();
1788
1
        assert!(
matches!0
(result, MonoType::Series(_)));
1789
1790
        // Test aggregation on Series
1791
1
        let mean_str = r#"df![age => [25, 30]].col("age").mean()"#;
1792
1
        let result = infer_str(mean_str).unwrap();
1793
1
        assert_eq!(result, MonoType::Float);
1794
1
    }
1795
1796
    #[test]
1797
1
    fn test_infer_function() {
1798
1
        let result = infer_str("fun add(x: i32, y: i32) -> i32 { x + y }").unwrap();
1799
1
        match result {
1800
1
            MonoType::Function(first_arg, remaining) => {
1801
1
                assert!(
matches!0
(first_arg.as_ref(), MonoType::Int));
1802
1
                match remaining.as_ref() {
1803
1
                    MonoType::Function(second_arg, return_type) => {
1804
1
                        assert!(
matches!0
(second_arg.as_ref(), MonoType::Int));
1805
1
                        assert!(
matches!0
(return_type.as_ref(), MonoType::Int));
1806
                    }
1807
0
                    _ => panic!("Expected function type"),
1808
                }
1809
            }
1810
0
            _ => panic!("Expected function type"),
1811
        }
1812
1
    }
1813
1814
    #[test]
1815
1
    fn test_type_errors() {
1816
1
        assert!(infer_str("1 + true").is_err());
1817
1
        assert!(infer_str("if 42 { 1 } else { 2 }").is_err());
1818
1
        assert!(infer_str("[1, true, 3]").is_err());
1819
1
    }
1820
1821
    #[test]
1822
1
    fn test_infer_lambda() {
1823
        // Simple lambda: |x| x + 1
1824
1
        let result = infer_str("|x| x + 1").unwrap();
1825
1
        match result {
1826
1
            MonoType::Function(arg, ret) => {
1827
1
                assert!(
matches!0
(arg.as_ref(), MonoType::Int));
1828
1
                assert!(
matches!0
(ret.as_ref(), MonoType::Int));
1829
            }
1830
0
            _ => panic!("Expected function type for lambda"),
1831
        }
1832
1833
        // Lambda with multiple params: |x, y| x * y
1834
1
        let result = infer_str("|x, y| x * y").unwrap();
1835
1
        match result {
1836
1
            MonoType::Function(first_arg, remaining) => {
1837
1
                assert!(
matches!0
(first_arg.as_ref(), MonoType::Int));
1838
1
                match remaining.as_ref() {
1839
1
                    MonoType::Function(second_arg, return_type) => {
1840
1
                        assert!(
matches!0
(second_arg.as_ref(), MonoType::Int));
1841
1
                        assert!(
matches!0
(return_type.as_ref(), MonoType::Int));
1842
                    }
1843
0
                    _ => panic!("Expected function type"),
1844
                }
1845
            }
1846
0
            _ => panic!("Expected function type for lambda"),
1847
        }
1848
1849
        // Lambda with no params: || 42
1850
1
        let result = infer_str("|| 42").unwrap();
1851
1
        assert_eq!(result, MonoType::Int);
1852
1853
        // Lambda used in let binding
1854
1
        let result = infer_str("let f = |x| x + 1 in f(5)").unwrap();
1855
1
        assert_eq!(result, MonoType::Int);
1856
1
    }
1857
1858
    #[test]
1859
1
    fn test_self_hosting_patterns() {
1860
        // Test fat arrow lambda syntax inference
1861
1
        let result = infer_str("x => x * 2").unwrap();
1862
1
        match result {
1863
1
            MonoType::Function(arg, ret) => {
1864
1
                assert!(
matches!0
(arg.as_ref(), MonoType::Int));
1865
1
                assert!(
matches!0
(ret.as_ref(), MonoType::Int));
1866
            }
1867
0
            _ => panic!("Expected function type for fat arrow lambda"),
1868
        }
1869
1870
        // Test higher-order function patterns (compiler combinators)
1871
1
        let result = infer_str("let map = |f, xs| xs in let double = |x| x * 2 in map(double, [1, 2, 3])").unwrap();
1872
1
        assert!(
matches!0
(result, MonoType::List(_)));
1873
1874
        // Test recursive function inference (needed for recursive descent parser)
1875
1
        let result = infer_str("fun factorial(n: i32) -> i32 { if n <= 1 { 1 } else { n * factorial(n - 1) } }").unwrap();
1876
1
        match result {
1877
1
            MonoType::Function(arg, ret) => {
1878
1
                assert!(
matches!0
(arg.as_ref(), MonoType::Int));
1879
1
                assert!(
matches!0
(ret.as_ref(), MonoType::Int));
1880
            }
1881
0
            _ => panic!("Expected function type for recursive function"),
1882
        }
1883
1
    }
1884
    
1885
    #[test]
1886
1
    fn test_compiler_data_structures() {
1887
        // Test struct type inference for compiler data structures
1888
1
        let result = infer_str("struct Token { kind: String, value: String }").unwrap();
1889
1
        assert_eq!(result, MonoType::Unit);
1890
        
1891
        // Test enum for AST nodes
1892
1
        let result = infer_str("enum Expr { Literal, Binary, Function }").unwrap();
1893
1
        assert_eq!(result, MonoType::Unit);
1894
        
1895
        // Test Vec operations for token streams - basic list inference
1896
1
        let result = infer_str("[1, 2, 3]").unwrap();
1897
1
        assert!(
matches!0
(result, MonoType::List(_)));
1898
        
1899
        // Test list length method
1900
1
        let result = infer_str("[1, 2, 3].len()").unwrap();
1901
1
        assert_eq!(result, MonoType::Int);
1902
1
    }
1903
    
1904
    #[test]
1905
1
    fn test_constraint_solving() {
1906
        // Test basic list operations
1907
1
        let result = infer_str("[1, 2, 3].len()").unwrap();
1908
1
        assert_eq!(result, MonoType::Int);
1909
        
1910
        // Test polymorphic function inference
1911
1
        let result = infer_str("let id = |x| x in let n = id(42) in let s = id(\"hello\") in n").unwrap();
1912
1
        assert_eq!(result, MonoType::Int);
1913
        
1914
        // Test simple constraint solving
1915
1
        let result = infer_str("let f = |x| x + 1 in f").unwrap();
1916
1
        assert!(
matches!0
(result, MonoType::Function(_, _)));
1917
        
1918
        // Test function composition
1919
1
        let result = infer_str("let compose = |f, g, x| f(g(x)) in compose").unwrap();
1920
1
        assert!(
matches!0
(result, MonoType::Function(_, _)));
1921
1
    }
1922
}