From 9f11638cba02cc0ac00cb3ee33573468a8fee9ed Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Mon, 30 Dec 2024 04:53:38 -0300 Subject: [PATCH] v: cleanup ComptimeSelector `.typ` key generation (#23308) --- vlib/v/ast/ast.v | 2 ++ vlib/v/checker/comptime.v | 4 +++ vlib/v/gen/c/assign.v | 38 +++++++++++------------- vlib/v/gen/c/comptime.v | 5 ++-- vlib/v/gen/c/dumpexpr.v | 7 ++--- vlib/v/gen/c/fn.v | 10 +++---- vlib/v/type_resolver/comptime_resolver.v | 15 ++-------- 7 files changed, 35 insertions(+), 46 deletions(-) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 1f39d9a326..fad6c30963 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -1994,6 +1994,8 @@ pub mut: left_type Type field_expr Expr typ Type + is_name bool // true if f.$(field.name) + typ_key string // `f.typ` cached key for type resolver } @[minify] diff --git a/vlib/v/checker/comptime.v b/vlib/v/checker/comptime.v index 3b1aca10e2..753b7406fd 100644 --- a/vlib/v/checker/comptime.v +++ b/vlib/v/checker/comptime.v @@ -244,6 +244,10 @@ fn (mut c Checker) comptime_selector(mut node ast.ComptimeSelector) ast.Type { c.error('compile time field access can only be used when iterating over `T.fields`', left_pos) } + node.is_name = node.field_expr.field_name == 'name' + if mut node.field_expr.expr is ast.Ident { + node.typ_key = '${node.field_expr.expr.name}.typ' + } expr_type = c.type_resolver.get_comptime_selector_type(node, ast.void_type) if expr_type != ast.void_type { return expr_type diff --git a/vlib/v/gen/c/assign.v b/vlib/v/gen/c/assign.v index 7f9bc53f73..a62d8b80f4 100644 --- a/vlib/v/gen/c/assign.v +++ b/vlib/v/gen/c/assign.v @@ -305,15 +305,14 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { g.assign_ct_type = var_type } } else if val is ast.ComptimeSelector { - key_str := g.comptime.get_comptime_selector_key_type(val) - if key_str != '' { + if val.typ_key != '' { if is_decl { - var_type = g.type_resolver.get_ct_type_or_default(key_str, + var_type = g.type_resolver.get_ct_type_or_default(val.typ_key, var_type) val_type = var_type left.obj.typ = var_type } else { - val_type = g.type_resolver.get_ct_type_or_default(key_str, + val_type = g.type_resolver.get_ct_type_or_default(val.typ_key, var_type) } g.assign_ct_type = var_type @@ -330,14 +329,16 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { var_type = val_type.clear_flag(.option) left.obj.typ = var_type } - } else if val is ast.DumpExpr && val.expr is ast.ComptimeSelector { - key_str := g.comptime.get_comptime_selector_key_type(val.expr as ast.ComptimeSelector) - if key_str != '' { - var_type = g.type_resolver.get_ct_type_or_default(key_str, var_type) - val_type = var_type - left.obj.typ = var_type + } else if val is ast.DumpExpr { + if val.expr is ast.ComptimeSelector { + if val.expr.typ_key != '' { + var_type = g.type_resolver.get_ct_type_or_default(val.expr.typ_key, + var_type) + val_type = var_type + left.obj.typ = var_type + } + g.assign_ct_type = var_type } - g.assign_ct_type = var_type } else if val is ast.IndexExpr { if val.left is ast.Ident && g.type_resolver.is_generic_param_var(val.left) { ctyp := g.unwrap_generic(g.get_gn_var_type(val.left)) @@ -374,23 +375,20 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { is_auto_heap = left.obj.is_auto_heap } } else if mut left is ast.ComptimeSelector { - key_str := g.comptime.get_comptime_selector_key_type(left) - if key_str != '' { - var_type = g.type_resolver.get_ct_type_or_default(key_str, var_type) + if left.typ_key != '' { + var_type = g.type_resolver.get_ct_type_or_default(left.typ_key, var_type) } g.assign_ct_type = var_type if val is ast.ComptimeSelector { - key_str_right := g.comptime.get_comptime_selector_key_type(val) - if key_str_right != '' { - val_type = g.type_resolver.get_ct_type_or_default(key_str_right, var_type) + if val.typ_key != '' { + val_type = g.type_resolver.get_ct_type_or_default(val.typ_key, var_type) } } else if val is ast.CallExpr { g.assign_ct_type = g.comptime.comptime_for_field_type } } else if mut left is ast.IndexExpr && val is ast.ComptimeSelector { - key_str := g.comptime.get_comptime_selector_key_type(val) - if key_str != '' { - val_type = g.type_resolver.get_ct_type_or_default(key_str, var_type) + if val.typ_key != '' { + val_type = g.type_resolver.get_ct_type_or_default(val.typ_key, var_type) } g.assign_ct_type = val_type } diff --git a/vlib/v/gen/c/comptime.v b/vlib/v/gen/c/comptime.v index 684368654d..725b8f3550 100644 --- a/vlib/v/gen/c/comptime.v +++ b/vlib/v/gen/c/comptime.v @@ -21,10 +21,9 @@ fn (mut g Gen) comptime_selector(node ast.ComptimeSelector) { g.write('.') } // check for field.name - if node.field_expr is ast.SelectorExpr { + if node.is_name && node.field_expr is ast.SelectorExpr { if node.field_expr.expr is ast.Ident { - if node.field_expr.expr.name == g.comptime.comptime_for_field_var - && node.field_expr.field_name == 'name' { + if node.field_expr.expr.name == g.comptime.comptime_for_field_var { _, field_name := g.type_resolver.get_comptime_selector_var_type(node) g.write(c_name(field_name)) if is_interface_field { diff --git a/vlib/v/gen/c/dumpexpr.v b/vlib/v/gen/c/dumpexpr.v index 5546efa7bc..124985af58 100644 --- a/vlib/v/gen/c/dumpexpr.v +++ b/vlib/v/gen/c/dumpexpr.v @@ -32,12 +32,11 @@ fn (mut g Gen) dump_expr(node ast.DumpExpr) { } } } - // var.${field.name} - if node.expr is ast.ComptimeSelector { + // var.$(field.name) + if node.expr is ast.ComptimeSelector && node.expr.is_name { if node.expr.field_expr is ast.SelectorExpr { if node.expr.field_expr.expr is ast.Ident { - if node.expr.field_expr.expr.name == g.comptime.comptime_for_field_var - && node.expr.field_expr.field_name == 'name' { + if node.expr.field_expr.expr.name == g.comptime.comptime_for_field_var { field, _ := g.type_resolver.get_comptime_selector_var_type(node.expr) name = g.styp(g.unwrap_generic(field.typ.clear_flags(.shared_f, .result))) expr_type = field.typ diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index 9a79fc8e01..9342347b2c 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -1302,9 +1302,8 @@ fn (mut g Gen) gen_to_str_method_call(node ast.CallExpr) bool { } left_node := node.left if left_node is ast.ComptimeSelector { - key_str := g.comptime.get_comptime_selector_key_type(left_node) - if key_str != '' { - rec_type = g.type_resolver.get_ct_type_or_default(key_str, rec_type) + if left_node.typ_key != '' { + rec_type = g.type_resolver.get_ct_type_or_default(left_node.typ_key, rec_type) g.gen_expr_to_string(left_node, rec_type) return true } @@ -2274,9 +2273,8 @@ fn (mut g Gen) fn_call(node ast.CallExpr) { } else { g.write('${c_fn_name(print_method)}(') if expr is ast.ComptimeSelector { - key_str := g.comptime.get_comptime_selector_key_type(expr) - if key_str != '' { - typ = g.type_resolver.get_ct_type_or_default(key_str, typ) + if expr.typ_key != '' { + typ = g.type_resolver.get_ct_type_or_default(expr.typ_key, typ) } } else if expr is ast.ComptimeCall { if expr.method_name == 'method' { diff --git a/vlib/v/type_resolver/comptime_resolver.v b/vlib/v/type_resolver/comptime_resolver.v index 48ad48ad38..46c7cd91d5 100644 --- a/vlib/v/type_resolver/comptime_resolver.v +++ b/vlib/v/type_resolver/comptime_resolver.v @@ -13,16 +13,6 @@ pub fn (mut t TypeResolver) get_comptime_selector_var_type(node ast.ComptimeSele return field, field_name } -@[inline] -pub fn (t &ResolverInfo) get_comptime_selector_key_type(val ast.ComptimeSelector) string { - if val.field_expr is ast.SelectorExpr { - if val.field_expr.expr is ast.Ident { - return '${val.field_expr.expr.name}.typ' - } - } - return '' -} - // is_comptime_expr checks if the node is related to a comptime expr @[inline] pub fn (t &ResolverInfo) is_comptime_expr(node ast.Expr) bool { @@ -130,9 +120,8 @@ pub fn (t &TypeResolver) get_type_from_comptime_var(var ast.Ident) ast.Type { // get_comptime_selector_type retrieves the var.$(field.name) type when field_name is 'name' otherwise default_type is returned @[inline] pub fn (mut t TypeResolver) get_comptime_selector_type(node ast.ComptimeSelector, default_type ast.Type) ast.Type { - if node.field_expr is ast.SelectorExpr - && t.info.check_comptime_is_field_selector(node.field_expr) - && node.field_expr.field_name == 'name' { + if node.is_name && node.field_expr is ast.SelectorExpr + && t.info.check_comptime_is_field_selector(node.field_expr) { return t.resolver.unwrap_generic(t.info.comptime_for_field_type) } return default_type