From 49c3922037ef0b913466e707d85a4e085f6e9716 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 12 Mar 2018 00:08:52 -0400 Subject: [PATCH] fix incorrect setEvalBranchQuota compile error closes #688 --- src/all_types.hpp | 1 + src/ir.cpp | 3 ++- test/cases/eval.zig | 21 +++++++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/all_types.hpp b/src/all_types.hpp index 7d480b5b4..cfe70c96d 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -49,6 +49,7 @@ struct IrExecutable { size_t backward_branch_quota; bool invalid; bool is_inline; + bool is_generic_instantiation; FnTableEntry *fn_entry; Buf *c_import_buf; AstNode *source_node; diff --git a/src/ir.cpp b/src/ir.cpp index 8fa6d5c44..69b955aef 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -12127,6 +12127,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal impl_fn->ir_executable.parent_exec = ira->new_irb.exec; impl_fn->analyzed_executable.source_node = call_instruction->base.source_node; impl_fn->analyzed_executable.parent_exec = ira->new_irb.exec; + impl_fn->analyzed_executable.is_generic_instantiation = true; ira->codegen->fn_defs.append(impl_fn); } @@ -15234,7 +15235,7 @@ static TypeTableEntry *ir_analyze_instruction_type_id(IrAnalyze *ira, static TypeTableEntry *ir_analyze_instruction_set_eval_branch_quota(IrAnalyze *ira, IrInstructionSetEvalBranchQuota *instruction) { - if (ira->new_irb.exec->parent_exec != nullptr) { + if (ira->new_irb.exec->parent_exec != nullptr && !ira->new_irb.exec->is_generic_instantiation) { ir_add_error(ira, &instruction->base, buf_sprintf("@setEvalBranchQuota must be called from the top of the comptime stack")); return ira->codegen->builtin_types.entry_invalid; diff --git a/test/cases/eval.zig b/test/cases/eval.zig index 58877f7e2..ef6fa73ce 100644 --- a/test/cases/eval.zig +++ b/test/cases/eval.zig @@ -448,3 +448,24 @@ test "comptime function with mutable pointer is not memoized" { fn increment(value: &i32) void { *value += 1; } + +fn generateTable(comptime T: type) [1010]T { + var res : [1010]T = undefined; + var i : usize = 0; + while (i < 1010) : (i += 1) { + res[i] = T(i); + } + return res; +} + +fn doesAlotT(comptime T: type, value: usize) T { + @setEvalBranchQuota(5000); + const table = comptime blk: { + break :blk generateTable(T); + }; + return table[value]; +} + +test "@setEvalBranchQuota at same scope as generic function call" { + assert(doesAlotT(u32, 2) == 2); +}