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

./v test vlib/v/tests/generics_chans_select_test.v fails #20298

Closed
bakul opened this issue Dec 28, 2023 · 5 comments · Fixed by #20327
Closed

./v test vlib/v/tests/generics_chans_select_test.v fails #20298

bakul opened this issue Dec 28, 2023 · 5 comments · Fixed by #20327
Assignees
Labels
Bug This tag is applied to issues which reports bugs. Status: Confirmed This bug has been confirmed to be valid by a contributor. Unit: cgen Bugs/feature requests, that are related to the default C generating backend. Unit: Compiler Bugs/feature requests, that are related to the V compiler in general.

Comments

@bakul
Copy link
Contributor

bakul commented Dec 28, 2023

Describe the bug

This is on FreeBSD-14.0-p4. I did a fresh install of v with git clone & gmake. There is a problem wit tcc so I removed thirdparty/tcc. Running the above test fails. Every other test succeeds.

Reproduction Steps

Do a fresh install on a freebsd-14.0 machine (patch number doesn't matter). Make sure boehm-gc-threaded pkg is installed. Then gmake, remove thirdparty/gcc and then run the above test.

Expected Behavior

The test should pass.

Current Behavior

See below

Possible Solution

No idea.

Additional Information/Context

./v test vlib/v/tests/generics_chans_select_test.v
---- Testing... -----------------------------------------------------------------
 FAIL   724.968 ms vlib/v/tests/generics_chans_select_test.v
==================
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/tmp/v_1001/tsession_262e37012000_705016034380/generics_chans_select_test.17295752555952635124.tmp.c:25386:6: error: incompatible pointer to integer conversion assigning to 'bool' (aka 'unsigned char') from 'anon_fn_main__foo__bool' (aka 'unsigned char (*)(struct main__Foo)') [-Wint-conversion]
                        b = ( (*(anon_fn_main__foo__bool*)_t5.data));
                          ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/tmp/v_1001/tsession_262e37012000_705016034380/generics_chans_select_test.17295752555952635124.tmp.c:25387:4: warning: expression result unused [-Wunused-value]
                        e;
                        ^
/tmp/v_1001/tsession_262e37012000_705016034380/generics_chans_select_test.17295752555952635124.tmp.c:25452:6: error: incompatible pointer to integer conversion assigning to 'bool' (aka 'unsigned char') from 'anon_fn_main__bar__bool' (aka 'unsigned char (*)(struct main__Bar)') [-Wint-conversion]
                        b = ( (*(anon_fn_main__bar__bool*)_t5.data));
                          ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/tmp/v_1001/tsession_262e37012000_705016034380/generics_chans_select_test.17295752555952635124.tmp.c:25453:4: warning: expression result unused [-Wunused-value]
                        e;
...
==================
(Use `v -cg` to print the entire error message)

builder error:
==================
C error. This should never happen.

This is a compiler bug, please report it using `v bug file.v`.

https://github.com/vlang/v/issues/new/choose

You can also use #help on Discord: https://discord.gg/vlang

---------------------------------------------------------------------------------
Failed command 1:    '/home/bakul/v/v'   -o '/tmp/v_1001/tsession_262e37012000_705016034380/01HJS780B8S78RYTHJSNTT2VPZ/generics_chans_select_test' '/home/bakul/v/vlib/v/tests/generics_chans_select_test.v'
Summary for all V _test.v files: 1 failed, 1 total. Runtime: 730 ms, on 1 job.

V version

V 0.4.3 680b0d4

Environment details (OS name and version, etc.)

V full version: V 0.4.3 2dce525.680b0d4
OS: freebsd, 14.0-RELEASE-p4, FreeBSD 14.0-RELEASE-p4 #47 releng/14.0-n265400-4edf3b80733e: Tue Dec 19 15:35:46 PST 2023     xxx:/usr/obj/home/FreeBSD/releng-14/amd64.amd64/sys/GENERIC
Processor: 1 cpus, 64bit, little endian

getwd: /home/bakul/v
vexe: /home/bakul/v/v
vexe mtime: 2023-12-28 22:02:16

vroot: OK, value: /home/bakul/v
VMODULES: OK, value: /home/bakul/.vmodules
VTMP: OK, value: /tmp/v_1001

Git version: git version 2.42.0
Git vroot status: 680b0d46
.git/config present: true

CC version: FreeBSD clang version 16.0.6 (https://github.com/llvm/llvm-project.git llvmorg-16.0.6-0-g7cbf1a259152)
thirdparty/tcc: N/A

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.

@bakul bakul added the Bug This tag is applied to issues which reports bugs. label Dec 28, 2023
@bakul
Copy link
Contributor Author

bakul commented Dec 28, 2023

The test succeeds on FreeBSD-13.2-STABLE, using tcc. It fails when cc is used in place of tcc.

@spytheman
Copy link
Member

I can reproduce the same cgen error with clang 16.0.6 on windows too.

@spytheman spytheman added Unit: cgen Bugs/feature requests, that are related to the default C generating backend. Unit: Compiler Bugs/feature requests, that are related to the V compiler in general. Status: Confirmed This bug has been confirmed to be valid by a contributor. labels Dec 29, 2023
@spytheman
Copy link
Member

It compiles fine with clang 15.0.0 and lower.

@shove70
Copy link
Contributor

shove70 commented Dec 30, 2023

This test case has an error, see the comments in the code:

import time

pub type EventListener[T] = fn (T) !

@[heap]
struct Chan[T] {
	c chan T
}

pub type Check[T] = fn (T) bool

struct EventWaiter[T] {
	check ?Check[T]
	c     &Chan[T]
}

pub struct EventController[T] {
mut:
	id        int
	wait_fors map[int]EventWaiter[T]
	listeners map[int]EventListener[T]
}

fn (mut ec EventController[T]) generate_id() int {
	return ec.id++
}

@[params]
pub struct EmitOptions {
pub:
	error_handler ?fn (int, IError)
}

pub fn (mut ec EventController[T]) emit(e T, options EmitOptions) {
	for i, w in ec.wait_fors {
		mut b := false
		if w.check != none {
			b = (w.check or { panic(err) }) // Here !!!!!!, w.check is a ?fn type, the correct code would be:  b = w.check or { panic(err) }(e),   The 'e' in the below row should be the call arg here.
			e
		} else {
			b = true
		}
		if b {
			w.c.c <- e
			ec.wait_fors.delete(i)
			return
		}
	}
	mut ts := []thread{}
	for i, l in ec.listeners {
		ts << spawn fn [options] [T](f EventListener[T], j int, e T) {
			f(e) or {
				if g := options.error_handler {
					g(j, err)
				}
			}
		}(l, i, e)
	}
	ts.wait()
}

@[params]
pub struct EventWaitParams[T] {
pub:
	check   ?Check[T]
	timeout ?time.Duration
}

pub struct Awaitable[T] {
	id      int
	timeout ?time.Duration
	c       Chan[T]
mut:
	controller &EventController[T]
}

struct Zero[T] {
	e T
}

pub fn (mut a Awaitable[T]) do() ?T {
	defer {
		a.controller.wait_fors.delete(a.id)
	}
	if timeout := a.timeout {
		mut e := Zero[T]{}.e
		select {
			e = <-a.c.c {
				r := e
				return r
			}
			timeout.nanoseconds() {
				return none
			}
		}
	}
	return <-a.c.c
}

pub fn (mut ec EventController[T]) wait(params EventWaitParams[T]) Awaitable[T] {
	mut c := Chan[T]{}
	id := ec.generate_id()
	ec.wait_fors[id] = EventWaiter[T]{
		check: params.check
		c: &mut c
	}
	return Awaitable[T]{
		id: id
		timeout: params.timeout
		controller: unsafe { &mut ec }
		c: c
	}
}

struct Foo {}

struct Bar {}

fn main() {
	x := EventController[Foo]{}
	println(x)
	y := EventController[Bar]{}
	println(y)
	assert true
}

There are 3 issues in this issue:

  1. The ?fn type assigned to the bool type, checker does not report an error
  2. Even if the code in test is correct, cgen has another problem.
  3. Fmt formats it into the wrong code, so the wrong code in this test is actually caused by fmt.

So there are 3 issues that need to be fixed


The root cause is the Parser.

@shove70 shove70 self-assigned this Dec 30, 2023
@shove70
Copy link
Contributor

shove70 commented Dec 30, 2023

Simplified:

type Fn[T] = fn (arg T) bool

struct Foo[T] {
	f ?Fn[T]
}

@[params]
struct Bar {}

fn (mut f Foo[T]) method (arg T) {
	mut b := false
	if f.f != none {
		b = (f.f or { panic(err) })
		arg
	} else {
		b = true
	}
	if b {
	}
}

fn main() {
	mut foo := Foo[Bar] {
		f: fn (arg Bar) bool {
			return true
		}
	}
	foo.method(Bar{})
}

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. Status: Confirmed This bug has been confirmed to be valid by a contributor. Unit: cgen Bugs/feature requests, that are related to the default C generating backend. Unit: Compiler Bugs/feature requests, that are related to the V compiler in general.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants