diff --git a/.github/workflows/module_docs_ci.yml b/.github/workflows/module_docs_ci.yml index 84c4d769a6f937..3f2b108397f907 100644 --- a/.github/workflows/module_docs_ci.yml +++ b/.github/workflows/module_docs_ci.yml @@ -5,11 +5,13 @@ on: paths: - 'vlib/**.v' - 'vlib/**.md' + - 'cmd/tools/vdoc/**.v' - '**/module_docs_ci.yml' push: paths: - 'vlib/**.v' - 'vlib/**.md' + - 'cmd/tools/vdoc/**.v' - '**/module_docs_ci.yml' # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. diff --git a/.github/workflows/other_ci.yml b/.github/workflows/other_ci.yml index b70932c54fbc22..50f0d94d2b4424 100644 --- a/.github/workflows/other_ci.yml +++ b/.github/workflows/other_ci.yml @@ -1,6 +1,7 @@ name: Other CI on: + workflow_dispatch: push: paths-ignore: - '**.md' @@ -101,17 +102,17 @@ jobs: ./v retry -- sudo apt update ./v retry -- sudo apt install --quiet -y libsodium-dev libssl-dev sqlite3 libsqlite3-dev postgresql libpq-dev valgrind ./v retry -- sudo apt install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libgl-dev xfonts-75dpi xfonts-base - ./v retry -- sudo apt install --quiet -y g++-9 g++-11 + ./v retry -- sudo apt install --quiet -y g++-9 g++-10 - name: g++-9 version run: g++-9 --version - name: V self compilation with g++ and -std=c++11 run: ./v -cc g++-9 -no-std -cflags -std=c++11 -o v2 cmd/v && ./v2 -cc g++-9 -no-std -cflags -std=c++11 -o v3 cmd/v - - name: g++-11 version - run: g++-11 --version + - name: g++-10 version + run: g++-10 --version - name: V self compilation with g++ and -std=c++20 - run: ./v -cc g++-11 -no-std -cflags -std=c++20 -o v2 cmd/v && ./v2 -cc g++-11 -no-std -cflags -std=c++20 -o v3 cmd/v + run: ./v -cc g++-10 -no-std -cflags -std=c++20 -o v2 cmd/v && ./v2 -cc g++-10 -no-std -cflags -std=c++20 -o v3 cmd/v # NB: this does not mean it runs, but at least keeps it from regressing - name: Ensure V can be compiled with -autofree diff --git a/cmd/tools/vdoc/files.v b/cmd/tools/vdoc/files.v index 405d6b66c22738..db8553c7ed4f50 100644 --- a/cmd/tools/vdoc/files.v +++ b/cmd/tools/vdoc/files.v @@ -4,10 +4,11 @@ import os struct IgnoreRules { mut: - patterns map[string]bool = { - 'testdata': true - 'tests': true - '*_test.v': true + // Ignore patterns use the path with a `.vdocignore` file as a base. E.g.: + // `{'': ['', ''], '': ['']}` + patterns map[string][]string = { + // Default ignore patterns. + '': ['testdata', 'tests', '*_test.v'] } paths map[string]bool } @@ -25,19 +26,23 @@ fn get_modules(path string) []string { fn get_paths(path string, mut ignore_rules IgnoreRules) []string { mut res := []string{} - for p in os.ls(path) or { return [] } { + outer: for p in os.ls(path) or { return [] } { ignore_rules.get(path) fp := os.join_path(path, p) if fp in ignore_rules.paths { continue } is_dir := os.is_dir(fp) - if ignore_rules.patterns.keys().any(p == it - || (it.contains('*') && p.ends_with(it.all_after('*'))) - || (is_dir && it.ends_with('/') && fp.ends_with(it.trim_right('/'))) - || (!it.ends_with('/') && it.contains('/') && fp.contains(it))) - { - continue + for ignore_path, patterns in ignore_rules.patterns { + if fp.starts_with(ignore_path) { + if patterns.any(p == it + || (it.contains('*') && p.ends_with(it.all_after('*'))) + || (is_dir && it.ends_with('/') && fp.ends_with(it.trim_right('/'))) + || (!it.ends_with('/') && it.contains('/') && fp.contains(it))) + { + continue outer + } + } } if is_dir { res << get_paths(fp, mut ignore_rules) @@ -73,7 +78,7 @@ fn (mut ignore_rules IgnoreRules) get(path string) { // `/a` should ignore `/a` but not `/b/a`. While `a` should ignore `/a` and `/b/a`. ignore_rules.paths[os.join_path(path, rule.trim_left('/'))] = true } else { - ignore_rules.patterns[rule] = true + ignore_rules.patterns[path] << rule } } } diff --git a/vlib/net/unix/stream.c.v b/vlib/net/unix/stream.c.v index 0c7dfbc0319b13..7c7d77ff7bc234 100644 --- a/vlib/net/unix/stream.c.v +++ b/vlib/net/unix/stream.c.v @@ -424,7 +424,6 @@ fn (mut s StreamSocket) connect(socket_path string) ! { addr := addrs[0] // cast to the correct type alen := addr.len() - eprintln(addr) $if net_nonblocking_sockets ? { res := $if is_coroutine ? { diff --git a/vlib/v/checker/infix.v b/vlib/v/checker/infix.v index 08d87a2dc45c21..560f14bfa98fed 100644 --- a/vlib/v/checker/infix.v +++ b/vlib/v/checker/infix.v @@ -331,6 +331,12 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { } } + if ((unwrapped_left_type.is_ptr() && !node.left.is_auto_deref_var()) + || (unwrapped_right_type.is_ptr() && !node.right.is_auto_deref_var())) + && node.op !in [.plus, .minus] { + c.error('infix `${node.op}` is not defined for pointer values', left_right_pos) + } + if !c.pref.translated && left_sym.kind in [.array, .array_fixed, .map, .struct_] { if left_sym.has_method_with_generic_parent(node.op.str()) { if method := left_sym.find_method_with_generic_parent(node.op.str()) { diff --git a/vlib/v/checker/tests/disallow_pointer_arithmetic_err.out b/vlib/v/checker/tests/disallow_pointer_arithmetic_err.out index 2c2a8c0f0939c7..2c67a2ca02c19d 100644 --- a/vlib/v/checker/tests/disallow_pointer_arithmetic_err.out +++ b/vlib/v/checker/tests/disallow_pointer_arithmetic_err.out @@ -25,6 +25,13 @@ vlib/v/checker/tests/disallow_pointer_arithmetic_err.vv:5:7: error: invalid oper | ~~~~~ 6 | _ := p * 2 //should be error 7 | _ := p + 5 //OK but only in unsafe block, r is *int +vlib/v/checker/tests/disallow_pointer_arithmetic_err.vv:5:7: error: infix `*` is not defined for pointer values + 3 | p := &x + 4 | _ := p + p //should be error + 5 | _ := p * p //should be error + | ~~~~~ + 6 | _ := p * 2 //should be error + 7 | _ := p + 5 //OK but only in unsafe block, r is *int vlib/v/checker/tests/disallow_pointer_arithmetic_err.vv:6:7: error: invalid operator `*` to `&int` and `int literal` 4 | _ := p + p //should be error 5 | _ := p * p //should be error @@ -32,3 +39,10 @@ vlib/v/checker/tests/disallow_pointer_arithmetic_err.vv:6:7: error: invalid oper | ~~~~~ 7 | _ := p + 5 //OK but only in unsafe block, r is *int 8 | _ := p - p //OK even in safe code, but n should be isize +vlib/v/checker/tests/disallow_pointer_arithmetic_err.vv:6:7: error: infix `*` is not defined for pointer values + 4 | _ := p + p //should be error + 5 | _ := p * p //should be error + 6 | _ := p * 2 //should be error + | ~~~~~ + 7 | _ := p + 5 //OK but only in unsafe block, r is *int + 8 | _ := p - p //OK even in safe code, but n should be isize diff --git a/vlib/v/checker/tests/invalid_op_ptr_err.out b/vlib/v/checker/tests/invalid_op_ptr_err.out new file mode 100644 index 00000000000000..0cf09ded367bc1 --- /dev/null +++ b/vlib/v/checker/tests/invalid_op_ptr_err.out @@ -0,0 +1,14 @@ +vlib/v/checker/tests/invalid_op_ptr_err.vv:3:6: error: infix `*` is not defined for pointer values + 1 | num := 10 + 2 | p := &num + 3 | x := 5 * p + | ~~~~~ + 4 | y := 5 / p + 5 | dump(x) +vlib/v/checker/tests/invalid_op_ptr_err.vv:4:6: error: infix `/` is not defined for pointer values + 2 | p := &num + 3 | x := 5 * p + 4 | y := 5 / p + | ~~~~~ + 5 | dump(x) + 6 | dump(p) diff --git a/vlib/v/checker/tests/invalid_op_ptr_err.vv b/vlib/v/checker/tests/invalid_op_ptr_err.vv new file mode 100644 index 00000000000000..05b88977a8135d --- /dev/null +++ b/vlib/v/checker/tests/invalid_op_ptr_err.vv @@ -0,0 +1,7 @@ +num := 10 +p := &num +x := 5 * p +y := 5 / p +dump(x) +dump(p) +dump(y) diff --git a/vlib/v/checker/tests/pointer_ops.out b/vlib/v/checker/tests/pointer_ops.out index 6aa773f1069ff0..5afb7cff62d601 100644 --- a/vlib/v/checker/tests/pointer_ops.out +++ b/vlib/v/checker/tests/pointer_ops.out @@ -54,6 +54,13 @@ vlib/v/checker/tests/pointer_ops.vv:15:3: error: invalid operator `%` to `&Foo` | ~~~~~~~ 16 | } 17 | } +vlib/v/checker/tests/pointer_ops.vv:15:3: error: infix `%` is not defined for pointer values + 13 | _ = p[3] + 14 | mut foo := &Foo{} + 15 | foo % 3 + | ~~~~~~~ + 16 | } + 17 | } vlib/v/checker/tests/pointer_ops.vv:15:3: error: mismatched types `&Foo` and `int literal` 13 | _ = p[3] 14 | mut foo := &Foo{} @@ -117,6 +124,13 @@ vlib/v/checker/tests/pointer_ops.vv:30:3: error: invalid operator `%` to `&Foo` | ~~~~~~~ 31 | } 32 | } +vlib/v/checker/tests/pointer_ops.vv:30:3: error: infix `%` is not defined for pointer values + 28 | _ = p[3] + 29 | mut foo := &Foo{} + 30 | foo % 3 + | ~~~~~~~ + 31 | } + 32 | } vlib/v/checker/tests/pointer_ops.vv:30:3: error: mismatched types `&Foo` and `int literal` 28 | _ = p[3] 29 | mut foo := &Foo{}