From 6bfb459c61a2c69a93e2bc437d00b8f4421ed98d Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Thu, 23 Apr 2026 18:19:43 +0300 Subject: [PATCH] parser: fix Failed to compile `mut threads := [4]thread (int64, int){}` with multiple values (fixes #26795) --- vlib/v/parser/expr.v | 6 ++++-- .../v/tests/concurrency/thread_returns_test.v | 20 +++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/vlib/v/parser/expr.v b/vlib/v/parser/expr.v index 4df88d2b4..f8993d424 100644 --- a/vlib/v/parser/expr.v +++ b/vlib/v/parser/expr.v @@ -330,8 +330,10 @@ fn (mut p Parser) check_expr(precedence int) !ast.Expr { } mut is_cast_expr := peek_n_tok.kind == .lpar && sbr_level == 0 && peek_n_tok.line_nr == line_nr - // `[](?Type){}` (and `[N](?Type){}`) is an array init, not a cast. - if is_cast_expr && prev_n_tok.kind == .rsbr { + // If the matching `)` is followed by `{`, this can still be an array init when + // the element type itself contains parentheses, e.g. `[](?Type){}` or + // `[]thread (T1, T2){}`. + if is_cast_expr && (prev_n_tok.kind == .rsbr || prev_n_tok.lit == 'thread') { mut par_level := 0 for i := n; true; i++ { tk := p.peek_token(i) diff --git a/vlib/v/tests/concurrency/thread_returns_test.v b/vlib/v/tests/concurrency/thread_returns_test.v index de2c70e1a..cea5c54e2 100644 --- a/vlib/v/tests/concurrency/thread_returns_test.v +++ b/vlib/v/tests/concurrency/thread_returns_test.v @@ -41,3 +41,23 @@ fn test_main() { mut foo := Foo.new() foo.bar() } + +fn test_arrays_of_threads_with_multi_returns() { + mut threads := []thread (int, int){} + for _ in 0 .. 2 { + threads << spawn get_multi_returns() + } + for thr in threads { + a, b := thr.wait() + assert a == 1 && b == 2 + } + + mut fixed_threads := [2]thread (int, int){} + for i in 0 .. fixed_threads.len { + fixed_threads[i] = spawn get_multi_returns() + } + for thr in fixed_threads { + a, b := thr.wait() + assert a == 1 && b == 2 + } +} -- 2.39.5