diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index eea94e9904..64cfead4ab 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -1073,6 +1073,7 @@ pub mut: is_mut bool // if mut *token* is before name. Use `is_mut()` to lookup mut variable or_expr OrExpr concrete_types []Type + ct_expr bool // is it a comptime expr? } // full_name returns the name of the ident, prefixed with the module name diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 6d03a745e9..8472b9606e 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -3052,8 +3052,8 @@ pub fn (mut c Checker) expr(mut node ast.Expr) ast.Type { } c.table.used_features.print_types[ast.int_type_idx] = true } - if c.comptime.inside_comptime_for && node.expr is ast.Ident { - if c.comptime.is_comptime_var(node.expr) { + if c.comptime.inside_comptime_for && mut node.expr is ast.Ident { + if node.expr.ct_expr { node.expr_type = c.comptime.get_type(node.expr as ast.Ident) } else if (node.expr as ast.Ident).name in c.comptime.type_map { node.expr_type = c.comptime.type_map[(node.expr as ast.Ident).name] @@ -4072,6 +4072,7 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type { obj.typ = typ } node.obj = obj + node.ct_expr = obj.ct_type_var != .no_comptime // unwrap option (`println(x)`) if is_option { if node.or_expr.kind == .absent { diff --git a/vlib/v/checker/for.v b/vlib/v/checker/for.v index 2c96c41c0c..1c081bba3c 100644 --- a/vlib/v/checker/for.v +++ b/vlib/v/checker/for.v @@ -94,8 +94,7 @@ fn (mut c Checker) for_in_stmt(mut node ast.ForInStmt) { node.cond.pos()) } mut is_comptime := false - if (node.cond is ast.Ident && c.comptime.is_comptime_var(node.cond)) - || node.cond is ast.ComptimeSelector { + if (node.cond is ast.Ident && node.cond.ct_expr) || node.cond is ast.ComptimeSelector { ctyp := c.comptime.get_type(node.cond) if ctyp != ast.void_type { is_comptime = true diff --git a/vlib/v/checker/if.v b/vlib/v/checker/if.v index 9832ee2a63..b4e7fbd330 100644 --- a/vlib/v/checker/if.v +++ b/vlib/v/checker/if.v @@ -579,7 +579,7 @@ fn (mut c Checker) smartcast_if_conds(mut node ast.Expr, mut scope ast.Scope, co scope, false, true) } } else if node.op == .key_is { - if node.left is ast.Ident && c.comptime.is_comptime_var(node.left) { + if node.left is ast.Ident && node.left.ct_expr { node.left_type = c.comptime.get_type(node.left) } else { node.left_type = c.expr(mut node.left) diff --git a/vlib/v/checker/infix.v b/vlib/v/checker/infix.v index 7ae7477cdc..980b6826db 100644 --- a/vlib/v/checker/infix.v +++ b/vlib/v/checker/infix.v @@ -784,7 +784,7 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { c.error('`${op}` can only be used to test for none in sql', node.pos) } } else if left_sym.kind !in [.interface, .sum_type] - && !c.comptime.is_comptime_var(node.left) { + && !c.comptime.is_comptime(node.left) { c.error('`${op}` can only be used with interfaces and sum types', node.pos) // can be used in sql too, but keep err simple } else if mut left_sym.info is ast.SumType { diff --git a/vlib/v/checker/postfix.v b/vlib/v/checker/postfix.v index 878bb805f5..30223759fc 100644 --- a/vlib/v/checker/postfix.v +++ b/vlib/v/checker/postfix.v @@ -25,7 +25,7 @@ fn (mut c Checker) postfix_expr(mut node ast.PostfixExpr) ast.Type { } if !(typ_sym.is_number() || ((c.inside_unsafe || c.pref.translated) && is_non_void_pointer)) { if c.comptime.comptime_for_field_var != '' { - if c.comptime.is_comptime_var(node.expr) || node.expr is ast.ComptimeSelector { + if c.comptime.is_comptime(node.expr) || node.expr is ast.ComptimeSelector { node.typ = c.unwrap_generic(c.comptime.get_type(node.expr)) if node.op == .question { node.typ = node.typ.clear_flag(.option) diff --git a/vlib/v/checker/str.v b/vlib/v/checker/str.v index 551c67c6fe..b6b82b7985 100644 --- a/vlib/v/checker/str.v +++ b/vlib/v/checker/str.v @@ -85,7 +85,7 @@ fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) ast.Type { c.error('no known default format for type `${c.table.get_type_name(ftyp)}`', node.fmt_poss[i]) } - } else if c.comptime.is_comptime_var(expr) && c.comptime.get_type(expr) != ast.void_type { + } else if c.comptime.is_comptime(expr) && c.comptime.get_type(expr) != ast.void_type { // still `_` placeholder for comptime variable without specifier node.need_fmts[i] = false } else { diff --git a/vlib/v/comptime/comptimeinfo.v b/vlib/v/comptime/comptimeinfo.v index e71ba31b86..9f9dfe8d5a 100644 --- a/vlib/v/comptime/comptimeinfo.v +++ b/vlib/v/comptime/comptimeinfo.v @@ -31,15 +31,29 @@ pub fn (mut ct ComptimeInfo) get_comptime_selector_key_type(val ast.ComptimeSele // is_comptime_expr checks if the node is related to a comptime expr @[inline] pub fn (mut ct ComptimeInfo) is_comptime_expr(node ast.Expr) bool { - return (node is ast.Ident && ct.get_ct_type_var(node) != .no_comptime) + return (node is ast.Ident && node.ct_expr) || (node is ast.IndexExpr && ct.is_comptime_expr(node.left)) || node is ast.ComptimeSelector } -// is_comptime_var checks if the node is related to a comptime variable +// is_comptime checks if the node is related to a comptime marked variable @[inline] -pub fn (mut ct ComptimeInfo) is_comptime_var(node ast.Expr) bool { - return ct.get_ct_type_var(node) != .no_comptime +pub fn (mut ct ComptimeInfo) is_comptime(node ast.Expr) bool { + return match node { + ast.Ident { + node.ct_expr + } + ast.IndexExpr { + if node.left is ast.Ident { + node.left.ct_expr + } else { + false + } + } + else { + false + } + } } // is_comptime_variant_var checks if the node is related to a comptime variant variable @@ -89,7 +103,7 @@ pub fn (mut ct ComptimeInfo) get_expr_type_or_default(node ast.Expr, default_typ pub fn (mut ct ComptimeInfo) get_type_or_default(node ast.Expr, default_typ ast.Type) ast.Type { match node { ast.Ident { - if ct.is_comptime_var(node) { + if node.ct_expr { ctyp := ct.get_type(node) return if ctyp != ast.void_type { ctyp } else { default_typ } } @@ -154,7 +168,7 @@ pub fn (mut ct ComptimeInfo) get_type(node ast.Expr) ast.Type { return ast.void_type } return f.return_type - } else if node is ast.IndexExpr && ct.is_comptime_var(node.left) { + } else if node is ast.IndexExpr && ct.is_comptime(node.left) { nltype := ct.get_type(node.left) nltype_unwrapped := ct.resolver.unwrap_generic(nltype) return ct.table.value_type(nltype_unwrapped) @@ -352,16 +366,16 @@ pub fn (mut ct ComptimeInfo) unwrap_generic_expr(expr ast.Expr, default_typ ast. return expr.typ } ast.InfixExpr { - if ct.is_comptime_var(expr.left) { + if ct.is_comptime(expr.left) { return ct.resolver.unwrap_generic(ct.get_type(expr.left)) } - if ct.is_comptime_var(expr.right) { + if ct.is_comptime(expr.right) { return ct.resolver.unwrap_generic(ct.get_type(expr.right)) } return default_typ } ast.Ident { - return if ct.is_comptime_var(expr) { + return if expr.ct_expr { ct.resolver.unwrap_generic(ct.get_type(expr)) } else { default_typ diff --git a/vlib/v/gen/c/array.v b/vlib/v/gen/c/array.v index 707ba5bf2d..52e0705861 100644 --- a/vlib/v/gen/c/array.v +++ b/vlib/v/gen/c/array.v @@ -562,8 +562,7 @@ fn (mut g Gen) gen_array_map(node ast.CallExpr) { } ast.CastExpr { // value.map(Type(it)) when `value` is a comptime var - if expr.expr is ast.Ident && node.left is ast.Ident - && g.comptime.is_comptime_var(node.left) { + if expr.expr is ast.Ident && node.left is ast.Ident && node.left.ct_expr { ctyp := g.comptime.get_type(node.left) if ctyp != ast.void_type { expr.expr_type = g.table.value_type(ctyp) diff --git a/vlib/v/gen/c/assign.v b/vlib/v/gen/c/assign.v index de19911bf9..b2df3b9daf 100644 --- a/vlib/v/gen/c/assign.v +++ b/vlib/v/gen/c/assign.v @@ -292,7 +292,7 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { } } if mut left.obj is ast.Var { - if val is ast.Ident && g.comptime.is_comptime_var(val) { + if val is ast.Ident && val.ct_expr { ctyp := g.unwrap_generic(g.comptime.get_type(val)) if ctyp != ast.void_type { var_type = ctyp diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index c2d07356da..80e169b23d 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -3769,7 +3769,7 @@ fn (mut g Gen) expr(node_ ast.Expr) { if mut node.expr is ast.ComptimeSelector && node.expr.left is ast.Ident { // val.$(field.name)? expr_str = '${node.expr.left.str()}.${g.comptime.comptime_for_field_value.name}' - } else if mut node.expr is ast.Ident && g.comptime.is_comptime_var(node.expr) { + } else if mut node.expr is ast.Ident && node.expr.ct_expr { // val? expr_str = node.expr.name } diff --git a/vlib/v/gen/c/comptime.v b/vlib/v/gen/c/comptime.v index c6fa396b0a..fae9b9a7f7 100644 --- a/vlib/v/gen/c/comptime.v +++ b/vlib/v/gen/c/comptime.v @@ -1071,7 +1071,7 @@ fn (mut g Gen) comptime_for(node ast.ComptimeFor) { // comptime_selector_type computes the selector type from an comptime var fn (mut g Gen) comptime_selector_type(node ast.SelectorExpr) ast.Type { - if !(node.expr is ast.Ident && g.comptime.is_comptime_var(node.expr)) { + if !(node.expr is ast.Ident && node.expr.ct_expr) { return node.expr_type } prevent_sum_type_unwrapping_once := g.prevent_sum_type_unwrapping_once diff --git a/vlib/v/gen/c/dumpexpr.v b/vlib/v/gen/c/dumpexpr.v index e9be281358..246a073882 100644 --- a/vlib/v/gen/c/dumpexpr.v +++ b/vlib/v/gen/c/dumpexpr.v @@ -44,12 +44,12 @@ fn (mut g Gen) dump_expr(node ast.DumpExpr) { } } } - } else if node.expr is ast.Ident && g.comptime.is_comptime_var(node.expr) { + } else if node.expr is ast.Ident && node.expr.ct_expr { expr_type = g.comptime.get_type(node.expr) name = g.styp(g.unwrap_generic(expr_type.clear_flags(.shared_f, .result))).replace('*', '') } else if node.expr is ast.SelectorExpr && node.expr.expr is ast.Ident - && g.comptime.is_comptime_var(node.expr.expr) { + && (node.expr.expr as ast.Ident).ct_expr { expr_type = g.comptime_selector_type(node.expr) name = g.styp(g.unwrap_generic(expr_type.clear_flags(.shared_f, .result))).replace('*', '') diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index 92ee090eb5..8e678a238c 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -2220,7 +2220,7 @@ fn (mut g Gen) fn_call(node ast.CallExpr) { mut print_auto_str := false if is_print && (node.args[0].typ != ast.string_type || g.comptime.comptime_for_method != unsafe { nil } - || g.comptime.is_comptime_var(node.args[0].expr)) { + || g.comptime.is_comptime(node.args[0].expr)) { g.inside_interface_deref = true defer { g.inside_interface_deref = false diff --git a/vlib/v/gen/c/for.v b/vlib/v/gen/c/for.v index c1f42868f3..944a3a76c8 100644 --- a/vlib/v/gen/c/for.v +++ b/vlib/v/gen/c/for.v @@ -142,8 +142,7 @@ fn (mut g Gen) for_in_stmt(node_ ast.ForInStmt) { mut node := unsafe { node_ } mut is_comptime := false - if (node.cond is ast.Ident && g.comptime.is_comptime_var(node.cond)) - || node.cond is ast.ComptimeSelector { + if (node.cond is ast.Ident && node.cond.ct_expr) || node.cond is ast.ComptimeSelector { mut unwrapped_typ := g.unwrap_generic(node.cond_type) ctyp := g.comptime.get_type(node.cond) if ctyp != ast.void_type { @@ -222,7 +221,7 @@ fn (mut g Gen) for_in_stmt(node_ ast.ForInStmt) { mut val_sym := g.table.sym(node.val_type) op_field := g.dot_or_ptr(node.cond_type) - if is_comptime && g.comptime.is_comptime_var(node.cond) { + if is_comptime && g.comptime.is_comptime(node.cond) { mut unwrapped_typ := g.unwrap_generic(node.cond_type) ctyp := g.unwrap_generic(g.comptime.get_type(node.cond)) if ctyp != ast.void_type { diff --git a/vlib/v/gen/c/str_intp.v b/vlib/v/gen/c/str_intp.v index bd75ce00d5..219b1f6e8a 100644 --- a/vlib/v/gen/c/str_intp.v +++ b/vlib/v/gen/c/str_intp.v @@ -240,7 +240,7 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { mut node_ := unsafe { node } mut fmts := node_.fmts.clone() for i, mut expr in node_.exprs { - if g.comptime.is_comptime_var(expr) { + if g.comptime.is_comptime(expr) { ctyp := g.comptime.get_type(expr) if ctyp != ast.void_type { node_.expr_types[i] = ctyp