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}