authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-23 14:07:34-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-23 14:07:34-04:00
log1dd658d1d02f8dfc432bcda88fdb542189c31725
tree02a59f559847a0898e9a2bfd915212df7775456a
parent20049caaba0354754811ae0d36a773c31cf4578a
signaturelock-open Commit is signed but in an unrecognized format.

allow top level declarations to be lazy

this case now works: ```zig const A = struct { b: B, }; const B = fn (A) void; ```

5 files changed, 47 insertions(+), 38 deletions(-)

src/all_types.hpp+1
......@@ -423,6 +423,7 @@ enum TldResolution {
423423 TldResolutionUnresolved,
424424 TldResolutionResolving,
425425 TldResolutionInvalid,
426 TldResolutionOkLazy,
426427 TldResolutionOk,
427428};
428429
src/analyze.cpp+41-33
......@@ -3091,7 +3091,7 @@ void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source
30913091
30923092void update_compile_var(CodeGen *g, Buf *name, ConstExprValue *value) {
30933093 Tld *tld = get_container_scope(g->compile_var_import)->decl_table.get(name);
3094 resolve_top_level_decl(g, tld, tld->source_node);
3094 resolve_top_level_decl(g, tld, tld->source_node, false);
30953095 assert(tld->id == TldIdVar);
30963096 TldVar *tld_var = (TldVar *)tld;
30973097 tld_var->var->const_value = value;
......@@ -3333,7 +3333,7 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf
33333333 return variable_entry;
33343334}
33353335
3336static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
3336static void resolve_decl_var(CodeGen *g, TldVar *tld_var, bool allow_lazy) {
33373337 AstNode *source_node = tld_var->base.source_node;
33383338 AstNodeVariableDeclaration *var_decl = &source_node->data.variable_declaration;
33393339
......@@ -3364,7 +3364,8 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
33643364 if (explicit_type && explicit_type->id == ZigTypeIdInvalid) {
33653365 implicit_type = explicit_type;
33663366 } else if (var_decl->expr) {
3367 init_value = analyze_const_value(g, tld_var->base.parent_scope, var_decl->expr, explicit_type, var_decl->symbol);
3367 init_value = analyze_const_value_allow_lazy(g, tld_var->base.parent_scope, var_decl->expr, explicit_type,
3368 var_decl->symbol, allow_lazy);
33683369 assert(init_value);
33693370 implicit_type = init_value->type;
33703371
......@@ -3539,50 +3540,57 @@ static void preview_use_decl(CodeGen *g, TldUsingNamespace *using_namespace, Sco
35393540 }
35403541}
35413542
3542void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node) {
3543 if (tld->resolution != TldResolutionUnresolved)
3543void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node, bool allow_lazy) {
3544 bool want_resolve_lazy = tld->resolution == TldResolutionOkLazy && !allow_lazy;
3545 if (tld->resolution != TldResolutionUnresolved && !want_resolve_lazy)
35443546 return;
35453547
3546 assert(tld->resolution != TldResolutionResolving);
35473548 tld->resolution = TldResolutionResolving;
35483549
35493550 switch (tld->id) {
3550 case TldIdVar:
3551 {
3552 TldVar *tld_var = (TldVar *)tld;
3553 resolve_decl_var(g, tld_var);
3554 break;
3555 }
3556 case TldIdFn:
3557 {
3558 TldFn *tld_fn = (TldFn *)tld;
3559 resolve_decl_fn(g, tld_fn);
3560 break;
3561 }
3562 case TldIdContainer:
3563 {
3564 TldContainer *tld_container = (TldContainer *)tld;
3565 resolve_decl_container(g, tld_container);
3566 break;
3567 }
3568 case TldIdCompTime:
3569 {
3570 TldCompTime *tld_comptime = (TldCompTime *)tld;
3571 resolve_decl_comptime(g, tld_comptime);
3572 break;
3551 case TldIdVar: {
3552 TldVar *tld_var = (TldVar *)tld;
3553 if (want_resolve_lazy) {
3554 ir_resolve_lazy(g, source_node, tld_var->var->const_value);
3555 } else {
3556 resolve_decl_var(g, tld_var, allow_lazy);
35733557 }
3558 tld->resolution = allow_lazy ? TldResolutionOkLazy : TldResolutionOk;
3559 break;
3560 }
3561 case TldIdFn: {
3562 TldFn *tld_fn = (TldFn *)tld;
3563 resolve_decl_fn(g, tld_fn);
3564
3565 tld->resolution = TldResolutionOk;
3566 break;
3567 }
3568 case TldIdContainer: {
3569 TldContainer *tld_container = (TldContainer *)tld;
3570 resolve_decl_container(g, tld_container);
3571
3572 tld->resolution = TldResolutionOk;
3573 break;
3574 }
3575 case TldIdCompTime: {
3576 TldCompTime *tld_comptime = (TldCompTime *)tld;
3577 resolve_decl_comptime(g, tld_comptime);
3578
3579 tld->resolution = TldResolutionOk;
3580 break;
3581 }
35743582 case TldIdUsingNamespace: {
35753583 TldUsingNamespace *tld_using_namespace = (TldUsingNamespace *)tld;
35763584 assert(tld_using_namespace->base.parent_scope->id == ScopeIdDecls);
35773585 ScopeDecls *dest_decls_scope = (ScopeDecls *)tld_using_namespace->base.parent_scope;
35783586 preview_use_decl(g, tld_using_namespace, dest_decls_scope);
35793587 resolve_use_decl(g, tld_using_namespace, dest_decls_scope);
3588
3589 tld->resolution = TldResolutionOk;
35803590 break;
35813591 }
35823592 }
35833593
3584 tld->resolution = TldResolutionOk;
3585
35863594 if (g->trace_err != nullptr && source_node != nullptr) {
35873595 g->trace_err = add_error_note(g, g->trace_err, source_node, buf_create_from_str("referenced here"));
35883596 }
......@@ -4254,7 +4262,7 @@ void semantic_analyze(CodeGen *g) {
42544262 Tld *tld = g->resolve_queue.at(g->resolve_queue_index);
42554263 g->trace_err = nullptr;
42564264 AstNode *source_node = nullptr;
4257 resolve_top_level_decl(g, tld, source_node);
4265 resolve_top_level_decl(g, tld, source_node, false);
42584266 }
42594267
42604268 for (; g->fn_defs_index < g->fn_defs.length; g->fn_defs_index += 1) {
......@@ -6602,7 +6610,7 @@ bool type_ptr_eql(const ZigType *a, const ZigType *b) {
66026610
66036611ConstExprValue *get_builtin_value(CodeGen *codegen, const char *name) {
66046612 Tld *tld = get_container_scope(codegen->compile_var_import)->decl_table.get(buf_create_from_str(name));
6605 resolve_top_level_decl(codegen, tld, nullptr);
6613 resolve_top_level_decl(codegen, tld, nullptr, false);
66066614 assert(tld->id == TldIdVar);
66076615 TldVar *tld_var = (TldVar *)tld;
66086616 ConstExprValue *var_value = tld_var->var->const_value;
src/analyze.hpp+1-1
......@@ -58,7 +58,7 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *abs_full_path, Bu
5858ZigVar *find_variable(CodeGen *g, Scope *orig_context, Buf *name, ScopeFnDef **crossed_fndef_scope);
5959Tld *find_decl(CodeGen *g, Scope *scope, Buf *name);
6060Tld *find_container_decl(CodeGen *g, ScopeDecls *decls_scope, Buf *name);
61void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node);
61void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node, bool allow_lazy);
6262
6363ZigType *get_src_ptr_type(ZigType *type);
6464ZigType *get_codegen_ptr_type(ZigType *type);
src/codegen.cpp+1-1
......@@ -8896,7 +8896,7 @@ static void gen_root_source(CodeGen *g) {
88968896 }
88978897 Tld *panic_tld = find_decl(g, &get_container_scope(import_with_panic)->base, buf_create_from_str("panic"));
88988898 assert(panic_tld != nullptr);
8899 resolve_top_level_decl(g, panic_tld, nullptr);
8899 resolve_top_level_decl(g, panic_tld, nullptr, false);
89008900 }
89018901
89028902
src/ir.cpp+3-3
......@@ -17074,7 +17074,7 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira,
1707417074 auto entry = container_scope->decl_table.maybe_get(field_name);
1707517075 Tld *tld = entry ? entry->value : nullptr;
1707617076 if (tld && tld->id == TldIdFn) {
17077 resolve_top_level_decl(ira->codegen, tld, source_instr->source_node);
17077 resolve_top_level_decl(ira->codegen, tld, source_instr->source_node, false);
1707817078 if (tld->resolution == TldResolutionInvalid)
1707917079 return ira->codegen->invalid_instruction;
1708017080 TldFn *tld_fn = (TldFn *)tld;
......@@ -17317,7 +17317,7 @@ static IrInstruction *ir_error_dependency_loop(IrAnalyze *ira, IrInstruction *so
1731717317}
1731817318
1731917319static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_instruction, Tld *tld) {
17320 resolve_top_level_decl(ira->codegen, tld, source_instruction->source_node);
17320 resolve_top_level_decl(ira->codegen, tld, source_instruction->source_node, true);
1732117321 if (tld->resolution == TldResolutionInvalid) {
1732217322 return ira->codegen->invalid_instruction;
1732317323 }
......@@ -19682,7 +19682,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr
1968219682 while ((curr_entry = decl_it.next()) != nullptr) {
1968319683 // If the declaration is unresolved, force it to be resolved again.
1968419684 if (curr_entry->value->resolution == TldResolutionUnresolved) {
19685 resolve_top_level_decl(ira->codegen, curr_entry->value, curr_entry->value->source_node);
19685 resolve_top_level_decl(ira->codegen, curr_entry->value, curr_entry->value->source_node, false);
1968619686 if (curr_entry->value->resolution != TldResolutionOk) {
1968719687 return ErrorSemanticAnalyzeFail;
1968819688 }