From 2ddeaf89dc6b1a238fd781935f8e9573612165a5 Mon Sep 17 00:00:00 2001 From: yuyi Date: Thu, 21 Sep 2023 17:21:47 +0800 Subject: [PATCH] checker: fix generic comparison for conditional assignment --- vlib/v/checker/infix.v | 15 +++++++++++++ ...c_comparison_for_conditional_assign_test.v | 21 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 vlib/v/tests/generic_comparison_for_conditional_assign_test.v diff --git a/vlib/v/checker/infix.v b/vlib/v/checker/infix.v index a4b825244bd6a0..4610cc5e73ca08 100644 --- a/vlib/v/checker/infix.v +++ b/vlib/v/checker/infix.v @@ -43,6 +43,21 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { if node.op == .key_is { c.inside_x_is_type = true } + // `arr << if n > 0 { 10 } else { 11 }` set the right c.expected_type + if node.op == .left_shift && c.table.sym(left_type).kind == .array { + if mut node.right is ast.IfExpr { + if node.right.is_expr && node.right.branches.len > 0 { + mut last_stmt := node.right.branches[0].stmts.last() + if mut last_stmt is ast.ExprStmt { + expr_typ := c.expr(mut last_stmt.expr) + info := c.table.sym(left_type).array_info() + if expr_typ == info.elem_type { + c.expected_type = info.elem_type + } + } + } + } + } mut right_type := c.expr(mut node.right) if node.op == .key_is { c.inside_x_is_type = false diff --git a/vlib/v/tests/generic_comparison_for_conditional_assign_test.v b/vlib/v/tests/generic_comparison_for_conditional_assign_test.v new file mode 100644 index 00000000000000..078c9690e5a749 --- /dev/null +++ b/vlib/v/tests/generic_comparison_for_conditional_assign_test.v @@ -0,0 +1,21 @@ +fn clip[N](x []N, min N, max N) []N { + mut result := []N{cap: x.len} + for value in x { + result << if value < min { + min + } else if value > max { + max + } else { + value + } + } + return result +} + +fn test_generic_comparison_for_conditional_assign() { + a := [1, 2, 3, 4, 5] + dump(a) + b := clip(a, 2, 4) + dump(b) + assert b == [2, 2, 3, 4, 4] +}