diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 2f82ed82a4..1d3488b27c 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -651,7 +651,8 @@ pub fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { } return ast.bool_type } - .plus, .minus, .mul, .div, .mod, .xor, .amp, .pipe { // binary operators that expect matching types + .plus, .minus, .mul, .div, .mod, .xor, .amp, .pipe { + // binary operators that expect matching types if right_sym.info is ast.Alias && (right_sym.info as ast.Alias).language != .c && c.mod == c.table.type_to_str(right_type).split('.')[0] && c.table.sym((right_sym.info as ast.Alias).parent_type).is_primitive() { @@ -3515,9 +3516,9 @@ pub fn (mut c Checker) postfix_expr(mut node ast.PostfixExpr) ast.Type { if !c.inside_unsafe && is_non_void_pointer && !node.expr.is_auto_deref_var() { c.warn('pointer arithmetic is only allowed in `unsafe` blocks', node.pos) } - if !(typ_sym.is_number() || (c.inside_unsafe && is_non_void_pointer)) { - c.error('invalid operation: $node.op.str() (non-numeric type `$typ_sym.name`)', - node.pos) + if !(typ_sym.is_number() || ((c.inside_unsafe || c.pref.translated) && is_non_void_pointer)) { + typ_str := c.table.type_to_str(typ) + c.error('invalid operation: $node.op.str() (non-numeric type `$typ_str`)', node.pos) } else { node.auto_locked, _ = c.fail_if_immutable(node.expr) } diff --git a/vlib/v/checker/tests/pointer_ops.out b/vlib/v/checker/tests/pointer_ops.out index 022111696c..ce4017f43a 100644 --- a/vlib/v/checker/tests/pointer_ops.out +++ b/vlib/v/checker/tests/pointer_ops.out @@ -39,11 +39,18 @@ vlib/v/checker/tests/pointer_ops.vv:10:3: error: operator `-=` not defined on le 10 | p -= 3 | ^ 11 | _ = p[3] - 12 | } + 12 | mut foo := &Foo{} vlib/v/checker/tests/pointer_ops.vv:11:8: error: type `voidptr` does not support indexing 9 | p-- 10 | p -= 3 11 | _ = p[3] | ~~~ - 12 | } - 13 | } + 12 | mut foo := &Foo{} + 13 | foo % 3 +vlib/v/checker/tests/pointer_ops.vv:13:3: error: invalid operator `%` to `&Foo` and `int literal` + 11 | _ = p[3] + 12 | mut foo := &Foo{} + 13 | foo % 3 + | ~~~~~~~ + 14 | } + 15 | } diff --git a/vlib/v/checker/tests/pointer_ops.vv b/vlib/v/checker/tests/pointer_ops.vv index e93161b675..37a4554da1 100644 --- a/vlib/v/checker/tests/pointer_ops.vv +++ b/vlib/v/checker/tests/pointer_ops.vv @@ -9,5 +9,9 @@ fn test_voidptr() { p-- p -= 3 _ = p[3] + mut foo := &Foo{} + foo % 3 } } + +struct Foo{} diff --git a/vlib/v/util/util.v b/vlib/v/util/util.v index 13aa0602f3..67a17f286e 100644 --- a/vlib/v/util/util.v +++ b/vlib/v/util/util.v @@ -41,6 +41,7 @@ const builtin_module_names = ['builtin', 'strconv', 'strings', 'dlmalloc'] pub fn module_is_builtin(mod string) bool { // NOTE: using util.builtin_module_parts here breaks -usecache on macos return mod in util.builtin_module_names + // return mod in util.builtin_module_parts } pub fn tabs(n int) string {