Skip to main content

compiler/
infer.rs

1use super::{Compiler, FnInferRet, ListElemState, Symbol};
2use anyhow::Result;
3use dynamic::{Dynamic, Type};
4use parser::{BinaryOp, Expr, ExprKind, Pattern, PatternKind, Span, Stmt, StmtKind, UnaryOp};
5use smol_str::SmolStr;
6
7#[derive(Clone)]
8struct ReturnInfo {
9    ty: Type,
10    shape: Option<Type>,
11}
12
13/// 类型推断递归链的硬上限。同一实例化由 `self.type_ctx.fns` 记忆化挡住,但互递归的泛型
14/// 函数每次可能产生新的 (generic_args, fn_tys) 实例化,记忆化命不中,会无限递归
15/// 直至栈溢出。超过此深度即把推断结果回退成 [`Type::Any`],把"挂起/崩溃"降级为
16/// 一个保守但安全的类型。正常代码的推断链远不及此。
17const MAX_INFER_DEPTH: usize = 64;
18
19impl Compiler {
20    /// 类型检查:算术/位/移位运算符两侧涉及 Str 或 Bool 时报错。
21    /// 设计依据:动态语义下,字符串与数值拼接合理 (`1 + "x"` = "1x"),
22    /// 但减/乘/除/位运算遇到字符串或布尔没有合理动态行为,运行时只会 panic。
23    /// `Add/AddAssign` 显式跳过 — 与 `Type::add` 一致允许字符串拼接。
24    /// 比较运算 (Eq/Ne/Lt/...) 也跳过 — dynamic 端已有任意类型比较语义。
25    fn check_arith_types(op: &BinaryOp, left_ty: &Type, right_ty: &Type, span: Span) -> Result<()> {
26        if !op.is_arith() || op.is_add() {
27            return Ok(());
28        }
29        let bad_left = matches!(left_ty, Type::Str | Type::Bool);
30        let bad_right = matches!(right_ty, Type::Str | Type::Bool);
31        if bad_left || bad_right {
32            let op_name = op.symbol();
33            return Err(Self::semantic_error(span, format!("运算符 {op_name} 不支持 Str/Bool 类型:左侧 {left_ty:?},右侧 {right_ty:?}")));
34        }
35        Ok(())
36    }
37
38    fn current_infer_key(&self) -> Option<(u32, Vec<Type>, Vec<Type>)> {
39        self.type_ctx.infer_stack.last().cloned()
40    }
41
42    fn pending_return_seed(&self, id: u32, generic_args: &[Type], fn_tys: &[Type]) -> Option<Type> {
43        self.type_ctx.fns.get(&id).and_then(|fns| {
44            fns.iter().find_map(|item| {
45                if item.0 == generic_args
46                    && item.1 == fn_tys
47                    && let FnInferRet::Pending(seed) = &item.2
48                {
49                    seed.clone()
50                } else {
51                    None
52                }
53            })
54        })
55    }
56
57    fn update_pending_return_seed(&mut self, ty: &Type) {
58        if ty.is_any() {
59            return;
60        }
61        let Some((id, generic_args, fn_tys)) = self.current_infer_key() else {
62            return;
63        };
64        let Some(fns) = self.type_ctx.fns.get_mut(&id) else {
65            return;
66        };
67        if let Some(item) = fns.iter_mut().find(|item| item.0 == generic_args && item.1 == fn_tys)
68            && let FnInferRet::Pending(seed) = &mut item.2
69        {
70            let next = seed.take().map(|prev| prev + ty.clone()).unwrap_or_else(|| ty.clone());
71            *seed = Some(next);
72        }
73    }
74
75    /// 扫描函数体,查找第一个非递归路径上的返回值类型(仅处理字面量)。
76    fn try_find_base_return_ty(&self, body: &Stmt) -> Option<Type> {
77        match &body.kind {
78            StmtKind::Block(stmts) => stmts.iter().find_map(|s| self.try_find_base_return_ty(s)),
79            StmtKind::If { then_body, else_body, .. } => self.try_find_base_return_ty(then_body).or_else(|| else_body.as_ref().and_then(|b| self.try_find_base_return_ty(b))),
80            StmtKind::Return(Some(expr)) => Self::try_literal_type(expr),
81            StmtKind::Expr(expr, false) => Self::try_literal_type(expr),
82            _ => None,
83        }
84    }
85
86    /// 带作用域的 base case 返回类型查找
87    fn try_find_base_return_ty_with_scope(&mut self, body: &Stmt, fn_id: u32, fn_name: &str, args: &[SmolStr], fn_tys: &[Type]) -> Option<Type> {
88        let saved_state = self.take_local_state();
89        self.sym_tab.frames.push(0);
90        for (arg, ty) in args.iter().zip(fn_tys.iter()) {
91            self.add_name(arg.clone());
92            self.add_ty(ty.clone());
93        }
94        let result = self.try_find_base_return_ty_with_scope_inner(body, fn_id, fn_name);
95        self.restore_local_state(saved_state);
96        result
97    }
98
99    fn try_find_base_return_ty_with_scope_inner(&mut self, body: &Stmt, fn_id: u32, fn_name: &str) -> Option<Type> {
100        match &body.kind {
101            StmtKind::Block(stmts) => stmts.iter().find_map(|s| self.try_find_base_return_ty_with_scope_inner(s, fn_id, fn_name)),
102            StmtKind::If { then_body, else_body, .. } => {
103                self.try_find_base_return_ty_with_scope_inner(then_body, fn_id, fn_name).or_else(|| else_body.as_ref().and_then(|b| self.try_find_base_return_ty_with_scope_inner(b, fn_id, fn_name)))
104            }
105            StmtKind::Return(Some(expr)) => {
106                if Self::expr_calls_fn(expr, fn_id, fn_name) {
107                    None
108                } else {
109                    self.infer_return_expr(expr).ok().map(|info| info.ty)
110                }
111            }
112            StmtKind::Expr(expr, false) => {
113                if Self::expr_calls_fn(expr, fn_id, fn_name) {
114                    None
115                } else {
116                    self.infer_return_expr(expr).ok().map(|info| info.ty)
117                }
118            }
119            _ => None,
120        }
121    }
122
123    fn expr_calls_fn(expr: &Expr, fn_id: u32, fn_name: &str) -> bool {
124        match &expr.kind {
125            ExprKind::Call { obj, params } => {
126                if let ExprKind::Id(id, _) = &obj.kind {
127                    return *id == fn_id;
128                }
129                if let ExprKind::Ident(name) = &obj.kind {
130                    if name.as_str() == fn_name || fn_name.ends_with(&format!("::{}", name)) {
131                        return true;
132                    }
133                }
134                params.iter().any(|p| Self::expr_calls_fn(p, fn_id, fn_name))
135            }
136            ExprKind::Binary { left, op: _, right } => Self::expr_calls_fn(left, fn_id, fn_name) || Self::expr_calls_fn(right, fn_id, fn_name),
137            ExprKind::Unary { op: _, value } => Self::expr_calls_fn(value, fn_id, fn_name),
138            ExprKind::Typed { value, ty: _ } => Self::expr_calls_fn(value, fn_id, fn_name),
139            _ => false,
140        }
141    }
142
143    fn try_literal_type(expr: &Expr) -> Option<Type> {
144        match &expr.kind {
145            ExprKind::Value(v) => Some(v.get_type()),
146            ExprKind::Unary { op: UnaryOp::Neg, value } => Self::try_literal_type(value),
147            _ => None,
148        }
149    }
150
151    fn add_pattern_bindings_for_infer(&mut self, pat: &Pattern, expr_ty: Type) -> Result<()> {
152        match &pat.kind {
153            PatternKind::Ident { name, ty } => {
154                let annotated_ty = self.sym_tab.symbols.get_type(ty)?;
155                self.add_name(name.clone());
156                self.add_ty(if annotated_ty.is_any() { expr_ty } else { annotated_ty });
157            }
158            PatternKind::Var { idx, .. } => self.set_ty(*idx, expr_ty),
159            PatternKind::Tuple(pats) => {
160                if let Type::Tuple(tys) = expr_ty {
161                    for (pat, ty) in pats.iter().zip(tys) {
162                        self.add_pattern_bindings_for_infer(pat, ty)?;
163                    }
164                } else {
165                    for pat in pats {
166                        self.add_pattern_bindings_for_infer(pat, Type::Any)?;
167                    }
168                }
169            }
170            PatternKind::List { elems, .. } => {
171                for pat in elems {
172                    self.add_pattern_bindings_for_infer(pat, Type::Any)?;
173                }
174            }
175            PatternKind::Wildcard => {
176                self.add_name("".into());
177                self.add_ty(expr_ty);
178            }
179            PatternKind::Literal(_) | PatternKind::Member(_, _) | PatternKind::Idx(_, _) | PatternKind::Struct { .. } => {}
180        }
181        Ok(())
182    }
183
184    fn for_pattern_ty(&mut self, range: &Expr) -> Result<Type> {
185        if matches!(range.kind, ExprKind::Range { .. }) {
186            return self.infer_range_expr(range);
187        }
188        Ok(match self.infer_expr(range)? {
189            Type::Array(elem_ty, _) | Type::Vec(elem_ty, _) | Type::List(elem_ty) => elem_ty.as_ref().clone(),
190            _ => Type::Any,
191        })
192    }
193
194    fn infer_range_expr(&mut self, range: &Expr) -> Result<Type> {
195        let ExprKind::Range { start, stop, .. } = &range.kind else {
196            return self.infer_expr(range);
197        };
198        let start_ty = self.infer_expr(start)?;
199        let stop_ty = self.infer_expr(stop)?;
200        Ok(Self::merge_range_bound_types(start_ty, stop_ty))
201    }
202
203    fn merge_range_bound_types(start_ty: Type, stop_ty: Type) -> Type {
204        if start_ty.is_any() {
205            stop_ty
206        } else if stop_ty.is_any() {
207            start_ty
208        // 无后缀整数字面量(默认 I32/I64)在 range 里向另一端的具体无符号类型靠拢,
209        // 这样 `0..n`(n: u32)仍是 u32 range,而不是被默认 I64 拖宽成 i64(会拆穿 GPU 后端)。
210        } else if matches!(start_ty, Type::I32 | Type::I64) && stop_ty.is_uint() {
211            stop_ty
212        } else if matches!(stop_ty, Type::I32 | Type::I64) && start_ty.is_uint() {
213            start_ty
214        } else {
215            start_ty + stop_ty
216        }
217    }
218
219    fn merge_return_type(span: Span, left: Option<Type>, right: Type) -> Result<Type> {
220        match left {
221            Some(left) if left == right => Ok(left),
222            Some(left) if left.is_void() || right.is_void() => Err(Self::semantic_error(span, format!("返回类型不一致: {:?} 和 {:?}", left, right))),
223            Some(left) if left.is_any() || right.is_any() => Ok(Type::Any),
224            Some(left) => Ok(left + right),
225            None => Ok(right),
226        }
227    }
228
229    fn return_shape(&self, expr: &Expr, ty: &Type) -> Option<Type> {
230        if !ty.is_any() {
231            return match ty {
232                Type::Struct { .. } => Some(ty.clone()),
233                Type::Map => Some(Type::Map),
234                Type::List(elem) | Type::Array(elem, _) => Some(Type::List(elem.clone())),
235                _ => None,
236            };
237        }
238        match &expr.kind {
239            ExprKind::List(_) | ExprKind::Tuple(_) => Some(Type::list_any()),
240            ExprKind::Dict(_) => Some(Type::Map),
241            ExprKind::Value(value) => Self::dynamic_return_shape(value.get_type()),
242            ExprKind::Const(idx) => self.sym_tab.consts.get_index(*idx).and_then(|(_, value)| Self::dynamic_return_shape(value.get_type())),
243            ExprKind::Typed { ty, .. } => Some(ty.clone()),
244            _ => None,
245        }
246    }
247
248    fn dynamic_return_shape(ty: Type) -> Option<Type> {
249        match ty {
250            Type::Map => Some(Type::Map),
251            Type::List(elem) => Some(Type::List(elem)),
252            Type::Array(elem, _) => Some(Type::List(elem)),
253            _ => None,
254        }
255    }
256
257    fn local_var_idx_for_expr(&self, expr: &Expr) -> Option<u32> {
258        match &expr.kind {
259            ExprKind::Var(idx) => Some(*idx),
260            ExprKind::Ident(name) => (self.top()..self.sym_tab.names.len()).rev().find(|idx| self.sym_tab.names[*idx].eq(name)).map(|idx| (idx - self.top()) as u32),
261            _ => None,
262        }
263    }
264
265    fn infer_list_method(&mut self, target: &Expr, elem_ty: &Type, method: &str, params: &[Expr]) -> Result<Option<Type>> {
266        match method {
267            "get_idx" | "pop" => Ok(Some(match self.local_var_idx_for_expr(target).and_then(|idx| self.list_elem_state(idx)) {
268                Some(ListElemState::Known(ty)) => ty,
269                Some(ListElemState::Unknown | ListElemState::Mixed) => Type::Any,
270                None => elem_ty.clone(),
271            })),
272            "push" => {
273                let pushed_ty = params
274                    .first()
275                    .map(|param| {
276                        if let Some(value) = self.get_value(param)
277                            && (value.is_str() || value.is_native())
278                        {
279                            Ok(value.get_type())
280                        } else {
281                            self.infer_expr(param)
282                        }
283                    })
284                    .transpose()?
285                    .unwrap_or(Type::Any);
286                if let Some(idx) = self.local_var_idx_for_expr(target) {
287                    let state = self.list_elem_state(idx).unwrap_or_else(|| if elem_ty.is_any() { ListElemState::Unknown } else { ListElemState::Known(elem_ty.clone()) });
288                    let next_state = match state {
289                        ListElemState::Unknown if pushed_ty.is_any() => ListElemState::Mixed,
290                        ListElemState::Unknown => ListElemState::Known(pushed_ty),
291                        ListElemState::Known(_) if pushed_ty.is_any() => ListElemState::Mixed,
292                        ListElemState::Known(prev) => {
293                            let merged = if prev == pushed_ty {
294                                prev
295                            } else if (prev.is_int() || prev.is_uint() || prev.is_float()) && (pushed_ty.is_int() || pushed_ty.is_uint() || pushed_ty.is_float()) {
296                                prev + pushed_ty
297                            } else {
298                                Type::Any
299                            };
300                            if merged.is_any() { ListElemState::Mixed } else { ListElemState::Known(merged) }
301                        }
302                        ListElemState::Mixed => ListElemState::Mixed,
303                    };
304                    let next_elem = if let ListElemState::Known(ty) = &next_state { ty.clone() } else { Type::Any };
305                    self.set_ty(idx, Type::List(std::rc::Rc::new(next_elem)));
306                    self.set_list_elem_state(idx, Some(next_state));
307                }
308                Ok(Some(Type::Void))
309            }
310            "len" => Ok(Some(Type::I32)),
311            "contains" | "is_list" | "is_null" => Ok(Some(Type::Bool)),
312            _ => Ok(None),
313        }
314    }
315
316    fn infer_return_expr(&mut self, expr: &Expr) -> Result<ReturnInfo> {
317        let ty = self.infer_expr(expr)?;
318        let shape = self.return_shape(expr, &ty);
319        let ty = if matches!(shape, Some(Type::Map | Type::List(_))) { Type::Any } else { ty };
320        Ok(ReturnInfo { ty, shape })
321    }
322
323    fn merge_return_info(span: Span, left: Option<ReturnInfo>, right: ReturnInfo) -> Result<ReturnInfo> {
324        let Some(left) = left else {
325            return Ok(right);
326        };
327        if let (Some(left_shape), Some(right_shape)) = (&left.shape, &right.shape)
328            && left_shape != right_shape
329        {
330            return Err(Self::semantic_error(span, format!("返回类型不一致: {:?} 和 {:?}", left_shape, right_shape)));
331        }
332        if let Some(left_shape) = &left.shape
333            && left_shape.is_struct()
334            && right.ty.is_any()
335            && right.shape.is_none()
336        {
337            return Err(Self::semantic_error(span, format!("返回类型不一致: {:?} 和 {:?}", left_shape, Type::Any)));
338        }
339        if let Some(right_shape) = &right.shape
340            && right_shape.is_struct()
341            && left.ty.is_any()
342            && left.shape.is_none()
343        {
344            return Err(Self::semantic_error(span, format!("返回类型不一致: {:?} 和 {:?}", Type::Any, right_shape)));
345        }
346        let ty = Self::merge_return_type(span, Some(left.ty), right.ty)?;
347        Ok(ReturnInfo { ty, shape: left.shape.or(right.shape) })
348    }
349
350    fn infer_return_type(&mut self, stmt: &Stmt) -> Result<Option<Type>> {
351        self.infer_returns(stmt, true).map(|(info, _)| info.map(|info| info.ty))
352    }
353
354    pub(crate) fn check_return_type(&mut self, stmt: &Stmt) -> Result<()> {
355        self.infer_returns(stmt, true).map(|_| ())
356    }
357
358    fn infer_returns(&mut self, stmt: &Stmt, tail: bool) -> Result<(Option<ReturnInfo>, bool)> {
359        match &stmt.kind {
360            StmtKind::Return(Some(expr)) => Ok((Some(self.infer_return_expr(expr)?), true)),
361            StmtKind::Return(None) => Ok((Some(ReturnInfo { ty: Type::Void, shape: Some(Type::Void) }), true)),
362            StmtKind::Block(stmts) => {
363                let mut ret = None;
364                for (idx, stmt) in stmts.iter().enumerate() {
365                    let (info, always_returns) = self.infer_returns(stmt, tail && idx == stmts.len().saturating_sub(1))?;
366                    if let Some(info) = info {
367                        self.update_pending_return_seed(&info.ty);
368                        ret = Some(Self::merge_return_info(stmt.span, ret, info)?);
369                        if let Some(ret) = &ret {
370                            self.update_pending_return_seed(&ret.ty);
371                        }
372                    }
373                    if always_returns {
374                        return Ok((ret, true));
375                    }
376                }
377                Ok((ret, false))
378            }
379            StmtKind::If { cond, then_body, else_body } => {
380                let cond_ty = self.infer_expr(cond)?;
381                if cond_ty != Type::Bool {
382                    return Err(Self::semantic_error(cond.span, format!("条件表达式必须是布尔类型,实际是 {:?}", cond_ty)));
383                }
384                let (mut ret, then_returns) = self.infer_returns(then_body, tail)?;
385                if let Some(ret) = &ret {
386                    self.update_pending_return_seed(&ret.ty);
387                }
388                let else_returns = if let Some(body) = else_body {
389                    let (else_ty, else_returns) = self.infer_returns(body, tail)?;
390                    if let Some(info) = else_ty {
391                        self.update_pending_return_seed(&info.ty);
392                        ret = Some(Self::merge_return_info(body.span, ret, info)?);
393                        if let Some(ret) = &ret {
394                            self.update_pending_return_seed(&ret.ty);
395                        }
396                    }
397                    else_returns
398                } else {
399                    false
400                };
401                Ok((ret, then_returns && else_returns))
402            }
403            StmtKind::While { cond, body } => {
404                let cond_ty = self.infer_expr(cond)?;
405                if cond_ty != Type::Bool {
406                    return Err(Self::semantic_error(cond.span, format!("条件表达式必须是布尔类型,实际是 {:?}", cond_ty)));
407                }
408                self.infer_returns(body, false).map(|(ty, _)| (ty, false))
409            }
410            StmtKind::Loop(body) => self.infer_returns(body, false),
411            StmtKind::For { pat, range, body } => {
412                let ty = self.for_pattern_ty(range)?;
413                self.add_pattern_bindings_for_infer(pat, ty)?;
414                self.infer_returns(body, false).map(|(ty, _)| (ty, false))
415            }
416            StmtKind::Let { .. } => {
417                self.infer_stmt(stmt)?;
418                Ok((None, false))
419            }
420            StmtKind::Expr(expr, close) => {
421                let info = self.infer_return_expr(expr)?;
422                Ok(if *close || !tail { (None, false) } else { (Some(info), true) })
423            }
424            _ => {
425                self.infer_stmt(stmt)?;
426                Ok((None, false))
427            }
428        }
429    }
430
431    pub fn infer_expr(&mut self, expr: &Expr) -> Result<Type> {
432        match &expr.kind {
433            ExprKind::Value(Dynamic::Null) => Ok(Type::Any),
434            ExprKind::Value(v) if v.is_list() => Ok(v.get_type()),
435            ExprKind::Value(v) if v.is_map() => Ok(Type::Any),
436            ExprKind::Value(v) => Ok(v.get_type()),
437            ExprKind::Const(idx) => Ok(match self.sym_tab.consts.get_index(*idx) {
438                Some((_, value)) if value.is_str() => Type::Str,
439                Some((_, value)) if value.is_list() && value.len() == 0 => Type::list_any(),
440                _ => Type::Any,
441            }),
442            ExprKind::Var(idx) => {
443                let idx = self.top() + (*idx as usize);
444                if idx < self.sym_tab.tys.len() { self.sym_tab.symbols.get_type(&self.sym_tab.tys[idx]) } else { Ok(Type::Any) }
445            }
446            ExprKind::Ident(ident) => {
447                for idx in (self.top()..self.sym_tab.names.len()).rev() {
448                    if self.sym_tab.names[idx].eq(ident) && idx < self.sym_tab.tys.len() {
449                        return self.sym_tab.symbols.get_type(&self.sym_tab.tys[idx]);
450                    }
451                }
452                let id = self.sym_tab.symbols.get_id(ident).map_err(|_| Self::semantic_error(expr.span, format!("未找到标识符 {}", ident)))?;
453                match self.sym_tab.symbols.get_symbol(id)?.1 {
454                    Symbol::Const { ty, .. } => Ok(ty.clone()),
455                    Symbol::Static { ty, .. } => Ok(ty.clone()),
456                    Symbol::Struct(ty, _) => Ok(ty.clone()),
457                    Symbol::Fn { .. } => Ok(Type::Symbol { id, params: Vec::new() }),
458                    Symbol::Native(ty) => Ok(ty.clone()),
459                    s => Err(Self::semantic_error(expr.span, format!("符号 {:?} 不是变量、常量、静态变量、结构体", s))),
460                }
461            }
462            ExprKind::Id(id, _) => match self.sym_tab.symbols.get_symbol(*id)?.1 {
463                Symbol::Const { ty, .. } => Ok(ty.clone()),
464                Symbol::Static { ty, .. } => Ok(ty.clone()),
465                Symbol::Struct(ty, _) => Ok(ty.clone()),
466                Symbol::Fn { .. } => Ok(Type::Symbol { id: *id, params: Vec::new() }),
467                Symbol::Native(ty) => Ok(ty.clone()),
468                s => Err(Self::semantic_error(expr.span, format!("符号 {:?} 不是变量、常量、静态变量、结构体", s))),
469            },
470            ExprKind::Generic { obj, params } => {
471                let params = params.iter().map(|param| self.sym_tab.symbols.get_type(param).unwrap_or_else(|_| param.clone())).collect();
472                match self.infer_expr(obj)? {
473                    Type::Symbol { id, .. } => Ok(Type::Symbol { id, params }),
474                    _ => Ok(Type::Any),
475                }
476            }
477            ExprKind::AssocId { id, params } => Ok(Type::Symbol { id: *id, params: params.clone() }),
478            ExprKind::Unary { op, value } => match op {
479                UnaryOp::Not => {
480                    let ty = self.infer_expr(value.as_ref())?;
481                    if ty.is_int() || ty.is_uint() { Ok(ty) } else { Ok(Type::Bool) }
482                }
483                UnaryOp::Neg => self.infer_expr(value.as_ref()),
484                UnaryOp::Unknow => Ok(Type::Any),
485            },
486            ExprKind::Binary { left, op, right } => {
487                if op == &BinaryOp::Assign
488                    && let ExprKind::Tuple(left_items) | ExprKind::List(left_items) = &left.kind
489                {
490                    if let ExprKind::Tuple(right_items) | ExprKind::List(right_items) = &right.kind {
491                        if left_items.len() != right_items.len() {
492                            return Err(Self::semantic_error(expr.span, format!("多重赋值数量不匹配: 左侧 {} 个,右侧 {} 个", left_items.len(), right_items.len())));
493                        }
494                        for item in right_items {
495                            let _ = self.infer_expr(item)?;
496                        }
497                    } else {
498                        let _ = self.infer_expr(right)?;
499                    }
500                    return Ok(Type::Void);
501                }
502                let assign_idx = if op.is_assign() { if let ExprKind::Var(idx) = &left.kind { Some(*idx) } else { None } } else { None };
503                let ty = if op.is_logic() {
504                    Type::Bool
505                } else if op == &BinaryOp::Idx {
506                    let left_ty = self.infer_expr(left)?;
507                    if matches!(right.kind, ExprKind::Range { .. }) {
508                        // 切片 `arr[a..b]` 仍产生同元素类型的 list,
509                        // 长度未定所以固定返回 `Type::List(elem)`。
510                        let elem_ty = match &left_ty {
511                            Type::Array(e, _) | Type::Vec(e, _) | Type::List(e) => (**e).clone(),
512                            _ => Type::Any,
513                        };
514                        return Ok(Type::List(std::rc::Rc::new(elem_ty)));
515                    }
516                    if let Type::Array(elem_ty, _) = left_ty {
517                        (*elem_ty).clone()
518                    } else if let Type::Vec(elem_ty, _) = left_ty {
519                        (*elem_ty).clone()
520                    } else if let Type::List(elem_ty) = left_ty {
521                        (*elem_ty).clone()
522                    } else {
523                        let left_ty = self.sym_tab.symbols.get_type(&left_ty)?;
524                        let right_ty = if right.is_value() || right.is_const() {
525                            let right_value = if let ExprKind::Const(c) = &right.kind {
526                                match self.sym_tab.consts.get_index(*c) {
527                                    Some((_, v)) => v.clone(),
528                                    None => right.clone().value()?,
529                                }
530                            } else {
531                                right.clone().value()?
532                            };
533                            if right_value.is_str() {
534                                if left_ty.is_any() {
535                                    return Ok(Type::Any);
536                                }
537                                if let Ok(field) = self.sym_tab.symbols.get_field(&left_ty, right_value.as_str()) {
538                                    return if let Type::Fn { ret, .. } = field.1 { Ok(ret.as_ref().clone()) } else { Ok(field.1.clone()) };
539                                }
540                            } else if let Type::Struct { fields, .. } = &left_ty
541                                && let Some(idx) = right_value.as_int()
542                            {
543                                return fields.get(idx as usize).map(|(_, ty)| ty.clone()).ok_or_else(|| Self::semantic_error(right.span, format!("结构字段索引越界 {}", idx)));
544                            }
545                            right_value.get_type()
546                        } else {
547                            self.infer_expr(right)?
548                        };
549                        if right_ty.is_int() || right_ty.is_uint() {
550                            if left_ty.is_any() {
551                                return Ok(Type::Any);
552                            }
553                            let (_, s) = self.sym_tab.symbols.get_field(&left_ty, "get_idx")?;
554                            let fn_ty = self.sym_tab.symbols.get_type(&s)?;
555                            return if let Type::Fn { ret, .. } = &fn_ty { Ok(ret.as_ref().clone()) } else { Ok(fn_ty) };
556                        }
557                        if left_ty.is_any() {
558                            return Ok(Type::Any);
559                        }
560                        Type::Any
561                    }
562                } else {
563                    let left_ty = self.infer_expr(left)?;
564                    let right_ty = self.infer_expr(right)?;
565                    Self::check_arith_types(op, &left_ty, &right_ty, expr.span)?;
566                    if op == &BinaryOp::Assign {
567                        if !left_ty.is_any() && right_ty.is_any() { left_ty } else { right_ty }
568                    } else if op.is_assign() && !left_ty.is_any() && right_ty.is_any() {
569                        left_ty
570                    } else {
571                        left_ty + right_ty
572                    }
573                };
574                assign_idx.map(|idx| self.set_ty(idx, ty.clone()));
575                Ok(ty)
576            }
577            ExprKind::Call { obj, params } => {
578                if let ExprKind::Assoc { ty, name } = &obj.kind {
579                    let base_name = match ty {
580                        Type::Ident { name, .. } => name.clone(),
581                        Type::Symbol { id, .. } => self.sym_tab.symbols.get_symbol(*id)?.0.clone(),
582                        _ => return Ok(Type::Any),
583                    };
584                    let id = self.sym_tab.symbols.get_id(&format!("{}::{}", base_name, name))?;
585                    let generic_args = match ty {
586                        Type::Ident { params, .. } | Type::Symbol { params, .. } => params.iter().map(|param| self.sym_tab.symbols.get_type(param).unwrap_or_else(|_| param.clone())).collect::<Vec<_>>(),
587                        _ => Vec::new(),
588                    };
589                    let mut args = Vec::new();
590                    for p in params {
591                        args.push(self.infer_expr(p)?);
592                    }
593                    self.infer_fn_with_params(id, &args, &generic_args)
594                } else if let ExprKind::AssocId { id, params: generic_args } = &obj.kind {
595                    let mut args = Vec::new();
596                    for p in params {
597                        args.push(self.infer_expr(p)?);
598                    }
599                    self.infer_fn_with_params(*id, &args, generic_args)
600                } else if let ExprKind::Generic { obj, params: generic_args } = &obj.kind {
601                    let Type::Symbol { id, .. } = self.infer_expr(obj)? else {
602                        return Ok(Type::Any);
603                    };
604                    let generic_args = generic_args.iter().map(|param| self.sym_tab.symbols.get_type(param).unwrap_or_else(|_| param.clone())).collect::<Vec<_>>();
605                    let mut args = Vec::new();
606                    for p in params {
607                        args.push(self.infer_expr(p)?);
608                    }
609                    self.infer_fn_with_params(id, &args, &generic_args)
610                } else if let ExprKind::TypedMethod { obj: target, ty, name } = &obj.kind {
611                    let base_name = match ty {
612                        Type::Ident { name, .. } => name.clone(),
613                        Type::Symbol { id, .. } => self.sym_tab.symbols.get_symbol(*id)?.0.clone(),
614                        _ => return Ok(Type::Any),
615                    };
616                    let id = self.sym_tab.symbols.get_id(&format!("{}::{}", base_name, name))?;
617                    let mut args = vec![self.infer_expr(target)?];
618                    for p in params {
619                        args.push(self.infer_expr(p)?);
620                    }
621                    self.infer_fn(id, &args)
622                } else if let ExprKind::Id(id, obj_expr) = &obj.kind {
623                    let method = self.sym_tab.symbols.get_symbol(*id).ok().and_then(|(name, _)| name.rsplit_once("::").map(|(_, method)| method.to_string()));
624                    if let Some(target) = obj_expr
625                        && let Some(method) = method
626                    {
627                        let target_ty = self.infer_expr(target)?;
628                        if let Type::List(elem_ty) | Type::Array(elem_ty, _) = &target_ty
629                            && let Some(ret_ty) = self.infer_list_method(target, elem_ty, method.as_str(), params)?
630                        {
631                            return Ok(ret_ty);
632                        }
633                    }
634                    let mut args: Vec<Type> = if let Some(obj) = obj_expr { vec![self.infer_expr(obj)?] } else { Vec::new() };
635                    for p in params {
636                        args.push(self.infer_expr(p)?);
637                    }
638                    self.infer_fn(*id, &args)
639                } else if let ExprKind::Ident(name) = &obj.kind {
640                    for idx in (self.top()..self.sym_tab.names.len()).rev() {
641                        if self.sym_tab.names[idx].eq(name) && idx < self.sym_tab.tys.len() {
642                            return if let Type::Symbol { id, .. } = &self.sym_tab.tys[idx] {
643                                let id = *id;
644                                let mut args = Vec::new();
645                                for p in params {
646                                    args.push(self.infer_expr(p)?);
647                                }
648                                self.infer_fn(id, &args)
649                            } else {
650                                Ok(Type::Any)
651                            };
652                        }
653                    }
654                    let Ok(id) = self.sym_tab.symbols.get_id(name) else {
655                        return Ok(Type::Any);
656                    };
657                    if !self.sym_tab.symbols.get_symbol(id)?.1.is_fn() {
658                        return Err(Self::semantic_error(obj.span, format!("符号 {} 不是函数", name)));
659                    }
660                    let mut args = Vec::new();
661                    for p in params {
662                        args.push(self.infer_expr(p)?);
663                    }
664                    self.infer_fn(id, &args)
665                } else if obj.is_idx() {
666                    let (target, _, method) = obj.clone().binary().unwrap();
667                    let ty = self.infer_expr(&target)?;
668                    if let Some(method) = self.get_value(&method) {
669                        let method = method.as_str();
670                        if let Type::List(elem_ty) | Type::Array(elem_ty, _) = &ty
671                            && let Some(ret_ty) = self.infer_list_method(&target, elem_ty, method, params)?
672                        {
673                            return Ok(ret_ty);
674                        }
675                        let fn_ty = match self.get_field(&ty, method) {
676                            Ok((_, fn_ty)) => fn_ty,
677                            Err(_) => {
678                                let id = self.sym_tab.symbols.get_id(method)?;
679                                if self.sym_tab.symbols.get_symbol(id)?.1.is_fn() {
680                                    Type::Symbol { id, params: Vec::new() }
681                                } else {
682                                    return Err(Self::semantic_error(obj.span, format!("符号 {method} 不是函数")));
683                                }
684                            }
685                        };
686                        if let Type::Symbol { id, .. } = fn_ty {
687                            let mut args = vec![ty];
688                            for p in params {
689                                args.push(self.infer_expr(p)?);
690                            }
691                            self.infer_fn(id, &args)
692                        } else {
693                            Ok(fn_ty)
694                        }
695                    } else {
696                        Ok(Type::Any)
697                    }
698                } else if let ExprKind::Var(idx) = &obj.kind {
699                    let idx = self.top() + (*idx as usize);
700                    if idx < self.sym_tab.tys.len()
701                        && let Type::Symbol { id, .. } = self.sym_tab.tys[idx]
702                    {
703                        let mut args = Vec::new();
704                        for p in params {
705                            args.push(self.infer_expr(p)?);
706                        }
707                        self.infer_fn(id, &args)
708                    } else {
709                        Ok(Type::Any)
710                    }
711                } else if obj.is_value() {
712                    Ok(Type::Void)
713                } else {
714                    Ok(Type::Any)
715                }
716            }
717            ExprKind::Typed { ty, .. } => self.sym_tab.symbols.get_type(ty),
718            ExprKind::Stmt(stmt) => self.infer_stmt(stmt),
719            ExprKind::Repeat { value, len } => {
720                let value_ty = self.infer_expr(value)?;
721                let len = self.sym_tab.symbols.get_type(len).unwrap_or_else(|_| len.clone());
722                if let Type::ConstInt(len) = len {
723                    let len = u32::try_from(len).map_err(|_| Self::semantic_error(expr.span, "重复数组长度必须是非负 u32"))?;
724                    Ok(Type::Array(std::rc::Rc::new(value_ty), len))
725                } else {
726                    Ok(Type::ArrayParam(std::rc::Rc::new(value_ty), std::rc::Rc::new(len)))
727                }
728            }
729            ExprKind::List(items) => {
730                if items.is_empty() {
731                    return Ok(Type::list_any());
732                }
733                let mut elem_ty = Type::Any;
734                for item in items {
735                    let item_ty = self.infer_expr(item)?;
736                    elem_ty = if elem_ty.is_any() { item_ty } else { elem_ty + item_ty };
737                }
738                Ok(Type::Array(std::rc::Rc::new(elem_ty), items.len() as u32))
739            }
740            ExprKind::Range { start, stop, .. } => {
741                let start_ty = self.infer_expr(start)?;
742                let stop_ty = self.infer_expr(stop)?;
743                Ok(Self::merge_range_bound_types(start_ty, stop_ty))
744            }
745            _ => Ok(Type::Any),
746        }
747    }
748
749    fn get_fn_tys(&mut self, tys: &[Type], arg_tys: &[Type]) -> Result<Vec<Type>> {
750        let mut fn_tys = Vec::new();
751        for (i, ty) in tys.iter().enumerate() {
752            if !ty.is_any() {
753                fn_tys.push(ty.clone());
754            } else if let Some(arg_ty) = arg_tys.get(i) {
755                fn_tys.push(self.sym_tab.symbols.get_type(arg_ty)?);
756            } else {
757                fn_tys.push(Type::Any);
758            }
759        }
760        Ok(fn_tys)
761    }
762
763    fn is_optimizable_local_ty(ty: &Type) -> bool {
764        ty.is_bool() || ty.is_native()
765    }
766
767    fn is_optimizable_list_elem_ty(ty: &Type) -> bool {
768        matches!(ty, Type::Bool | Type::U8 | Type::I8 | Type::U16 | Type::I16 | Type::U32 | Type::I32 | Type::F32 | Type::U64 | Type::I64 | Type::F64 | Type::Str)
769    }
770
771    fn local_type_hint_at(&self, pos: usize) -> Option<Type> {
772        let ty = self.sym_tab.tys.get(pos)?;
773        match ty {
774            Type::List(_) => self.type_ctx.list_elem_states.get(pos).cloned().flatten().and_then(|state| {
775                if let ListElemState::Known(elem_ty) = state
776                    && Self::is_optimizable_list_elem_ty(&elem_ty)
777                {
778                    Some(Type::List(std::rc::Rc::new(elem_ty)))
779                } else {
780                    None
781                }
782            }),
783            ty if Self::is_optimizable_local_ty(ty) => Some(ty.clone()),
784            _ => None,
785        }
786    }
787
788    fn collect_local_type_hints(&self) -> Vec<Option<Type>> {
789        (self.top()..self.sym_tab.tys.len()).map(|pos| self.local_type_hint_at(pos)).collect()
790    }
791
792    fn set_local_type_hints(&mut self, id: u32, generic_args: &[Type], fn_tys: &[Type], hints: Vec<Option<Type>>) {
793        let items = self.type_ctx.local_type_hints.entry(id).or_default();
794        if let Some(item) = items.iter_mut().find(|item| item.0 == generic_args && item.1 == fn_tys) {
795            item.2 = hints;
796        } else {
797            items.push((generic_args.to_vec(), fn_tys.to_vec(), hints));
798        }
799    }
800
801    pub fn inferred_local_type_hints(&self, id: u32, generic_args: &[Type], fn_tys: &[Type]) -> Vec<Option<Type>> {
802        self.type_ctx.local_type_hints.get(&id).and_then(|items| items.iter().find(|item| item.0 == generic_args && item.1 == fn_tys)).map(|item| item.2.clone()).unwrap_or_default()
803    }
804
805    pub fn infer_fn(&mut self, id: u32, arg_tys: &[Type]) -> Result<Type> {
806        self.infer_fn_with_params(id, arg_tys, &[])
807    }
808
809    pub fn infer_fn_with_params(&mut self, id: u32, arg_tys: &[Type], generic_args: &[Type]) -> Result<Type> {
810        // 病态(互)递归泛型推断会不断产生新实例化、绕过记忆化;到达深度上限即回退 Any,
811        // 避免推断阶段栈溢出崩溃。
812        if self.type_ctx.infer_stack.len() > MAX_INFER_DEPTH {
813            return Ok(Type::Any);
814        }
815        let (name, s) = self.sym_tab.symbols.get_symbol(id).map(|(n, s)| (n.clone(), s.clone()))?;
816        if let Symbol::Fn { ty, args, generic_params, cap, body, .. } = s {
817            if let Type::Fn { tys, ret: _ } = ty {
818                let resolved_generic_args = crate::resolve_generic_args_from_types(&generic_params, &tys, arg_tys, generic_args)?;
819                let generic_args = resolved_generic_args.as_slice();
820                let tys = if generic_params.is_empty() { tys } else { tys.iter().map(|ty| crate::substitute_type(ty, &generic_params, generic_args)).collect() };
821                let body = if generic_params.is_empty() { body.as_ref().clone() } else { crate::substitute_stmt(body.as_ref(), &generic_params, generic_args) };
822                let fn_tys = self.get_fn_tys(&tys, arg_tys)?;
823                let body = if generic_params.is_empty() {
824                    body
825                } else {
826                    let mut compile_tys = tys.clone();
827                    let mut compile_cap = cap.clone();
828                    let saved_state = self.take_local_state();
829                    if let Some((module, _)) = name.split_once("::") {
830                        self.sym_tab.symbols.push_module_scope(module.into());
831                    }
832                    let compiled = self.compile_fn(&args, &mut compile_tys, body, &mut compile_cap);
833                    if name.contains("::") {
834                        self.sym_tab.symbols.pop_module_scope();
835                    }
836                    self.restore_local_state(saved_state);
837                    Stmt::new(StmtKind::Block(compiled?), Span::default())
838                };
839                if let Some(fns) = self.type_ctx.fns.get_mut(&id) {
840                    for f in fns.iter() {
841                        if f.0 == generic_args && f.1 == fn_tys {
842                            return match &f.2 {
843                                FnInferRet::Done(ret_ty) => self.sym_tab.symbols.get_type(ret_ty),
844                                FnInferRet::Pending(seed) => seed.as_ref().map(|ty| self.sym_tab.symbols.get_type(ty)).unwrap_or_else(|| {
845                                    // 递归自调用且种子为空:尝试从函数体 base case 查找返回类型
846                                    if self.type_ctx.infer_stack.iter().any(|(sid, sargs, _)| *sid == id && sargs == generic_args) {
847                                        if let Some(base_ty) = self.try_find_base_return_ty(&body) {
848                                            return self.sym_tab.symbols.get_type(&base_ty);
849                                        }
850                                    }
851                                    Ok(Type::Any)
852                                }),
853                            };
854                        }
855                    }
856                    fns.push((generic_args.to_vec(), fn_tys.clone(), FnInferRet::Pending(None)));
857                } else {
858                    self.type_ctx.fns.insert(id, vec![(generic_args.to_vec(), fn_tys.clone(), FnInferRet::Pending(None))]);
859                }
860                // 递归函数:预扫描 base case 返回类型作为种子
861                if self.pending_return_seed(id, generic_args, &fn_tys).is_none() {
862                    if let Some(base_ty) = self.try_find_base_return_ty_with_scope(&body, id, &name, &args, &fn_tys) {
863                        if let Some(fns) = self.type_ctx.fns.get_mut(&id) {
864                            if let Some(item) = fns.iter_mut().find(|item| item.0 == generic_args && item.1 == fn_tys)
865                                && let FnInferRet::Pending(seed) = &mut item.2
866                                && seed.is_none()
867                            {
868                                *seed = Some(base_ty);
869                            }
870                        }
871                    }
872                }
873                let mut ret_ty = None;
874                let mut local_type_hints = Vec::new();
875                for _ in 0..4 {
876                    let before_seed = self.pending_return_seed(id, generic_args, &fn_tys);
877                    let saved_state = self.take_local_state();
878                    self.sym_tab.frames.push(0);
879                    for (arg, ty) in args.iter().zip(fn_tys.iter()) {
880                        self.add_name(arg.clone());
881                        self.add_ty(ty.clone());
882                    }
883                    for c in cap.vars.iter() {
884                        if let Some((name, ty)) = cap.names.get(*c) {
885                            self.add_name(name.clone());
886                            self.add_ty(ty.clone());
887                        } else {
888                            self.add_name("".into());
889                            self.add_ty(Type::Any);
890                        }
891                    }
892                    self.type_ctx.infer_stack.push((id, generic_args.to_vec(), fn_tys.clone()));
893                    let pass_ret_ty = self.infer_return_type(&body).map(|ty| ty.unwrap_or(Type::Void));
894                    self.type_ctx.infer_stack.pop();
895                    let pass_local_type_hints = self.collect_local_type_hints();
896                    self.restore_local_state(saved_state);
897                    let pass_ret_ty = match pass_ret_ty {
898                        Ok(pass_ret_ty) => self.sym_tab.symbols.get_type(&pass_ret_ty).unwrap_or(pass_ret_ty),
899                        Err(err) => {
900                            log::error!("infer_fn {} failed: {:?}", name, err);
901                            let should_remove = self
902                                .type_ctx
903                                .fns
904                                .get_mut(&id)
905                                .map(|fns| {
906                                    fns.retain(|item| item.0 != generic_args || item.1 != fn_tys || !matches!(item.2, FnInferRet::Pending(_)));
907                                    fns.is_empty()
908                                })
909                                .unwrap_or(false);
910                            if should_remove {
911                                self.type_ctx.fns.remove(&id);
912                            }
913                            return Err(err);
914                        }
915                    };
916                    if !pass_ret_ty.is_any() {
917                        self.update_pending_return_seed(&pass_ret_ty);
918                        ret_ty = Some(pass_ret_ty.clone());
919                    } else if ret_ty.is_none() {
920                        ret_ty = Some(pass_ret_ty);
921                    }
922                    local_type_hints = pass_local_type_hints;
923                    let after_seed = self.pending_return_seed(id, generic_args, &fn_tys);
924                    if before_seed == after_seed {
925                        break;
926                    }
927                }
928                let ret_ty = ret_ty.unwrap_or(Type::Any);
929                self.type_ctx.fns.get_mut(&id).map(|f| {
930                    f.iter_mut().find(|item| item.0 == generic_args && item.1 == fn_tys).map(|item| item.2 = FnInferRet::Done(ret_ty.clone()));
931                });
932                self.set_local_type_hints(id, generic_args, &fn_tys, local_type_hints);
933                if generic_args.is_empty()
934                    && let Some((_, Symbol::Fn { ty: Type::Fn { ret, .. }, .. })) = self.sym_tab.symbols.get_symbol_mut(id)
935                    && ret.is_any()
936                {
937                    *ret = std::rc::Rc::new(ret_ty.clone());
938                }
939                Ok(ret_ty)
940            } else {
941                Ok(Type::Any)
942            }
943        } else if let Symbol::Native(f) = s {
944            if let Type::Fn { ret, .. } = f { Ok((*ret).clone()) } else { Ok(Type::Any) }
945        } else if matches!(s, Symbol::Null) {
946            Ok(Type::Any)
947        } else {
948            Err(Self::semantic_error(Span::default(), format!("符号 {:?} 不是函数", name)))
949        }
950    }
951
952    pub fn infer_stmt(&mut self, stmt: &Stmt) -> Result<Type> {
953        match &stmt.kind {
954            StmtKind::Expr(expr, close) => {
955                if !close {
956                    self.infer_expr(expr)
957                } else {
958                    self.infer_expr(expr)?;
959                    Ok(Type::Void)
960                }
961            }
962            StmtKind::Return(expr) => {
963                if let Some(e) = expr {
964                    self.infer_expr(e)
965                } else {
966                    Ok(Type::Void)
967                }
968            }
969            StmtKind::Block(stmts) => {
970                for (idx, stmt) in stmts.iter().enumerate() {
971                    let ty = self.infer_stmt(stmt)?;
972                    if stmt.is_return() || idx == stmts.len() - 1 {
973                        return Ok(ty);
974                    }
975                }
976                Ok(Type::Void)
977            }
978            StmtKind::If { then_body, else_body, .. } => {
979                let then_ty = self.infer_stmt(then_body)?;
980                if let Some(e) = else_body {
981                    let else_ty = self.infer_stmt(e)?;
982                    if then_ty != else_ty {
983                        log::debug!("then 和 else 有不同类型 {:?} {:?}", then_ty, else_ty);
984                        return Self::merge_return_type(stmt.span, Some(then_ty), else_ty);
985                    }
986                }
987                if else_body.is_none() {
988                    return Ok(Type::Void);
989                }
990                Ok(then_ty)
991            }
992            StmtKind::While { cond, body } => {
993                let cond_ty = self.infer_expr(cond)?;
994                if cond_ty != Type::Bool {
995                    return Err(Self::semantic_error(cond.span, format!("条件表达式必须是布尔类型,实际是 {:?}", cond_ty)));
996                }
997                self.infer_stmt(body)
998            }
999            StmtKind::For { pat, range, body } => {
1000                let ty = self.for_pattern_ty(range)?;
1001                self.add_pattern_bindings_for_infer(pat, ty)?;
1002                self.infer_stmt(body)
1003            }
1004            StmtKind::Let { pat, value } => {
1005                let expr_ty = if let StmtKind::Expr(expr, _) = &value.kind { self.infer_expr(expr)? } else { self.infer_stmt(value)? };
1006                self.add_pattern_bindings_for_infer(pat, expr_ty)?;
1007                Ok(Type::Void)
1008            }
1009            _ => Ok(Type::Void),
1010        }
1011    }
1012}