From 70f685ba46c238cde8793d7761603c47287997c9 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Fri, 27 Dec 2024 09:04:08 -0300 Subject: [PATCH] fix --- vlib/v/ast/ast.v | 15 ++++++++------- vlib/v/checker/infix.v | 31 +++++++++++++++++-------------- vlib/v/comptime/comptimeinfo.v | 33 +++++++++++++++++++++++++++++++++ vlib/v/gen/c/infix.v | 12 ++++++++---- vlib/v/parser/fn.v | 2 +- 5 files changed, 67 insertions(+), 26 deletions(-) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 1f39d9a326f2a3..fb8a4d71ccc1d1 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -1625,13 +1625,14 @@ pub mut: @[minify] pub struct CastExpr { pub mut: - arg Expr // `n` in `string(buf, n)` - typ Type // `string` - expr Expr // `buf` in `string(buf, n)` and `&Type(buf)` - typname string // `&Type` in `&Type(buf)` - expr_type Type // `byteptr`, the type of the `buf` expression - has_arg bool // true for `string(buf, n)`, false for `&Type(buf)` - pos token.Pos + arg Expr // `n` in `string(buf, n)` + typ Type // `string` + expr Expr // `buf` in `string(buf, n)` and `&Type(buf)` + typname string // `&Type` in `&Type(buf)` + expr_type Type // `byteptr`, the type of the `buf` expression + has_arg bool // true for `string(buf, n)`, false for `&Type(buf)` + pos token.Pos + is_generated bool // true when added by Checker } @[minify] diff --git a/vlib/v/checker/infix.v b/vlib/v/checker/infix.v index 21825362df54f2..4340385a0693ad 100644 --- a/vlib/v/checker/infix.v +++ b/vlib/v/checker/infix.v @@ -84,11 +84,12 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { if left_type in [ast.f32_type_idx, ast.f64_type_idx] && right_type == ast.float_literal_type { defer { node.right = ast.CastExpr{ - expr: node.right - typ: left_type - typname: c.table.get_type_name(left_type) - expr_type: right_type - pos: node.right.pos() + expr: node.right + typ: left_type + typname: c.table.get_type_name(left_type) + expr_type: right_type + pos: node.right.pos() + is_generated: true } } } @@ -99,10 +100,11 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { if right_type in [ast.f32_type_idx, ast.f64_type_idx] && left_type == ast.float_literal_type { defer { node.left = ast.CastExpr{ - expr: node.left - typ: right_type - typname: c.table.get_type_name(right_type) - expr_type: left_type + expr: node.left + typ: right_type + typname: c.table.get_type_name(right_type) + expr_type: left_type + is_generated: true } } } @@ -732,11 +734,12 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { node = ast.InfixExpr{ left: ast.CastExpr{ - expr: node.left - typ: modified_left_type - typname: c.table.type_str(modified_left_type) - expr_type: left_type - pos: node.pos + expr: node.left + typ: modified_left_type + typname: c.table.type_str(modified_left_type) + expr_type: left_type + pos: node.pos + is_generated: true } left_type: left_type op: .right_shift diff --git a/vlib/v/comptime/comptimeinfo.v b/vlib/v/comptime/comptimeinfo.v index 2de799a049c2b1..e61a2f8ddb87d0 100644 --- a/vlib/v/comptime/comptimeinfo.v +++ b/vlib/v/comptime/comptimeinfo.v @@ -61,6 +61,21 @@ pub fn (mut ct ComptimeInfo) is_comptime(node ast.Expr) bool { false } } + ast.SelectorExpr { + return node.expr is ast.Ident && node.expr.ct_expr + } + ast.CastExpr { + if node.is_generated { + if node.expr is ast.InfixExpr { + return ct.is_comptime(node.expr.left) || ct.is_comptime(node.expr.right) + } + return ct.is_comptime(node.expr) + } + return false + } + ast.ParExpr { + return ct.is_comptime(node.expr) + } else { false } @@ -120,6 +135,22 @@ pub fn (mut ct ComptimeInfo) get_type_or_default(node ast.Expr, default_typ ast. return if ctyp != ast.void_type { ctyp } else { default_typ } } } + ast.SelectorExpr { + if node.expr is ast.Ident && node.expr.ct_expr { + struct_typ := ct.resolver.unwrap_generic(ct.get_type(node.expr)) + if field := ct.table.find_field(ct.table.sym(struct_typ), node.field_name) { + return field.typ + } + } + } + ast.ParExpr { + return ct.get_type_or_default(node.expr, default_typ) + } + ast.CastExpr { + if node.is_generated { + return ct.get_type_or_default(node.expr, default_typ) + } + } else { return default_typ } @@ -184,6 +215,8 @@ pub fn (mut ct ComptimeInfo) get_type(node ast.Expr) ast.Type { nltype := ct.get_type(node.left) nltype_unwrapped := ct.resolver.unwrap_generic(nltype) return ct.table.value_type(nltype_unwrapped) + } else if node is ast.SelectorExpr && ct.is_comptime(node.expr) { + println('>>> ${node.expr}') } return ast.void_type } diff --git a/vlib/v/gen/c/infix.v b/vlib/v/gen/c/infix.v index c33b40a131d79b..8458b6890cdd3e 100644 --- a/vlib/v/gen/c/infix.v +++ b/vlib/v/gen/c/infix.v @@ -925,8 +925,8 @@ fn (mut g Gen) gen_interface_is_op(node ast.InfixExpr) { // infix_expr_arithmetic_op generates code for `+`, `-`, `*`, `/`, and `%` // It handles operator overloading when necessary fn (mut g Gen) infix_expr_arithmetic_op(node ast.InfixExpr) { - left := g.unwrap(node.left_type) - right := g.unwrap(node.right_type) + left := g.unwrap(g.comptime.get_type_or_default(node.left, node.left_type)) + right := g.unwrap(g.comptime.get_type_or_default(node.right, node.right_type)) if left.sym.info is ast.Struct && left.sym.info.generic_types.len > 0 { mut method_name := left.sym.cname + '_' + util.replace_op(node.op.str()) method_name = g.generic_fn_name(left.sym.info.concrete_types, method_name) @@ -1188,8 +1188,12 @@ fn (mut g Gen) gen_plain_infix_expr(node ast.InfixExpr) { && node.op in [.plus, .minus, .mul, .div, .mod] && !(g.pref.translated || g.file.is_translated) if needs_cast { - typ_str := g.styp(node.promoted_type) - g.write('(${typ_str})(') + typ_str := if g.comptime.is_comptime(node.left) { + g.styp(g.comptime.get_type(node.left)) + } else { + g.styp(node.promoted_type) + } + g.write('(${typ_str}/*${node.left}*/)(') } if node.left_type.is_ptr() && node.left.is_auto_deref_var() && !node.right_type.is_pointer() { g.write('*') diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index f265820c7347f3..7df0d5372c77b0 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -512,7 +512,7 @@ run them via `v file.v` instead', pos: param.pos is_used: is_pub || no_body || (is_method && k == 0) || p.builtin_mod is_arg: true - ct_type_var: if (!is_method || k > 0) && param.typ.has_flag(.generic) + ct_type_var: if (!is_method || k >= 0) && param.typ.has_flag(.generic) && !param.typ.has_flag(.variadic) { .generic_param } else {