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 {...@@ -423,6 +423,7 @@ enum TldResolution {
423 TldResolutionUnresolved,423 TldResolutionUnresolved,
424 TldResolutionResolving,424 TldResolutionResolving,
425 TldResolutionInvalid,425 TldResolutionInvalid,
426 TldResolutionOkLazy,
426 TldResolutionOk,427 TldResolutionOk,
427};428};
428429
src/analyze.cpp+41-33
...@@ -3091,7 +3091,7 @@ void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source...@@ -3091,7 +3091,7 @@ void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source
30913091
3092void update_compile_var(CodeGen *g, Buf *name, ConstExprValue *value) {3092void update_compile_var(CodeGen *g, Buf *name, ConstExprValue *value) {
3093 Tld *tld = get_container_scope(g->compile_var_import)->decl_table.get(name);3093 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);
3095 assert(tld->id == TldIdVar);3095 assert(tld->id == TldIdVar);
3096 TldVar *tld_var = (TldVar *)tld;3096 TldVar *tld_var = (TldVar *)tld;
3097 tld_var->var->const_value = value;3097 tld_var->var->const_value = value;
...@@ -3333,7 +3333,7 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf...@@ -3333,7 +3333,7 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf
3333 return variable_entry;3333 return variable_entry;
3334}3334}
33353335
3336static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {3336static void resolve_decl_var(CodeGen *g, TldVar *tld_var, bool allow_lazy) {
3337 AstNode *source_node = tld_var->base.source_node;3337 AstNode *source_node = tld_var->base.source_node;
3338 AstNodeVariableDeclaration *var_decl = &source_node->data.variable_declaration;3338 AstNodeVariableDeclaration *var_decl = &source_node->data.variable_declaration;
33393339
...@@ -3364,7 +3364,8 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {...@@ -3364,7 +3364,8 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
3364 if (explicit_type && explicit_type->id == ZigTypeIdInvalid) {3364 if (explicit_type && explicit_type->id == ZigTypeIdInvalid) {
3365 implicit_type = explicit_type;3365 implicit_type = explicit_type;
3366 } else if (var_decl->expr) {3366 } 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);
3368 assert(init_value);3369 assert(init_value);
3369 implicit_type = init_value->type;3370 implicit_type = init_value->type;
33703371
...@@ -3539,50 +3540,57 @@ static void preview_use_decl(CodeGen *g, TldUsingNamespace *using_namespace, Sco...@@ -3539,50 +3540,57 @@ static void preview_use_decl(CodeGen *g, TldUsingNamespace *using_namespace, Sco
3539 }3540 }
3540}3541}
35413542
3542void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node) {3543void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node, bool allow_lazy) {
3543 if (tld->resolution != TldResolutionUnresolved)3544 bool want_resolve_lazy = tld->resolution == TldResolutionOkLazy && !allow_lazy;
3545 if (tld->resolution != TldResolutionUnresolved && !want_resolve_lazy)
3544 return;3546 return;
35453547
3546 assert(tld->resolution != TldResolutionResolving);
3547 tld->resolution = TldResolutionResolving;3548 tld->resolution = TldResolutionResolving;
35483549
3549 switch (tld->id) {3550 switch (tld->id) {
3550 case TldIdVar:3551 case TldIdVar: {
3551 {3552 TldVar *tld_var = (TldVar *)tld;
3552 TldVar *tld_var = (TldVar *)tld;3553 if (want_resolve_lazy) {
3553 resolve_decl_var(g, tld_var);3554 ir_resolve_lazy(g, source_node, tld_var->var->const_value);
3554 break;3555 } else {
3555 }3556 resolve_decl_var(g, tld_var, allow_lazy);
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;
3573 }3557 }
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 }
3574 case TldIdUsingNamespace: {3582 case TldIdUsingNamespace: {
3575 TldUsingNamespace *tld_using_namespace = (TldUsingNamespace *)tld;3583 TldUsingNamespace *tld_using_namespace = (TldUsingNamespace *)tld;
3576 assert(tld_using_namespace->base.parent_scope->id == ScopeIdDecls);3584 assert(tld_using_namespace->base.parent_scope->id == ScopeIdDecls);
3577 ScopeDecls *dest_decls_scope = (ScopeDecls *)tld_using_namespace->base.parent_scope;3585 ScopeDecls *dest_decls_scope = (ScopeDecls *)tld_using_namespace->base.parent_scope;
3578 preview_use_decl(g, tld_using_namespace, dest_decls_scope);3586 preview_use_decl(g, tld_using_namespace, dest_decls_scope);
3579 resolve_use_decl(g, tld_using_namespace, dest_decls_scope);3587 resolve_use_decl(g, tld_using_namespace, dest_decls_scope);
3588
3589 tld->resolution = TldResolutionOk;
3580 break;3590 break;
3581 }3591 }
3582 }3592 }
35833593
3584 tld->resolution = TldResolutionOk;
3585
3586 if (g->trace_err != nullptr && source_node != nullptr) {3594 if (g->trace_err != nullptr && source_node != nullptr) {
3587 g->trace_err = add_error_note(g, g->trace_err, source_node, buf_create_from_str("referenced here"));3595 g->trace_err = add_error_note(g, g->trace_err, source_node, buf_create_from_str("referenced here"));
3588 }3596 }
...@@ -4254,7 +4262,7 @@ void semantic_analyze(CodeGen *g) {...@@ -4254,7 +4262,7 @@ void semantic_analyze(CodeGen *g) {
4254 Tld *tld = g->resolve_queue.at(g->resolve_queue_index);4262 Tld *tld = g->resolve_queue.at(g->resolve_queue_index);
4255 g->trace_err = nullptr;4263 g->trace_err = nullptr;
4256 AstNode *source_node = nullptr;4264 AstNode *source_node = nullptr;
4257 resolve_top_level_decl(g, tld, source_node);4265 resolve_top_level_decl(g, tld, source_node, false);
4258 }4266 }
42594267
4260 for (; g->fn_defs_index < g->fn_defs.length; g->fn_defs_index += 1) {4268 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) {...@@ -6602,7 +6610,7 @@ bool type_ptr_eql(const ZigType *a, const ZigType *b) {
66026610
6603ConstExprValue *get_builtin_value(CodeGen *codegen, const char *name) {6611ConstExprValue *get_builtin_value(CodeGen *codegen, const char *name) {
6604 Tld *tld = get_container_scope(codegen->compile_var_import)->decl_table.get(buf_create_from_str(name));6612 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);
6606 assert(tld->id == TldIdVar);6614 assert(tld->id == TldIdVar);
6607 TldVar *tld_var = (TldVar *)tld;6615 TldVar *tld_var = (TldVar *)tld;
6608 ConstExprValue *var_value = tld_var->var->const_value;6616 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...@@ -58,7 +58,7 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *abs_full_path, Bu
58ZigVar *find_variable(CodeGen *g, Scope *orig_context, Buf *name, ScopeFnDef **crossed_fndef_scope);58ZigVar *find_variable(CodeGen *g, Scope *orig_context, Buf *name, ScopeFnDef **crossed_fndef_scope);
59Tld *find_decl(CodeGen *g, Scope *scope, Buf *name);59Tld *find_decl(CodeGen *g, Scope *scope, Buf *name);
60Tld *find_container_decl(CodeGen *g, ScopeDecls *decls_scope, Buf *name);60Tld *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
63ZigType *get_src_ptr_type(ZigType *type);63ZigType *get_src_ptr_type(ZigType *type);
64ZigType *get_codegen_ptr_type(ZigType *type);64ZigType *get_codegen_ptr_type(ZigType *type);
src/codegen.cpp+1-1
...@@ -8896,7 +8896,7 @@ static void gen_root_source(CodeGen *g) {...@@ -8896,7 +8896,7 @@ static void gen_root_source(CodeGen *g) {
8896 }8896 }
8897 Tld *panic_tld = find_decl(g, &get_container_scope(import_with_panic)->base, buf_create_from_str("panic"));8897 Tld *panic_tld = find_decl(g, &get_container_scope(import_with_panic)->base, buf_create_from_str("panic"));
8898 assert(panic_tld != nullptr);8898 assert(panic_tld != nullptr);
8899 resolve_top_level_decl(g, panic_tld, nullptr);8899 resolve_top_level_decl(g, panic_tld, nullptr, false);
8900 }8900 }
89018901
89028902
src/ir.cpp+3-3
...@@ -17074,7 +17074,7 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira,...@@ -17074,7 +17074,7 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira,
17074 auto entry = container_scope->decl_table.maybe_get(field_name);17074 auto entry = container_scope->decl_table.maybe_get(field_name);
17075 Tld *tld = entry ? entry->value : nullptr;17075 Tld *tld = entry ? entry->value : nullptr;
17076 if (tld && tld->id == TldIdFn) {17076 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);
17078 if (tld->resolution == TldResolutionInvalid)17078 if (tld->resolution == TldResolutionInvalid)
17079 return ira->codegen->invalid_instruction;17079 return ira->codegen->invalid_instruction;
17080 TldFn *tld_fn = (TldFn *)tld;17080 TldFn *tld_fn = (TldFn *)tld;
...@@ -17317,7 +17317,7 @@ static IrInstruction *ir_error_dependency_loop(IrAnalyze *ira, IrInstruction *so...@@ -17317,7 +17317,7 @@ static IrInstruction *ir_error_dependency_loop(IrAnalyze *ira, IrInstruction *so
17317}17317}
1731817318
17319static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_instruction, Tld *tld) {17319static 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);
17321 if (tld->resolution == TldResolutionInvalid) {17321 if (tld->resolution == TldResolutionInvalid) {
17322 return ira->codegen->invalid_instruction;17322 return ira->codegen->invalid_instruction;
17323 }17323 }
...@@ -19682,7 +19682,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr...@@ -19682,7 +19682,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr
19682 while ((curr_entry = decl_it.next()) != nullptr) {19682 while ((curr_entry = decl_it.next()) != nullptr) {
19683 // If the declaration is unresolved, force it to be resolved again.19683 // If the declaration is unresolved, force it to be resolved again.
19684 if (curr_entry->value->resolution == TldResolutionUnresolved) {19684 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);
19686 if (curr_entry->value->resolution != TldResolutionOk) {19686 if (curr_entry->value->resolution != TldResolutionOk) {
19687 return ErrorSemanticAnalyzeFail;19687 return ErrorSemanticAnalyzeFail;
19688 }19688 }