stage1 支持tuple 修复悬垂指针问题

This commit is contained in:
zzy committed 2026-09-14 19:01:33 +08:00
1 parent a621e34d51
commit 3175e04e6e
2 files changed
+158 -58

No files matched your search

+50 -15
View File
@@ -361,7 +361,6 @@ static spl_lang_type_id_t sema_eval_decl(spl_sema_t *sema, spl_def_id_t def_id)
}
}
def->lang_id = result;
spl_def_node_t *final_def = spl_def_node(sema->type, def_id);
if (final_def) {
final_def->lang_id = result;
@@ -630,6 +629,28 @@ static spl_lang_type_id_t sema_check(spl_sema_t *sema, spl_ast_node_ref_t ref,
break; /* 非数组 expected:退回通用逻辑 */
}
case SPL_AST_EXPR_TUPLE: {
spl_lang_type_node_t *en = spl_lang_type_node(sema->type, expected);
if (en && en->kind == SPL_LANG_TYPE_TUPLE) {
usize nelems = vec_size(n->tuple.elems);
usize ntypes = vec_size(en->extra.elems);
if (nelems != ntypes) {
SPL_ERROR(&n->dbg, "tuple arity mismatch (expected %zu, got %zu)", ntypes, nelems);
sema->error_count++;
return 0;
}
for (usize i = 0; i < nelems; ++i) {
spl_lang_type_id_t et = vec_at(en->extra.elems, i);
if (!sema_check(sema, vec_at(n->tuple.elems, i), et))
return 0;
}
n->resolved_lang_tid = expected;
n->expected_lang_tid = 0;
return expected;
}
break;
}
case SPL_AST_EXPR_AGGREGATE_LIT: {
spl_lang_type_node_t *en = spl_lang_type_node(sema->type, expected);
if (!en || (en->kind != SPL_LANG_TYPE_STRUCT && en->kind != SPL_LANG_TYPE_UNION &&
@@ -710,8 +731,8 @@ static spl_lang_type_id_t sema_check(spl_sema_t *sema, spl_ast_node_ref_t ref,
continue;
}
seen[idx] = true;
spl_type_member_t *m = &vec_at(irn->agg_type.variants, idx);
spl_lang_type_id_t ft = sema_lang_from_ir(sema, m->type_id);
usize field_tid_ir = vec_at(irn->agg_type.variants, idx).type_id;
spl_lang_type_id_t ft = sema_lang_from_ir(sema, field_tid_ir);
if (!ft)
continue;
if (!item->struct_init_item.expr) {
@@ -1078,7 +1099,8 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
/* 固定参数:check 到形参类型 */
for (usize i = 0; i < nargs && i < fixed; ++i) {
spl_lang_type_id_t pt = vec_at(fn->extra.fn.params, i);
spl_lang_type_id_t pt =
vec_at(spl_lang_type_node(sema->type, callee_tid)->extra.fn.params, i);
sema_check(sema, vec_at(n->call.args, i), pt);
}
/* varargs:默认提升到 isize */
@@ -1131,11 +1153,11 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
}
for (usize i = 0; i < vec_size(agg->methods); ++i) {
spl_lang_method_t *meth = &vec_at(agg->methods, i);
if (strcmp(meth->name, n->field.field) != 0)
spl_lang_method_t meth = vec_at(agg->methods, i);
if (strcmp(meth.name, n->field.field) != 0)
continue;
n->resolved_def_id = meth->def_id;
spl_lang_type_id_t t = sema_eval_decl(sema, meth->def_id);
n->resolved_def_id = meth.def_id;
spl_lang_type_id_t t = sema_eval_decl(sema, meth.def_id);
n->resolved_lang_tid = t;
return t;
}
@@ -1160,10 +1182,22 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
case SPL_LANG_TYPE_PTR:
elem = obj->extra.elem;
break;
case SPL_LANG_TYPE_TUPLE:
if (vec_size(obj->extra.elems) > 0)
elem = vec_at(obj->extra.elems, 0);
case SPL_LANG_TYPE_TUPLE: {
spl_ast_node_t *idx_node = spl_ast_node(sema->ast, n->index.index);
if (!idx_node || idx_node->kind != SPL_AST_EXPR_INT_LIT) {
SPL_ERROR(&n->dbg, "tuple index must be an integer literal");
sema->error_count++;
return 0;
}
isize i = idx_node->int_lit.val;
if (i < 0 || (usize)i >= vec_size(obj->extra.elems)) {
SPL_ERROR(&n->dbg, "tuple index out of range");
sema->error_count++;
return 0;
}
elem = vec_at(obj->extra.elems, (usize)i);
break;
}
default:
SPL_ERROR(&n->dbg, "index base must be array/slice/ptr/range/tuple");
sema->error_count++;
@@ -1304,8 +1338,8 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
sema->error_count++;
continue;
}
spl_type_member_t *m = &vec_at(irn->agg_type.variants, idx);
spl_lang_type_id_t ft = sema_lang_from_ir(sema, m->type_id);
usize field_tid_ir = vec_at(irn->agg_type.variants, idx).type_id;
spl_lang_type_id_t ft = sema_lang_from_ir(sema, field_tid_ir);
if (ft && item->struct_init_item.expr)
sema_check(sema, item->struct_init_item.expr, ft);
}
@@ -1534,6 +1568,7 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
if (!def)
return 0;
spl_def_id_t owner_def_id = def->owner_def;
spl_lang_type_id_t fn_tid = def->lang_id;
if (fn_tid == 0)
fn_tid = sema_eval_decl(sema, n->resolved_def_id);
@@ -1546,8 +1581,8 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
return fn_tid;
spl_lang_type_id_t saved_agg = sema->current_aggregate_lang;
if (def->owner_def) {
spl_def_node_t *owner = spl_def_node(sema->type, def->owner_def);
if (owner_def_id) {
spl_def_node_t *owner = spl_def_node(sema->type, owner_def_id);
if (owner && owner->lang_id != 0)
sema->current_aggregate_lang = owner->lang_id;
}