diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 7b531979f9..347507d0da 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -1248,6 +1248,7 @@ pub mut: cond Expr stmts []Stmt scope &Scope = unsafe { nil } + id int } pub struct UnsafeExpr { @@ -1298,6 +1299,7 @@ pub mut: stmts []Stmt // right side exprs []Expr // left side scope &Scope = unsafe { nil } + id int } pub struct SelectExpr { diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 9dd559fb3a..dd48528656 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -102,6 +102,7 @@ pub mut: ct_cond_stack []ast.Expr ct_user_defines map[string]bool ct_system_defines map[string]bool + cur_ct_id int // id counter for $if $match branches mut: stmt_level int // the nesting level inside each stmts list; // .stmt_level is used to check for `evaluated but not used` ExprStmts like `1 << 1` diff --git a/vlib/v/checker/if.v b/vlib/v/checker/if.v index f8fae54428..720a6ded1f 100644 --- a/vlib/v/checker/if.v +++ b/vlib/v/checker/if.v @@ -107,9 +107,14 @@ fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type { if node.is_comptime { // `idx_str` is composed of two parts: // The first part represents the current context of the branch statement, `comptime_branch_context_str`, formatted like `T=int,X=string,method.name=json` - // The second part indicates the branch's location in the source file. + // The second part is the branch's id. // This format must match what is in `cgen`. - idx_str := comptime_branch_context_str + '|${c.file.path}|${branch.cond.pos()}|' + if branch.id == 0 { + // this is a new branch, alloc a new id for it + c.cur_ct_id++ + branch.id = c.cur_ct_id + } + idx_str := comptime_branch_context_str + '|id=${branch.id}|' c.comptime.inside_comptime_if = true mut sb := strings.new_builder(256) comptime_if_result, comptime_if_multi_pass_branch = c.comptime_if_cond(mut branch.cond, mut @@ -165,7 +170,12 @@ fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type { comptime_remove_curr_branch_stmts = true } // hack: as a `else` has no `cond`, so we use `branch.pos` here - idx_str := comptime_branch_context_str + '|${c.file.path}|${branch.pos}|' + if branch.id == 0 { + // this is a new branch, alloc a new id for it + c.cur_ct_id++ + branch.id = c.cur_ct_id + } + idx_str := comptime_branch_context_str + '|id=${branch.id}|' c.table.comptime_is_true[idx_str] = ast.ComptTimeCondResult{ val: comptime_if_result c_str: '' diff --git a/vlib/v/checker/match.v b/vlib/v/checker/match.v index 4554467718..39ed0e33a9 100644 --- a/vlib/v/checker/match.v +++ b/vlib/v/checker/match.v @@ -130,9 +130,14 @@ fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type { if node.is_comptime { // `idx_str` is composed of two parts: // The first part represents the current context of the branch statement, `comptime_branch_context_str`, formatted like `T=int,X=string,method.name=json` - // The second part indicates the branch's location in the source file. + // The second part is the branch's id. // This format must match what is in `cgen`. - idx_str := comptime_branch_context_str + '|${c.file.path}|${branch.pos}|' + if branch.id == 0 { + // this is a new branch, alloc a new id for it + c.cur_ct_id++ + branch.id = c.cur_ct_id + } + idx_str := comptime_branch_context_str + '|id=${branch.id}|' mut c_str := '' if !branch.is_else { if c.inside_x_matches_type { diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 5cfd332071..27d24474e2 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -5810,11 +5810,7 @@ fn (mut g Gen) gen_hash_stmts(mut sb strings.Builder, node &ast.HashStmtNode, se mut comptime_branch_context_str := g.gen_branch_context_string() mut is_true := ast.ComptTimeCondResult{} for i, branch in node.branches { - idx_str := if branch.cond.pos() == token.Pos{} { - comptime_branch_context_str + '|${g.file.path}|${branch.pos}|' - } else { - comptime_branch_context_str + '|${g.file.path}|${branch.cond.pos()}|' - } + idx_str := comptime_branch_context_str + '|id=${branch.id}|' if comptime_is_true := g.table.comptime_is_true[idx_str] { // `g.table.comptime_is_true` are the branch condition results set by `checker` is_true = comptime_is_true diff --git a/vlib/v/gen/c/comptime.v b/vlib/v/gen/c/comptime.v index ca067f1768..3c811f5a12 100644 --- a/vlib/v/gen/c/comptime.v +++ b/vlib/v/gen/c/comptime.v @@ -5,7 +5,6 @@ module c import os import v.ast -import v.token import v.util import v.pref import v.type_resolver @@ -418,13 +417,9 @@ fn (mut g Gen) comptime_if(node ast.IfExpr) { start_pos := g.out.len // `idx_str` is composed of two parts: // The first part represents the current context of the branch statement, `comptime_branch_context_str`, formatted like `T=int,X=string,method.name=json` - // The second part indicates the branch's location in the source file. + // The second part is the branch's id. // This format must match what is in `checker`. - idx_str := if branch.cond.pos() == token.Pos{} { - comptime_branch_context_str + '|${g.file.path}|${branch.pos}|' - } else { - comptime_branch_context_str + '|${g.file.path}|${branch.cond.pos()}|' - } + idx_str := comptime_branch_context_str + '|id=${branch.id}|' if comptime_is_true := g.table.comptime_is_true[idx_str] { // `g.table.comptime_is_true` are the branch condition results set by `checker` is_true = comptime_is_true @@ -984,9 +979,9 @@ fn (mut g Gen) comptime_match(node ast.MatchExpr) { for i, branch in node.branches { // `idx_str` is composed of two parts: // The first part represents the current context of the branch statement, `comptime_branch_context_str`, formatted like `T=int,X=string,method.name=json` - // The second part indicates the branch's location in the source file. + // The second part is the branch's id. // This format must match what is in `checker`. - idx_str := comptime_branch_context_str + '|${g.file.path}|${branch.pos}|' + idx_str := comptime_branch_context_str + '|id=${branch.id}|' if comptime_is_true := g.table.comptime_is_true[idx_str] { // `g.table.comptime_is_true` are the branch condition results set by `checker` is_true = comptime_is_true diff --git a/vlib/v/gen/js/comptime.v b/vlib/v/gen/js/comptime.v index c706756b20..801304c5f5 100644 --- a/vlib/v/gen/js/comptime.v +++ b/vlib/v/gen/js/comptime.v @@ -1,6 +1,5 @@ module js -import v.token import v.ast fn (mut g JsGen) gen_branch_context_string() string { @@ -30,11 +29,7 @@ fn (mut g JsGen) comptime_if(node ast.IfExpr) { mut comptime_branch_context_str := g.gen_branch_context_string() mut is_true := ast.ComptTimeCondResult{} for i, branch in node.branches { - idx_str := if branch.cond.pos() == token.Pos{} { - comptime_branch_context_str + '|${g.file.path}|${branch.pos}|' - } else { - comptime_branch_context_str + '|${g.file.path}|${branch.cond.pos()}|' - } + idx_str := comptime_branch_context_str + '|id=${branch.id}|' if comptime_is_true := g.table.comptime_is_true[idx_str] { is_true = comptime_is_true } else {