Commit ab88165326
Changed files (3)
test
behavior
src/Module.zig
@@ -1476,6 +1476,10 @@ pub const Fn = struct {
lbrace_column: u16,
rbrace_column: u16,
+ /// When a generic function is instantiated, this value is inherited from the
+ /// active Sema context. Importantly, this value is also updated when an existing
+ /// generic function instantiation is found and called.
+ branch_quota: u32,
state: Analysis,
is_cold: bool = false,
is_noinline: bool = false,
@@ -4891,6 +4895,7 @@ pub fn analyzeFnBody(mod: *Module, func: *Fn, arena: Allocator) SemaError!Air {
.func = func,
.fn_ret_ty = decl.ty.fnReturnType(),
.owner_func = func,
+ .branch_quota = @maximum(func.branch_quota, Sema.default_branch_quota),
};
defer sema.deinit();
src/Sema.zig
@@ -38,7 +38,7 @@ func: ?*Module.Fn,
/// generic function which uses a type expression for the return type.
/// The type will be `void` in the case that `func` is `null`.
fn_ret_ty: Type,
-branch_quota: u32 = 1000,
+branch_quota: u32 = default_branch_quota,
branch_count: u32 = 0,
/// Populated when returning `error.ComptimeBreak`. Used to communicate the
/// break instruction up the stack to find the corresponding Block.
@@ -102,6 +102,8 @@ const Package = @import("Package.zig");
const crash_report = @import("crash_report.zig");
const build_options = @import("build_options");
+pub const default_branch_quota = 1000;
+
pub const InstMap = std.AutoHashMapUnmanaged(Zir.Inst.Index, Air.Inst.Ref);
/// This is the context needed to semantically analyze ZIR instructions and
@@ -3752,8 +3754,7 @@ fn zirSetEvalBranchQuota(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
const src = inst_data.src();
const quota = @intCast(u32, try sema.resolveInt(block, src, inst_data.operand, Type.u32));
- if (sema.branch_quota < quota)
- sema.branch_quota = quota;
+ sema.branch_quota = @maximum(sema.branch_quota, quota);
}
fn zirStore(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
@@ -5679,6 +5680,8 @@ fn instantiateGenericCall(
break :callee new_func;
} else gop.key_ptr.*;
+ callee.branch_quota = @maximum(callee.branch_quota, sema.branch_quota);
+
const callee_inst = try sema.analyzeDeclVal(block, func_src, callee.owner_decl);
// Make a runtime call to the new function, making sure to omit the comptime args.
@@ -6773,6 +6776,7 @@ fn funcCommon(
.lbrace_column = @truncate(u16, src_locs.columns),
.rbrace_column = @truncate(u16, src_locs.columns >> 16),
.param_names = param_names,
+ .branch_quota = default_branch_quota,
};
if (maybe_inferred_error_set_node) |node| {
new_func.inferred_error_sets.prepend(node);
test/behavior/eval.zig
@@ -704,8 +704,6 @@ test "call method with comptime pass-by-non-copying-value self parameter" {
}
test "setting backward branch quota just before a generic fn call" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
-
@setEvalBranchQuota(1001);
loopNTimes(1001);
}