stage2 修复语义问题
This commit is contained in:
1 parent
76f980654c
commit
fc2d8f8db4
2 files changed
+74
-28
No files matched your search
+36
-16
@@ -302,27 +302,23 @@ static spl_lang_type_id_t sema_build_aggregate(spl_sema_t *sema, spl_ast_node_t
|
||||
|
||||
spl_lang_type_id_t saved_agg = sema->current_aggregate_lang;
|
||||
sema->current_aggregate_lang = agg_lang;
|
||||
/* 聚合体自成命名空间:成员类型可引用同体声明的嵌套类型(裸名)。 */
|
||||
sema_push_scope(sema);
|
||||
|
||||
spl_type_member_vec_t members;
|
||||
vec_init(members);
|
||||
spl_lang_method_vec_t methods;
|
||||
vec_init(methods);
|
||||
|
||||
/* 第一遍:登记嵌套类型/函数的 def,挂进 methods 与聚合作用域。成员类型可能引用它们,
|
||||
必须早于成员类型推断,否则限定名(经 methods)与裸名(经作用域)都解析不到。 */
|
||||
for (usize i = 0; i < vec_size(te->type_aggregate.members); ++i) {
|
||||
spl_ast_node_ref_t mref = vec_at(te->type_aggregate.members, i);
|
||||
spl_ast_node_t *mn = spl_ast_node(sema->ast, mref);
|
||||
if (!mn)
|
||||
continue;
|
||||
|
||||
if (mn->kind == SPL_AST_MEMBER_DECL) {
|
||||
spl_lang_type_id_t mtid = 0;
|
||||
if (mn->member_decl.type_expr)
|
||||
mtid = sema_infer(sema, mn->member_decl.type_expr);
|
||||
spl_type_member_t m = {.name = mn->member_decl.name,
|
||||
.type_id = spl_lang_type_get_ir_type(sema->type, mtid),
|
||||
.ast_node_ref = mref};
|
||||
vec_push(members, m);
|
||||
} else if (mn->kind == SPL_AST_FN_DECL) {
|
||||
if (mn->kind == SPL_AST_FN_DECL) {
|
||||
spl_def_id_t fn_def = mn->resolved_def_id;
|
||||
if (!fn_def) {
|
||||
fn_def = spl_def_alloc(sema->type, SPL_DEF_FN, mn->fn_decl.name, mn->dbg, sema->ast,
|
||||
@@ -334,6 +330,9 @@ static spl_lang_type_id_t sema_build_aggregate(spl_sema_t *sema, spl_ast_node_t
|
||||
fn_d->owner_def = owner_def_id;
|
||||
spl_lang_method_t meth = {.name = mn->fn_decl.name, .def_id = fn_def};
|
||||
vec_push(methods, meth);
|
||||
spl_symbol_t fsym = {.name = mn->fn_decl.name, .kind = SPL_SYMBOL_KIND_FN};
|
||||
fsym.node = fn_def;
|
||||
spl_scope_insert(sema->scope, sema->scope->current_scope, fsym);
|
||||
} else if (mn->kind == SPL_AST_TYPE_DECL) {
|
||||
spl_ast_node_t *tpat = spl_ast_node(sema->ast, mn->type_decl.pattern);
|
||||
if (!tpat || tpat->kind != SPL_AST_PATTERN_IDENT)
|
||||
@@ -352,9 +351,37 @@ static spl_lang_type_id_t sema_build_aggregate(spl_sema_t *sema, spl_ast_node_t
|
||||
}
|
||||
spl_lang_method_t meth = {.name = tname, .def_id = tdef};
|
||||
vec_push(methods, meth);
|
||||
spl_symbol_t tsym = {.name = tname, .kind = SPL_SYMBOL_KIND_TYPE};
|
||||
tsym.node = tdef;
|
||||
spl_scope_insert(sema->scope, sema->scope->current_scope, tsym);
|
||||
}
|
||||
}
|
||||
|
||||
spl_lang_type_node_t *lslot = spl_lang_type_node(sema->type, agg_lang);
|
||||
if (lslot) {
|
||||
vec_free(lslot->methods);
|
||||
lslot->methods = methods;
|
||||
vec_init(methods);
|
||||
}
|
||||
|
||||
/* 第二遍:成员(字段/变体)类型推断;此时嵌套名字已可解析。 */
|
||||
for (usize i = 0; i < vec_size(te->type_aggregate.members); ++i) {
|
||||
spl_ast_node_ref_t mref = vec_at(te->type_aggregate.members, i);
|
||||
spl_ast_node_t *mn = spl_ast_node(sema->ast, mref);
|
||||
if (!mn)
|
||||
continue;
|
||||
if (mn->kind == SPL_AST_MEMBER_DECL) {
|
||||
spl_lang_type_id_t mtid = 0;
|
||||
if (mn->member_decl.type_expr)
|
||||
mtid = sema_infer(sema, mn->member_decl.type_expr);
|
||||
spl_type_member_t m = {.name = mn->member_decl.name,
|
||||
.type_id = spl_lang_type_get_ir_type(sema->type, mtid),
|
||||
.ast_node_ref = mref};
|
||||
vec_push(members, m);
|
||||
}
|
||||
}
|
||||
|
||||
sema_pop_scope(sema);
|
||||
sema->current_aggregate_lang = saved_agg;
|
||||
|
||||
spl_type_node_t tn = {0};
|
||||
@@ -366,13 +393,6 @@ static spl_lang_type_id_t sema_build_aggregate(spl_sema_t *sema, spl_ast_node_t
|
||||
vec_init(members);
|
||||
spl_lang_define_ir(sema->type, agg_ir, &tn);
|
||||
|
||||
spl_lang_type_node_t *lslot = spl_lang_type_node(sema->type, agg_lang);
|
||||
if (lslot) {
|
||||
vec_free(lslot->methods);
|
||||
lslot->methods = methods;
|
||||
vec_init(methods);
|
||||
}
|
||||
|
||||
return agg_lang;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user