Skip to main content

compiler/
infer.rs

1use super::{Compiler, FnInferRet, Symbol};
2use anyhow::Result;
3use dynamic::{Dynamic, Type};
4use parser::{BinaryOp, Expr, ExprKind, Pattern, PatternKind, Span, Stmt, StmtKind, UnaryOp};
5
6#[derive(Clone)]
7struct ReturnInfo {
8    ty: Type,
9    shape: Option<Type>,
10}
11
12impl Compiler {
13    fn current_infer_key(&self) -> Option<(u32, Vec<Type>, Vec<Type>)> {
14        self.infer_stack.last().cloned()
15    }
16
17    fn pending_return_seed(&self, id: u32, generic_args: &[Type], fn_tys: &[Type]) -> Option<Type> {
18        self.fns.get(&id).and_then(|fns| {
19            fns.iter().find_map(|item| {
20                if item.0 == generic_args
21                    && item.1 == fn_tys
22                    && let FnInferRet::Pending(seed) = &item.2
23                {
24                    seed.clone()
25                } else {
26                    None
27                }
28            })
29        })
30    }
31
32    fn update_pending_return_seed(&mut self, ty: &Type) {
33        if ty.is_any() {
34            return;
35        }
36        let Some((id, generic_args, fn_tys)) = self.current_infer_key() else {
37            return;
38        };
39        let Some(fns) = self.fns.get_mut(&id) else {
40            return;
41        };
42        if let Some(item) = fns.iter_mut().find(|item| item.0 == generic_args && item.1 == fn_tys)
43            && let FnInferRet::Pending(seed) = &mut item.2
44        {
45            let next = seed.take().map(|prev| prev + ty.clone()).unwrap_or_else(|| ty.clone());
46            *seed = Some(next);
47        }
48    }
49
50    fn add_pattern_bindings_for_infer(&mut self, pat: &Pattern, expr_ty: Type) -> Result<()> {
51        match &pat.kind {
52            PatternKind::Ident { name, ty } => {
53                let annotated_ty = self.symbols.get_type(ty)?;
54                self.add_name(name.clone());
55                self.add_ty(if annotated_ty.is_any() { expr_ty } else { annotated_ty });
56            }
57            PatternKind::Var { idx, .. } => self.set_ty(*idx, expr_ty),
58            PatternKind::Tuple(pats) => {
59                if let Type::Tuple(tys) = expr_ty {
60                    for (pat, ty) in pats.iter().zip(tys) {
61                        self.add_pattern_bindings_for_infer(pat, ty)?;
62                    }
63                } else {
64                    for pat in pats {
65                        self.add_pattern_bindings_for_infer(pat, Type::Any)?;
66                    }
67                }
68            }
69            PatternKind::List { elems, .. } => {
70                for pat in elems {
71                    self.add_pattern_bindings_for_infer(pat, Type::Any)?;
72                }
73            }
74            PatternKind::Wildcard => {
75                self.add_name("".into());
76                self.add_ty(expr_ty);
77            }
78            PatternKind::Literal(_) | PatternKind::Member(_, _) | PatternKind::Idx(_, _) => {}
79        }
80        Ok(())
81    }
82
83    fn for_pattern_ty(&mut self, range: &Expr) -> Result<Type> {
84        if matches!(range.kind, ExprKind::Range { .. }) {
85            return self.infer_expr(range);
86        }
87        Ok(match self.infer_expr(range)? {
88            Type::Array(elem_ty, _) | Type::Vec(elem_ty, _) => elem_ty.as_ref().clone(),
89            _ => Type::Any,
90        })
91    }
92
93    fn merge_return_type(span: Span, left: Option<Type>, right: Type) -> Result<Type> {
94        match left {
95            Some(left) if left == right => Ok(left),
96            Some(left) if left.is_void() || right.is_void() => Err(Self::semantic_error(span, format!("返回类型不一致: {:?} 和 {:?}", left, right))),
97            Some(left) => Ok(left + right),
98            None => Ok(right),
99        }
100    }
101
102    fn return_shape(&self, expr: &Expr, ty: &Type) -> Option<Type> {
103        if !ty.is_any() {
104            return if ty.is_struct() { Some(ty.clone()) } else { None };
105        }
106        match &expr.kind {
107            ExprKind::List(_) | ExprKind::Tuple(_) => Some(Type::List),
108            ExprKind::Dict(_) => Some(Type::Map),
109            ExprKind::Value(value) => Self::dynamic_return_shape(value.get_type()),
110            ExprKind::Const(idx) => self.consts.get(*idx).and_then(|value| Self::dynamic_return_shape(value.get_type())),
111            ExprKind::Typed { ty, .. } => Some(ty.clone()),
112            _ => None,
113        }
114    }
115
116    fn dynamic_return_shape(ty: Type) -> Option<Type> {
117        match ty {
118            Type::Map => Some(Type::Map),
119            Type::List | Type::Array(_, _) => Some(Type::List),
120            _ => None,
121        }
122    }
123
124    fn infer_return_expr(&mut self, expr: &Expr) -> Result<ReturnInfo> {
125        let ty = self.infer_expr(expr)?;
126        let shape = self.return_shape(expr, &ty);
127        Ok(ReturnInfo { ty, shape })
128    }
129
130    fn merge_return_info(span: Span, left: Option<ReturnInfo>, right: ReturnInfo) -> Result<ReturnInfo> {
131        let Some(left) = left else {
132            return Ok(right);
133        };
134        if let (Some(left_shape), Some(right_shape)) = (&left.shape, &right.shape)
135            && left_shape != right_shape
136        {
137            return Err(Self::semantic_error(span, format!("返回类型不一致: {:?} 和 {:?}", left_shape, right_shape)));
138        }
139        if let Some(left_shape) = &left.shape
140            && left_shape.is_struct()
141            && right.ty.is_any()
142            && right.shape.is_none()
143        {
144            return Err(Self::semantic_error(span, format!("返回类型不一致: {:?} 和 {:?}", left_shape, Type::Any)));
145        }
146        if let Some(right_shape) = &right.shape
147            && right_shape.is_struct()
148            && left.ty.is_any()
149            && left.shape.is_none()
150        {
151            return Err(Self::semantic_error(span, format!("返回类型不一致: {:?} 和 {:?}", Type::Any, right_shape)));
152        }
153        let ty = Self::merge_return_type(span, Some(left.ty), right.ty)?;
154        Ok(ReturnInfo { ty, shape: left.shape.or(right.shape) })
155    }
156
157    fn infer_return_type(&mut self, stmt: &Stmt) -> Result<Option<Type>> {
158        self.infer_returns(stmt, true).map(|(info, _)| info.map(|info| info.ty))
159    }
160
161    pub(crate) fn check_return_type(&mut self, stmt: &Stmt) -> Result<()> {
162        self.infer_returns(stmt, true).map(|_| ())
163    }
164
165    fn infer_returns(&mut self, stmt: &Stmt, tail: bool) -> Result<(Option<ReturnInfo>, bool)> {
166        match &stmt.kind {
167            StmtKind::Return(Some(expr)) => Ok((Some(self.infer_return_expr(expr)?), true)),
168            StmtKind::Return(None) => Ok((Some(ReturnInfo { ty: Type::Void, shape: Some(Type::Void) }), true)),
169            StmtKind::Block(stmts) => {
170                let mut ret = None;
171                for (idx, stmt) in stmts.iter().enumerate() {
172                    let (info, always_returns) = self.infer_returns(stmt, tail && idx == stmts.len().saturating_sub(1))?;
173                    if let Some(info) = info {
174                        self.update_pending_return_seed(&info.ty);
175                        ret = Some(Self::merge_return_info(stmt.span, ret, info)?);
176                        if let Some(ret) = &ret {
177                            self.update_pending_return_seed(&ret.ty);
178                        }
179                    }
180                    if always_returns {
181                        return Ok((ret, true));
182                    }
183                }
184                Ok((ret, false))
185            }
186            StmtKind::If { cond, then_body, else_body } => {
187                let cond_ty = self.infer_expr(cond)?;
188                if cond_ty != Type::Bool {
189                    return Err(Self::semantic_error(cond.span, format!("条件表达式必须是布尔类型,实际是 {:?}", cond_ty)));
190                }
191                let (mut ret, then_returns) = self.infer_returns(then_body, tail)?;
192                if let Some(ret) = &ret {
193                    self.update_pending_return_seed(&ret.ty);
194                }
195                let else_returns = if let Some(body) = else_body {
196                    let (else_ty, else_returns) = self.infer_returns(body, tail)?;
197                    if let Some(info) = else_ty {
198                        self.update_pending_return_seed(&info.ty);
199                        ret = Some(Self::merge_return_info(body.span, ret, info)?);
200                        if let Some(ret) = &ret {
201                            self.update_pending_return_seed(&ret.ty);
202                        }
203                    }
204                    else_returns
205                } else {
206                    false
207                };
208                Ok((ret, then_returns && else_returns))
209            }
210            StmtKind::While { cond, body } => {
211                let cond_ty = self.infer_expr(cond)?;
212                if cond_ty != Type::Bool {
213                    return Err(Self::semantic_error(cond.span, format!("条件表达式必须是布尔类型,实际是 {:?}", cond_ty)));
214                }
215                self.infer_returns(body, false).map(|(ty, _)| (ty, false))
216            }
217            StmtKind::Loop(body) => self.infer_returns(body, false),
218            StmtKind::For { pat, range, body } => {
219                let ty = self.for_pattern_ty(range)?;
220                self.add_pattern_bindings_for_infer(pat, ty)?;
221                self.infer_returns(body, false).map(|(ty, _)| (ty, false))
222            }
223            StmtKind::Let { .. } => {
224                self.infer_stmt(stmt)?;
225                Ok((None, false))
226            }
227            StmtKind::Expr(expr, close) => {
228                let info = self.infer_return_expr(expr)?;
229                Ok(if *close || !tail { (None, false) } else { (Some(info), true) })
230            }
231            _ => {
232                self.infer_stmt(stmt)?;
233                Ok((None, false))
234            }
235        }
236    }
237
238    pub fn infer_expr(&mut self, expr: &Expr) -> Result<Type> {
239        match &expr.kind {
240            ExprKind::Value(Dynamic::Null) => Ok(Type::Any),
241            ExprKind::Value(v) if v.is_list() || v.is_map() => Ok(Type::Any),
242            ExprKind::Value(v) => Ok(v.get_type()),
243            ExprKind::Const(_) => Ok(Type::Any),
244            ExprKind::Var(idx) => {
245                let idx = self.top() + (*idx as usize);
246                if idx < self.tys.len() { self.symbols.get_type(&self.tys[idx]) } else { Ok(Type::Any) }
247            }
248            ExprKind::Ident(ident) => {
249                for idx in (self.top()..self.names.len()).rev() {
250                    if self.names[idx].eq(ident) && idx < self.tys.len() {
251                        return self.symbols.get_type(&self.tys[idx]);
252                    }
253                }
254                let id = self.symbols.get_id(ident).map_err(|_| Self::semantic_error(expr.span, format!("未找到标识符 {}", ident)))?;
255                match self.symbols.get_symbol(id)?.1 {
256                    Symbol::Const { ty, .. } => Ok(ty.clone()),
257                    Symbol::Static { ty, .. } => Ok(ty.clone()),
258                    Symbol::Struct(ty, _) => Ok(ty.clone()),
259                    Symbol::Fn { .. } => Ok(Type::Symbol { id, params: Vec::new() }),
260                    Symbol::Native(ty) => Ok(ty.clone()),
261                    s => Err(Self::semantic_error(expr.span, format!("符号 {:?} 不是变量、常量、静态变量、结构体", s))),
262                }
263            }
264            ExprKind::Id(id, _) => match self.symbols.get_symbol(*id)?.1 {
265                Symbol::Const { ty, .. } => Ok(ty.clone()),
266                Symbol::Static { ty, .. } => Ok(ty.clone()),
267                Symbol::Struct(ty, _) => Ok(ty.clone()),
268                Symbol::Fn { .. } => Ok(Type::Symbol { id: *id, params: Vec::new() }),
269                Symbol::Native(ty) => Ok(ty.clone()),
270                s => Err(Self::semantic_error(expr.span, format!("符号 {:?} 不是变量、常量、静态变量、结构体", s))),
271            },
272            ExprKind::AssocId { id, params } => Ok(Type::Symbol { id: *id, params: params.clone() }),
273            ExprKind::Unary { op, value } => match op {
274                UnaryOp::Not => {
275                    let ty = self.infer_expr(value.as_ref())?;
276                    if ty.is_int() || ty.is_uint() { Ok(ty) } else { Ok(Type::Bool) }
277                }
278                UnaryOp::Neg => self.infer_expr(value.as_ref()),
279                UnaryOp::Unknow => Ok(Type::Any),
280            },
281            ExprKind::Binary { left, op, right } => {
282                let assign_idx = if op.is_assign() { if let ExprKind::Var(idx) = &left.kind { Some(*idx) } else { None } } else { None };
283                let ty = if op.is_logic() {
284                    Type::Bool
285                } else if op == &BinaryOp::Idx {
286                    let left_ty = self.infer_expr(left)?;
287                    if let Type::Array(elem_ty, _) = left_ty {
288                        (*elem_ty).clone()
289                    } else if let Type::Vec(elem_ty, _) = left_ty {
290                        (*elem_ty).clone()
291                    } else {
292                        let left_ty = self.symbols.get_type(&left_ty)?;
293                        let right_ty = if right.is_value() || right.is_const() {
294                            let right_value = if let ExprKind::Const(c) = &right.kind { self.consts[*c].clone() } else { right.clone().value()? };
295                            if right_value.is_str() {
296                                if left_ty.is_any() {
297                                    return Ok(Type::Any);
298                                }
299                                if let Ok(field) = self.symbols.get_field(&left_ty, right_value.as_str()) {
300                                    return if let Type::Fn { ret, .. } = field.1 { Ok(ret.as_ref().clone()) } else { Ok(field.1.clone()) };
301                                }
302                            } else if let Type::Struct { fields, .. } = &left_ty
303                                && let Some(idx) = right_value.as_int()
304                            {
305                                return fields.get(idx as usize).map(|(_, ty)| ty.clone()).ok_or_else(|| Self::semantic_error(right.span, format!("结构字段索引越界 {}", idx)));
306                            }
307                            right_value.get_type()
308                        } else {
309                            self.infer_expr(right)?
310                        };
311                        if right_ty.is_int() || right_ty.is_uint() {
312                            if left_ty.is_any() {
313                                return Ok(Type::Any);
314                            }
315                            let (_, s) = self.symbols.get_field(&left_ty, "get_idx")?;
316                            let fn_ty = self.symbols.get_type(&s)?;
317                            return if let Type::Fn { ret, .. } = &fn_ty { Ok(ret.as_ref().clone()) } else { Ok(fn_ty) };
318                        }
319                        if left_ty.is_any() {
320                            return Ok(Type::Any);
321                        }
322                        Type::Any
323                    }
324                } else {
325                    let left_ty = self.infer_expr(left)?;
326                    let right_ty = self.infer_expr(right)?;
327                    if op == &BinaryOp::Assign {
328                        if !left_ty.is_any() && right_ty.is_any() { left_ty } else { right_ty }
329                    } else if op.is_assign() && !left_ty.is_any() && right_ty.is_any() {
330                        left_ty
331                    } else {
332                        left_ty + right_ty
333                    }
334                };
335                assign_idx.map(|idx| self.set_ty(idx, ty.clone()));
336                Ok(ty)
337            }
338            ExprKind::Call { obj, params } => {
339                if let ExprKind::AssocId { id, params: generic_args } = &obj.kind {
340                    let mut args = Vec::new();
341                    for p in params {
342                        args.push(self.infer_expr(p)?);
343                    }
344                    self.infer_fn_with_params(*id, &args, generic_args)
345                } else if let ExprKind::TypedMethod { obj: target, ty, name } = &obj.kind {
346                    let base_name = match ty {
347                        Type::Ident { name, .. } => name.clone(),
348                        Type::Symbol { id, .. } => self.symbols.get_symbol(*id)?.0.clone(),
349                        _ => return Ok(Type::Any),
350                    };
351                    let id = self.symbols.get_id(&format!("{}::{}", base_name, name))?;
352                    let mut args = vec![self.infer_expr(target)?];
353                    for p in params {
354                        args.push(self.infer_expr(p)?);
355                    }
356                    self.infer_fn(id, &args)
357                } else if let ExprKind::Id(id, obj_expr) = &obj.kind {
358                    let mut args: Vec<Type> = if let Some(obj) = obj_expr { vec![self.infer_expr(obj)?] } else { Vec::new() };
359                    for p in params {
360                        args.push(self.infer_expr(p)?);
361                    }
362                    self.infer_fn(*id, &args)
363                } else if let ExprKind::Ident(name) = &obj.kind {
364                    for idx in (self.top()..self.names.len()).rev() {
365                        if self.names[idx].eq(name) && idx < self.tys.len() {
366                            return if let Type::Symbol { id, .. } = &self.tys[idx] {
367                                let id = *id;
368                                let mut args = Vec::new();
369                                for p in params {
370                                    args.push(self.infer_expr(p)?);
371                                }
372                                self.infer_fn(id, &args)
373                            } else {
374                                Ok(Type::Any)
375                            };
376                        }
377                    }
378                    let Ok(id) = self.symbols.get_id(name) else {
379                        return Ok(Type::Any);
380                    };
381                    if !self.symbols.get_symbol(id)?.1.is_fn() {
382                        return Err(Self::semantic_error(obj.span, format!("符号 {} 不是函数", name)));
383                    }
384                    let mut args = Vec::new();
385                    for p in params {
386                        args.push(self.infer_expr(p)?);
387                    }
388                    self.infer_fn(id, &args)
389                } else if obj.is_idx() {
390                    let (target, _, method) = obj.clone().binary().unwrap();
391                    let ty = self.infer_expr(&target)?;
392                    if let Some(method) = self.get_value(&method) {
393                        let method = method.as_str();
394                        let fn_ty = match self.get_field(&ty, method) {
395                            Ok((_, fn_ty)) => fn_ty,
396                            Err(_) => {
397                                let id = self.symbols.get_id(method)?;
398                                if self.symbols.get_symbol(id)?.1.is_fn() {
399                                    Type::Symbol { id, params: Vec::new() }
400                                } else {
401                                    return Err(Self::semantic_error(obj.span, format!("符号 {method} 不是函数")));
402                                }
403                            }
404                        };
405                        if let Type::Symbol { id, .. } = fn_ty {
406                            let mut args = vec![ty];
407                            for p in params {
408                                args.push(self.infer_expr(p)?);
409                            }
410                            self.infer_fn(id, &args)
411                        } else {
412                            Ok(fn_ty)
413                        }
414                    } else {
415                        Ok(Type::Any)
416                    }
417                } else if let ExprKind::Var(idx) = &obj.kind {
418                    let idx = self.top() + (*idx as usize);
419                    if idx < self.tys.len()
420                        && let Type::Symbol { id, .. } = self.tys[idx]
421                    {
422                        let mut args = Vec::new();
423                        for p in params {
424                            args.push(self.infer_expr(p)?);
425                        }
426                        self.infer_fn(id, &args)
427                    } else {
428                        Ok(Type::Any)
429                    }
430                } else if obj.is_value() {
431                    Ok(Type::Void)
432                } else {
433                    Ok(Type::Any)
434                }
435            }
436            ExprKind::Typed { ty, .. } => self.symbols.get_type(ty),
437            ExprKind::Stmt(stmt) => self.infer_stmt(stmt),
438            ExprKind::Range { start, stop, .. } => {
439                let start_ty = self.infer_expr(start)?;
440                let stop_ty = self.infer_expr(stop)?;
441                Ok(if start_ty.is_any() {
442                    stop_ty
443                } else if stop_ty.is_any() {
444                    start_ty
445                } else {
446                    stop_ty
447                })
448            }
449            _ => Ok(Type::Any),
450        }
451    }
452
453    fn get_fn_tys(&mut self, tys: &[Type], arg_tys: &[Type]) -> Result<Vec<Type>> {
454        let mut fn_tys = Vec::new();
455        for (i, ty) in tys.iter().enumerate() {
456            if !ty.is_any() {
457                fn_tys.push(ty.clone());
458            } else if let Some(arg_ty) = arg_tys.get(i) {
459                fn_tys.push(self.symbols.get_type(arg_ty)?);
460            } else {
461                fn_tys.push(Type::Any);
462            }
463        }
464        Ok(fn_tys)
465    }
466
467    pub fn infer_fn(&mut self, id: u32, arg_tys: &[Type]) -> Result<Type> {
468        self.infer_fn_with_params(id, arg_tys, &[])
469    }
470
471    pub fn infer_fn_with_params(&mut self, id: u32, arg_tys: &[Type], generic_args: &[Type]) -> Result<Type> {
472        let (name, s) = self.symbols.get_symbol(id).map(|(n, s)| (n.clone(), s.clone()))?;
473        if let Symbol::Fn { ty, args, generic_params, cap, body, .. } = s {
474            if let Type::Fn { tys, ret: _ } = ty {
475                let inferred_generic_args = if generic_args.is_empty() { crate::infer_generic_args_from_types(&generic_params, &tys, arg_tys) } else { generic_args.to_vec() };
476                let generic_args = if generic_params.is_empty() { &[] } else { inferred_generic_args.as_slice() };
477                let tys = if generic_params.is_empty() { tys } else { tys.iter().map(|ty| crate::substitute_type(ty, &generic_params, generic_args)).collect() };
478                let body = if generic_params.is_empty() { body.as_ref().clone() } else { crate::substitute_stmt(body.as_ref(), &generic_params, generic_args) };
479                let fn_tys = self.get_fn_tys(&tys, arg_tys)?;
480                let body = if generic_params.is_empty() {
481                    body
482                } else {
483                    let mut compile_tys = tys.clone();
484                    let mut compile_cap = cap.clone();
485                    let saved_state = self.take_local_state();
486                    let compiled = self.compile_fn(&args, &mut compile_tys, body, &mut compile_cap);
487                    self.restore_local_state(saved_state);
488                    Stmt::new(StmtKind::Block(compiled?), Span::default())
489                };
490                if let Some(fns) = self.fns.get_mut(&id) {
491                    for f in fns.iter() {
492                        if f.0 == generic_args && f.1 == fn_tys {
493                            return match &f.2 {
494                                FnInferRet::Done(ret_ty) => self.symbols.get_type(ret_ty),
495                                FnInferRet::Pending(seed) => seed.as_ref().map(|ty| self.symbols.get_type(ty)).unwrap_or(Ok(Type::Any)),
496                            };
497                        }
498                    }
499                    fns.push((generic_args.to_vec(), fn_tys.clone(), FnInferRet::Pending(None)));
500                } else {
501                    self.fns.insert(id, vec![(generic_args.to_vec(), fn_tys.clone(), FnInferRet::Pending(None))]);
502                }
503                let mut ret_ty = None;
504                for _ in 0..4 {
505                    let before_seed = self.pending_return_seed(id, generic_args, &fn_tys);
506                    let saved_state = self.take_local_state();
507                    self.frames.push(0);
508                    for (arg, ty) in args.iter().zip(fn_tys.iter()) {
509                        self.add_name(arg.clone());
510                        self.add_ty(ty.clone());
511                    }
512                    for c in cap.vars.iter() {
513                        if let Some((name, ty)) = cap.names.get(*c) {
514                            self.add_name(name.clone());
515                            self.add_ty(ty.clone());
516                        } else {
517                            self.add_name("".into());
518                            self.add_ty(Type::Any);
519                        }
520                    }
521                    self.infer_stack.push((id, generic_args.to_vec(), fn_tys.clone()));
522                    let pass_ret_ty = self.infer_return_type(&body).map(|ty| ty.unwrap_or(Type::Void));
523                    self.infer_stack.pop();
524                    self.restore_local_state(saved_state);
525                    let pass_ret_ty = match pass_ret_ty {
526                        Ok(pass_ret_ty) => self.symbols.get_type(&pass_ret_ty).unwrap_or(pass_ret_ty),
527                        Err(err) => {
528                            log::error!("infer_fn {} failed: {:?}", name, err);
529                            let should_remove = self
530                                .fns
531                                .get_mut(&id)
532                                .map(|fns| {
533                                    fns.retain(|item| item.0 != generic_args || item.1 != fn_tys || !matches!(item.2, FnInferRet::Pending(_)));
534                                    fns.is_empty()
535                                })
536                                .unwrap_or(false);
537                            if should_remove {
538                                self.fns.remove(&id);
539                            }
540                            return Err(err);
541                        }
542                    };
543                    if !pass_ret_ty.is_any() {
544                        self.update_pending_return_seed(&pass_ret_ty);
545                        ret_ty = Some(pass_ret_ty.clone());
546                    } else if ret_ty.is_none() {
547                        ret_ty = Some(pass_ret_ty);
548                    }
549                    let after_seed = self.pending_return_seed(id, generic_args, &fn_tys);
550                    if before_seed == after_seed {
551                        break;
552                    }
553                }
554                let ret_ty = ret_ty.unwrap_or(Type::Any);
555                self.fns.get_mut(&id).map(|f| {
556                    f.iter_mut().find(|item| item.0 == generic_args && item.1 == fn_tys).map(|item| item.2 = FnInferRet::Done(ret_ty.clone()));
557                });
558                if generic_args.is_empty()
559                    && let Some((_, Symbol::Fn { ty: Type::Fn { ret, .. }, .. })) = self.symbols.get_symbol_mut(id)
560                    && ret.is_any()
561                {
562                    *ret = std::rc::Rc::new(ret_ty.clone());
563                }
564                Ok(ret_ty)
565            } else {
566                Ok(Type::Any)
567            }
568        } else if let Symbol::Native(f) = s {
569            if let Type::Fn { ret, .. } = f { Ok((*ret).clone()) } else { Ok(Type::Any) }
570        } else if matches!(s, Symbol::Null) {
571            Ok(Type::Any)
572        } else {
573            Err(Self::semantic_error(Span::default(), format!("符号 {:?} 不是函数", name)))
574        }
575    }
576
577    pub fn infer_stmt(&mut self, stmt: &Stmt) -> Result<Type> {
578        match &stmt.kind {
579            StmtKind::Expr(expr, close) => {
580                if !close {
581                    self.infer_expr(expr)
582                } else {
583                    self.infer_expr(expr)?;
584                    Ok(Type::Void)
585                }
586            }
587            StmtKind::Return(expr) => {
588                if let Some(e) = expr {
589                    self.infer_expr(e)
590                } else {
591                    Ok(Type::Void)
592                }
593            }
594            StmtKind::Block(stmts) => {
595                for (idx, stmt) in stmts.iter().enumerate() {
596                    let ty = self.infer_stmt(stmt)?;
597                    if stmt.is_return() || idx == stmts.len() - 1 {
598                        return Ok(ty);
599                    }
600                }
601                Ok(Type::Void)
602            }
603            StmtKind::If { then_body, else_body, .. } => {
604                let then_ty = self.infer_stmt(then_body)?;
605                if let Some(e) = else_body {
606                    let else_ty = self.infer_stmt(e)?;
607                    if then_ty != else_ty {
608                        log::info!("then 和 else 有不同类型 {:?} {:?}", then_ty, else_ty);
609                        return Ok(if then_ty.is_any() { else_ty } else { then_ty });
610                    }
611                }
612                if else_body.is_none() {
613                    return Ok(Type::Void);
614                }
615                Ok(then_ty)
616            }
617            StmtKind::While { cond, body } => {
618                let cond_ty = self.infer_expr(cond)?;
619                if cond_ty != Type::Bool {
620                    return Err(Self::semantic_error(cond.span, format!("条件表达式必须是布尔类型,实际是 {:?}", cond_ty)));
621                }
622                self.infer_stmt(body)
623            }
624            StmtKind::For { pat, range, body } => {
625                let ty = self.for_pattern_ty(range)?;
626                self.add_pattern_bindings_for_infer(pat, ty)?;
627                self.infer_stmt(body)
628            }
629            StmtKind::Let { pat, value } => {
630                let expr_ty = if let StmtKind::Expr(expr, _) = &value.kind { self.infer_expr(expr)? } else { self.infer_stmt(value)? };
631                self.add_pattern_bindings_for_infer(pat, expr_ty)?;
632                Ok(Type::Void)
633            }
634            _ => Ok(Type::Void),
635        }
636    }
637}