Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compiler bug: go fn (){ go func() }() #21433

Open
vcker opened this issue May 5, 2024 · 1 comment
Open

Compiler bug: go fn (){ go func() }() #21433

vcker opened this issue May 5, 2024 · 1 comment
Labels
Bug This tag is applied to issues which reports bugs. Compiler Panic The V compiler itself paniced. It should not, it should produce nice and readable errors instead. Status: Confirmed This bug has been confirmed to be valid by a contributor. Unit: Checker Bugs/feature requests, that are related to the type checker.

Comments

@vcker
Copy link
Contributor

vcker commented May 5, 2024

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.

@vcker vcker added the Bug This tag is applied to issues which reports bugs. label May 5, 2024
@spytheman
Copy link
Member

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.

@spytheman spytheman added Compiler Panic The V compiler itself paniced. It should not, it should produce nice and readable errors instead. Status: Confirmed This bug has been confirmed to be valid by a contributor. Unit: Checker Bugs/feature requests, that are related to the type checker. labels May 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug This tag is applied to issues which reports bugs. Compiler Panic The V compiler itself paniced. It should not, it should produce nice and readable errors instead. Status: Confirmed This bug has been confirmed to be valid by a contributor. Unit: Checker Bugs/feature requests, that are related to the type checker.
Projects
None yet
Development

No branches or pull requests

2 participants