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
13const MAX_INFER_DEPTH: usize = 64;
18
19impl Compiler {
20 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 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 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 } 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 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 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 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 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}