From db525108ae5b2950e845895ac263a4593e459ea4 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sat, 9 Nov 2024 08:40:39 -0300 Subject: [PATCH] cgen,comptime: fix wrong type resolution on infix (#22804) --- vlib/v/comptime/comptimeinfo.v | 10 +++++++--- vlib/v/gen/c/infix.v | 12 ++---------- vlib/v/tests/comptime/comptime_infix_test.v | 18 ++++++++++++++++++ 3 files changed, 27 insertions(+), 13 deletions(-) create mode 100644 vlib/v/tests/comptime/comptime_infix_test.v diff --git a/vlib/v/comptime/comptimeinfo.v b/vlib/v/comptime/comptimeinfo.v index f16f39dfa..18465672d 100644 --- a/vlib/v/comptime/comptimeinfo.v +++ b/vlib/v/comptime/comptimeinfo.v @@ -66,18 +66,22 @@ pub fn (mut ct ComptimeInfo) is_generic_param_var(node ast.Expr) bool { && (node.obj as ast.Var).ct_type_var == .generic_param } -// get_expr_type computes the ast node type regarding its or_expr -pub fn (mut ct ComptimeInfo) get_expr_type(node ast.Expr) ast.Type { +// get_expr_type_or_default computes the ast node type regarding its or_expr if its comptime var otherwise default_typ is returned +pub fn (mut ct ComptimeInfo) get_expr_type_or_default(node ast.Expr, default_typ ast.Type) ast.Type { + if !ct.is_comptime_expr(node) { + return default_typ + } ctyp := ct.get_type(node) match node { ast.Ident { + // returns the unwrapped type of the var if ctyp.has_flag(.option) && node.or_expr.kind != .absent { return ctyp.clear_flag(.option) } } else {} } - return ctyp + return if ctyp != ast.void_type { ctyp } else { default_typ } } // get_type_or_default retries the comptime value if the AST node is related to comptime otherwise default_typ is returned diff --git a/vlib/v/gen/c/infix.v b/vlib/v/gen/c/infix.v index 45cf38b6f..ee7dad41f 100644 --- a/vlib/v/gen/c/infix.v +++ b/vlib/v/gen/c/infix.v @@ -96,16 +96,8 @@ fn (mut g Gen) infix_expr_arrow_op(node ast.InfixExpr) { // infix_expr_eq_op generates code for `==` and `!=` fn (mut g Gen) infix_expr_eq_op(node ast.InfixExpr) { - left_type := if g.comptime.is_comptime_expr(node.left) { - g.comptime.get_expr_type(node.left) - } else { - node.left_type - } - right_type := if g.comptime.is_comptime_expr(node.right) { - g.comptime.get_expr_type(node.right) - } else { - node.right_type - } + left_type := g.comptime.get_expr_type_or_default(node.left, node.left_type) + right_type := g.comptime.get_expr_type_or_default(node.right, node.right_type) left := g.unwrap(left_type) right := g.unwrap(right_type) mut has_defined_eq_operator := false diff --git a/vlib/v/tests/comptime/comptime_infix_test.v b/vlib/v/tests/comptime/comptime_infix_test.v new file mode 100644 index 000000000..b0f34b7f7 --- /dev/null +++ b/vlib/v/tests/comptime/comptime_infix_test.v @@ -0,0 +1,18 @@ +pub fn get_first[T](arr []T) T { + mut first := arr[0] + for i, v in arr { + if i == 0 { + first = v + } + if first == v { + break + } + } + return first +} + +fn test_main() { + assert get_first(['foo', 'bar']) == 'foo' + assert get_first([1, 2]) == 1 + assert get_first([1.2, 2.0]) == 1.2 +} -- 2.39.5