v
v copied to clipboard
Compiler bug: `go fn (){ go func() }()`
trafficstars
Describe the bug
this compile error
pub fn (mut me Exchange) start() ! {
go fn () {
mut rconn := net.dial_tcp(me.raddr)!
go me.exchange(me.lconn, mut rconn)
go me.exchange(rconn, mut me.lconn)
_ = <-me.end_sig
me.lconn.close() or {} // ignore
rconn.close() or {} // ignore
println('all exchange end')
}()
}
V panic: final_sym: invalid type (typ=ast.Type(0x0 = 0) idx=0). Compiler bug. This should never happen. Please report the bug using `v bug file.v`.
v hash: 065399e
0 v 0x0000000106d4a4a1 v__ast__default_table_panic_handler + 33
1 v 0x0000000106d4a4f8 v__ast__Table_panic + 72
2 v 0x0000000106d581f2 v__ast__Table_final_sym + 466
3 v 0x0000000106e14441 v__checker__Checker_spawn_expr + 257
4 v 0x0000000106da7b7a v__checker__Checker_expr + 7722
5 v 0x0000000106dc43cf v__checker__Checker_stmt + 1919
6 v 0x0000000106dd5ff7 v__checker__Checker_stmts_ending_with_expression + 631
7 v 0x0000000106df2568 v__checker__Checker_stmts + 56
8 v 0x0000000106e0a29c v__checker__Checker_anon_fn + 1836
9 v 0x0000000106da60ff v__checker__Checker_expr + 943
10 v 0x0000000106e0cea7 v__checker__Checker_call_expr + 439
11 v 0x0000000106e14360 v__checker__Checker_spawn_expr + 32
12 v 0x0000000106da7b7a v__checker__Checker_expr + 7722
13 v 0x0000000106dc43cf v__checker__Checker_stmt + 1919
14 v 0x0000000106dd5ff7 v__checker__Checker_stmts_ending_with_expression + 631
15 v 0x0000000106df2568 v__checker__Checker_stmts + 56
16 v 0x0000000106df7ce8 v__checker__Checker_fn_decl + 22376
17 v 0x0000000106dc46b7 v__checker__Checker_stmt + 2663
18 v 0x0000000106dc3b23 v__checker__Checker_check + 4259
19 v 0x0000000106dc5573 v__checker__Checker_check_files + 371
20 v 0x0000000107030ba8 v__builder__Builder_middle_stages + 216
21 v 0x0000000107033098 v__builder__Builder_front_and_middle_stages + 120
22 v 0x000000010704a492 v__builder__cbuilder__gen_c + 66
23 v 0x000000010704a2b6 v__builder__cbuilder__build_c + 294
24 v 0x000000010704a15f v__builder__cbuilder__compile_c + 543
25 v 0x00000001070421d1 v__builder__Builder_rebuild + 81
26 v 0x00000001070419d8 v__builder__compile + 88
27 v 0x000000010704d5d9 main__rebuild + 121
28 v 0x000000010704c79a main__main + 2186
29 v 0x000000010705216b main + 59
30 dyld 0x0000000110ed44fe start + 462
put fn(){}() to start_2, it compil ok
pub fn (mut me Exchange) start() ! {
go me.start_2()
}
pub fn (mut me Exchange) start_2() ! {
mut rconn := net.dial_tcp(me.raddr)!
go me.exchange(me.lconn, mut rconn)
go me.exchange(rconn, mut me.lconn)
_ = <-me.end_sig
me.lconn.close() or {} // ignore
rconn.close() or {} // ignore
println('all exchange end')
}
Reproduction Steps
v fmt -w exchange.v && v run exchange.v
Expected Behavior
no compile error
Current Behavior
V panic: final_sym: invalid type (typ=ast.Type(0x0 = 0) idx=0). Compiler bug. This should never happen. Please report the bug using `v bug file.v`.
v hash: 065399e
0 v 0x0000000106d4a4a1 v__ast__default_table_panic_handler + 33
1 v 0x0000000106d4a4f8 v__ast__Table_panic + 72
2 v 0x0000000106d581f2 v__ast__Table_final_sym + 466
3 v 0x0000000106e14441 v__checker__Checker_spawn_expr + 257
4 v 0x0000000106da7b7a v__checker__Checker_expr + 7722
5 v 0x0000000106dc43cf v__checker__Checker_stmt + 1919
6 v 0x0000000106dd5ff7 v__checker__Checker_stmts_ending_with_expression + 631
7 v 0x0000000106df2568 v__checker__Checker_stmts + 56
8 v 0x0000000106e0a29c v__checker__Checker_anon_fn + 1836
9 v 0x0000000106da60ff v__checker__Checker_expr + 943
10 v 0x0000000106e0cea7 v__checker__Checker_call_expr + 439
11 v 0x0000000106e14360 v__checker__Checker_spawn_expr + 32
12 v 0x0000000106da7b7a v__checker__Checker_expr + 7722
13 v 0x0000000106dc43cf v__checker__Checker_stmt + 1919
14 v 0x0000000106dd5ff7 v__checker__Checker_stmts_ending_with_expression + 631
15 v 0x0000000106df2568 v__checker__Checker_stmts + 56
16 v 0x0000000106df7ce8 v__checker__Checker_fn_decl + 22376
17 v 0x0000000106dc46b7 v__checker__Checker_stmt + 2663
18 v 0x0000000106dc3b23 v__checker__Checker_check + 4259
19 v 0x0000000106dc5573 v__checker__Checker_check_files + 371
20 v 0x0000000107030ba8 v__builder__Builder_middle_stages + 216
21 v 0x0000000107033098 v__builder__Builder_front_and_middle_stages + 120
22 v 0x000000010704a492 v__builder__cbuilder__gen_c + 66
23 v 0x000000010704a2b6 v__builder__cbuilder__build_c + 294
24 v 0x000000010704a15f v__builder__cbuilder__compile_c + 543
25 v 0x00000001070421d1 v__builder__Builder_rebuild + 81
26 v 0x00000001070419d8 v__builder__compile + 88
27 v 0x000000010704d5d9 main__rebuild + 121
28 v 0x000000010704c79a main__main + 2186
29 v 0x000000010705216b main + 59
30 dyld 0x0000000110ed44fe start + 462
Possible Solution
No response
Additional Information/Context
// whole file
module main
import net
import time
struct Exchange {
mut:
is_end bool
end_sig chan bool = chan bool{cap: 1}
raddr string
// TLS
lconn &net.TcpConn
}
fn new_exchange(lconn &net.TcpConn, remoteAddr string) Exchange {
return Exchange{
raddr: remoteAddr
lconn: lconn
}
}
pub fn (mut me Exchange) start() ! {
// go me.start_2()
go fn () {
mut rconn := net.dial_tcp(me.raddr)!
go me.exchange(me.lconn, mut rconn)
go me.exchange(rconn, mut me.lconn)
_ = <-me.end_sig
me.lconn.close() or {} // ignore
rconn.close() or {} // ignore
println('all exchange end')
}()
}
pub fn (mut me Exchange) start_2() ! {
mut rconn := net.dial_tcp(me.raddr)!
go me.exchange(me.lconn, mut rconn)
go me.exchange(rconn, mut me.lconn)
_ = <-me.end_sig
me.lconn.close() or {} // ignore
rconn.close() or {} // ignore
println('all exchange end')
}
fn (mut me Exchange) exchange(from net.TcpConn, mut to net.TcpConn) {
mut buf := []u8{len: 1024}
mut num_read := 0
mut num_write := 0
for {
num_read = from.read(mut buf) or {
println('xxxx from.read: ${err}')
-1
}
if num_read <= 0 {
me.end()
break
}
num_write = to.write_ptr(buf[0], num_read) or {
println('to.write_ptr error: ${err}')
-1
}
if num_read != num_write {
println('xxxx write faild')
me.end()
break
}
}
}
fn (mut me Exchange) end() {
if me.is_end {
return
}
me.is_end = true
me.end_sig <- true
}
struct ReverseProxy {
local string
remote string
mut:
running bool
}
fn new_reverse_proxy(local string, remote string) ReverseProxy {
return ReverseProxy{
local: local
remote: remote
}
}
fn (mut me ReverseProxy) serve() ! {
mut server := net.listen_tcp(.ip, me.local) or {
println('xxxx net.listen_tcp: ${err}')
panic(err)
}
println('proxy listen: ${server.addr()!}')
me.running = true
for ; me.running; {
mut lconn := server.accept()!
if !me.running {
break
}
println('accept new connect')
mut e := new_exchange(lconn, me.remote)
e.start() or { println('xxxx start: ${err}') }
}
println('serve end')
}
fn (mut me ReverseProxy) quit() {
me.running = false
mut rconn := net.dial_tcp(me.local) or { &net.TcpConn{} } // ignore
rconn.close() or {} // ignore
}
fn main() {
mut rp := new_reverse_proxy(':9923', '45.56.81.220:80')
go fn (mut rproxy ReverseProxy) {
time.sleep(10000 * time.millisecond)
rproxy.quit()
}(mut &rp)
rp.serve() or { println('xxxx listen: ${err}') }
}
V version
0.4.5 065399e
Environment details (OS name and version, etc.)
Darwin 21.1.0 Darwin Kernel Version 21.1.0: Wed Oct 13 17:33:23 PDT 2021; root:xnu-8019.41.5~1/RELEASE_X86_64 x86_64
[!NOTE] You can use the 👍 reaction to increase the issue's priority for developers.
Please note that only the 👍 reaction to the issue itself counts as a vote. Other reactions and those to comments will not be taken into account.
This triggers the same or very similar compiler panic:
fn f() ! {
go fn () {
mut x := 123
go g(mut x)
}()
}
It does not happen without the mut x argument to go g(); then it is a normal checker error.
No cgen error anymore.
bug.v:4:12: error: unknown function: g
2 | go fn () {
3 | mut x := 123
4 | go g(mut x)
| ~~~~~~~~
5 | }()
6 | }
bug.v:4:12: error: invalid expr
2 | go fn () {
3 | mut x := 123
4 | go g(mut x)
| ~~~~~~~~
5 | }()
6 | }