diff --git a/cmd/tools/vdoc/highlight.v b/cmd/tools/vdoc/highlight.v index b641b0cc28f746..ca0279627a8fba 100644 --- a/cmd/tools/vdoc/highlight.v +++ b/cmd/tools/vdoc/highlight.v @@ -83,7 +83,7 @@ fn color_highlight(code string, tb &ast.Table) string { && (next_tok.kind != .lpar || prev.kind !in [.key_fn, .rpar]) { tok_typ = .builtin } else if - (next_tok.kind in [.lcbr, .rpar, .eof, .comma, .pipe, .name, .rcbr, .assign, .key_pub, .key_mut, .pipe, .comma, .comment, .lt, .lsbr] + (next_tok.kind in [.lcbr, .rpar, .eof, .name, .rcbr, .assign, .key_pub, .key_mut, .pipe, .comma, .comment, .lt, .lsbr] && next_tok.lit !in highlight_builtin_types) && (prev.kind in [.name, .amp, .lcbr, .rsbr, .key_type, .assign, .dot, .not, .question, .rpar, .key_struct, .key_enum, .pipe, .key_interface, .comment, .ellipsis, .comma] && prev.lit !in highlight_builtin_types) diff --git a/vlib/v/checker/infix.v b/vlib/v/checker/infix.v index 3187823758f46b..06327571f4f21e 100644 --- a/vlib/v/checker/infix.v +++ b/vlib/v/checker/infix.v @@ -241,6 +241,9 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { c.error('left operand to `${node.op}` does not match the array element type: ${err.msg()}', left_right_pos) } + if mut node.right is ast.ArrayInit { + c.check_duplicated_items(node.right) + } } else { if mut node.right is ast.ArrayInit { for i, typ in node.right.expr_types { @@ -953,6 +956,18 @@ fn (mut c Checker) check_div_mod_by_zero(expr ast.Expr, op_kind token.Kind) { } } +fn (mut c Checker) check_duplicated_items(node &ast.ArrayInit) { + mut unique_items := []string{cap: node.exprs.len} + for item in node.exprs { + item_str := item.str() + if item_str in unique_items { + c.note('item `${item_str}` is duplicated in the list', item.pos()) + } else { + unique_items << item_str + } + } +} + fn (mut c Checker) check_like_operator(node &ast.InfixExpr) ast.Type { if node.left !is ast.Ident || !node.left_type.is_string() { c.error('the left operand of the `like` operator must be an identifier with a string type', diff --git a/vlib/v/checker/str.v b/vlib/v/checker/str.v index c196f2056f9351..142a4e42e6b617 100644 --- a/vlib/v/checker/str.v +++ b/vlib/v/checker/str.v @@ -96,8 +96,7 @@ fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) ast.Type { } if ((typ.is_unsigned() && fmt !in [`u`, `x`, `X`, `o`, `c`, `b`]) || (typ.is_signed() && fmt !in [`d`, `x`, `X`, `o`, `c`, `b`]) - || (typ.is_int_literal() - && fmt !in [`d`, `c`, `x`, `X`, `o`, `u`, `x`, `X`, `o`, `b`]) + || (typ.is_int_literal() && fmt !in [`d`, `c`, `x`, `X`, `o`, `u`, `b`]) || (typ.is_float() && fmt !in [`E`, `F`, `G`, `e`, `f`, `g`]) || (typ.is_pointer() && fmt !in [`p`, `x`, `X`]) || (typ.is_string() && fmt !in [`s`, `S`, `r`, `R`]) diff --git a/vlib/v/checker/tests/infix_dup_in_err.out b/vlib/v/checker/tests/infix_dup_in_err.out new file mode 100644 index 00000000000000..4feb328daf69c9 --- /dev/null +++ b/vlib/v/checker/tests/infix_dup_in_err.out @@ -0,0 +1,12 @@ +vlib/v/checker/tests/infix_dup_in_err.vv:1:16: notice: item `2` is duplicated in the list + 1 | if 1 in [1, 2, 2, 2] { println('ok') } + | ^ + 2 | + 3 | a := `a` +vlib/v/checker/tests/infix_dup_in_err.vv:4:20: notice: item `a` is duplicated in the list + 2 | + 3 | a := `a` + 4 | if `a` in [`c`, a, a] { println('ok') } + | ^ + 5 | + 6 | println('done') diff --git a/vlib/v/checker/tests/infix_dup_in_err.vv b/vlib/v/checker/tests/infix_dup_in_err.vv new file mode 100644 index 00000000000000..06b9e37b9337d4 --- /dev/null +++ b/vlib/v/checker/tests/infix_dup_in_err.vv @@ -0,0 +1,6 @@ +if 1 in [1, 2, 2, 2] { println('ok') } + +a := `a` +if `a` in [`c`, a, a] { println('ok') } + +println('done') \ No newline at end of file