feat: if let 语句 — if let Option::Some = expr { ... }

This commit is contained in:
2026-06-06 15:20:34 +08:00
parent 0e1f8c5795
commit e02cc7b1d6
4 changed files with 98 additions and 39 deletions
+12 -11
View File
@@ -364,11 +364,6 @@ static void analyze_enum_variant(AstNode* node, Scope* scope, ErrorList* errors,
"枚举变体 payload 类型不匹配: 期望 '%s',得到 '%s'",
type_name(expected_pt), type_name(actual));
}
} else if (expected_pt != TYPE_VOID) {
error_add(errors, "<sema>", node->loc.line, node->loc.col,
"枚举变体 '%s::%s' 需要 payload 类型 '%s'",
node->as.enum_variant.enum_name, node->as.enum_variant.variant_name,
type_name(expected_pt));
}
node->type.kind = TYPE_ENUM;
}
@@ -630,15 +625,21 @@ static void analyze_node(AstNode* node, Scope* scope, ErrorList* errors, Arena*
for (size_t i = 0; i < node->as.block.stmt_count; i++) {
analyze_node(node->as.block.stmts[i], scope, errors, a);
}
// 表达式作为值: 块类型 = 最后一条表达式语句类型
// 表达式作为值: 块类型 = 最后一条产生值的语句类型
if (node->as.block.stmt_count > 0) {
AstNode* last = node->as.block.stmts[node->as.block.stmt_count - 1];
TypeKind ek = TYPE_VOID;
const char* esn = NULL;
if (last->kind == AST_EXPR_STMT) {
TypeKind ek = last->as.expr_stmt.expr->type.kind;
if (ek != TYPE_ERROR && ek != TYPE_VOID) {
node->type.kind = ek;
node->type.struct_name = last->as.expr_stmt.expr->type.struct_name;
}
ek = last->as.expr_stmt.expr->type.kind;
esn = last->as.expr_stmt.expr->type.struct_name;
} else if (last->kind == AST_IF_STMT && last->type.kind != TYPE_VOID) {
ek = last->type.kind;
esn = last->type.struct_name;
}
if (ek != TYPE_ERROR && ek != TYPE_VOID) {
node->type.kind = ek;
node->type.struct_name = esn;
}
}
break;