vlang / v

Simple, fast, safe, compiled language for developing maintainable software. Compiles itself in <1s with zero library dependencies. Supports automatic C => V translation. https://vlang.io
MIT License
35.8k stars 2.16k forks source link

simple generic structure declaration error #21989

Open Cergoo opened 3 months ago

Cergoo commented 3 months ago

V doctor:

V full version: V 0.4.7 a4b8768.3ca5bc3
OS: linux, Linux Mint 21.3
Processor: 4 cpus, 64bit, little endian, Intel(R) Core(TM) i5-6300U CPU @ 2.40GHz

getwd: /home/prof/projects/v/parselona
vexe: /home/prof/v/v
vexe mtime: 2024-08-02 18:48:55

vroot: OK, value: /home/prof/v
VMODULES: OK, value: /home/prof/.vmodules
VTMP: OK, value: /tmp/v_1000

Git version: git version 2.43.0
Git vroot status: weekly.2024.31-29-g3ca5bc3b
.git/config present: true

CC version: cc (Ubuntu 13.2.0-23ubuntu4) 13.2.0
thirdparty/tcc status: thirdparty-linux-amd64 a0799a5b

What did you do? ./v -g -o vdbg cmd/v && ./vdbg src/parselona_test.v

module parselona

pub struct ParserResult[I, O] {
    i []I
    o []O
}
pub type TCount = u32

fn (count TCount) take_part<I, O>(i []I) !ParserResult[I, O] {
    if i.len<count { return error('error1') }
    return ParserResult {
        i: i[count..],
        o: i[..count],
    }
}

fn test_1() {
  input := 'ttt_uuuu_qqq_'
  t := TCount(4)
  n := [TCount(4).take_part, TCount(5).take_part, TCount(4).take_part]
}

What did you expect to see?

test complit

What did you see instead?

================== C compilation error (from tcc): ==============
cc: /tmp/v_1000/parselona_test.01J4AXAP60DBZN3ASH1PSJTWTM.tmp.c:1928: error: 'parselona__ParserResult_T_I_O' undeclared
=================================================================
(You can pass `-cg`, or `-show-c-output` as well, to print all the C error messages).
builder error: 
==================
C error found. It should never happen, when compiling pure V code.
This is a V compiler bug, please report it using `v bug file.v`,
or goto https://github.com/vlang/v/issues/new/choose .
You can also use #help on Discord: https://discord.gg/vlang .

[!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.

Cergoo commented 2 months ago

that is, if a generic function returns a generic structure, V cannot deduce that it is necessary to define a generic structure, that is, there is no description of it in C and it complains about the C code.

Cergoo commented 2 months ago

its good C error

JalonSolov commented 2 months ago

No, C errors are never good. V should at least try to catch it and give a nicer error, before sending it to the C compiler.

JalonSolov commented 2 months ago

However, a more complete example will be required before anything can be done about this. With the partial code you show above, there are lots of V errors, and the C compiler is never called at all:

x.v:5:3: warning: unused variable: `input`
    3 | 
    4 | fn test_1() {
    5 |   input := 'ttt_uuuu_qqq_'
      |   ~~~~~
    6 |   t := TCount(4)
    7 |   n := [TCount(4).take_part, TCount(5).take_part, TCount(4).take_part]
x.v:6:3: warning: unused variable: `t`
    4 | fn test_1() {
    5 |   input := 'ttt_uuuu_qqq_'
    6 |   t := TCount(4)
      |   ^
    7 |   n := [TCount(4).take_part, TCount(5).take_part, TCount(4).take_part]
    8 | }
x.v:7:3: warning: unused variable: `n`
    5 |   input := 'ttt_uuuu_qqq_'
    6 |   t := TCount(4)
    7 |   n := [TCount(4).take_part, TCount(5).take_part, TCount(4).take_part]
      |   ^
    8 | }
x.v:6:8: error: unknown type `parselona.TCount`
    4 | fn test_1() {
    5 |   input := 'ttt_uuuu_qqq_'
    6 |   t := TCount(4)
      |        ~~~~~~~~~
    7 |   n := [TCount(4).take_part, TCount(5).take_part, TCount(4).take_part]
    8 | }
x.v:7:9: error: unknown type `parselona.TCount`
    5 |   input := 'ttt_uuuu_qqq_'
    6 |   t := TCount(4)
    7 |   n := [TCount(4).take_part, TCount(5).take_part, TCount(4).take_part]
      |         ~~~~~~~~~
    8 | }
x.v:7:19: error: invalid void array element type
    5 |   input := 'ttt_uuuu_qqq_'
    6 |   t := TCount(4)
    7 |   n := [TCount(4).take_part, TCount(5).take_part, TCount(4).take_part]
      |                   ~~~~~~~~~
    8 | }
x.v:1:1: error: project must include a `main` module or be a shared library (compile with `v -shared`)
    1 | module parselona
      | ^
    2 | 
    3 |
If the code of your project is in multiple files, try with `v .` instead of `v x.v`
CoderMuffin commented 2 months ago

@JalonSolov Should be working here https://play.vlang.io/p/8170c26143

Cergoo commented 2 months ago

module parselona

pub struct ParserResult[O] {
    i []u8
    o O
}

type TParser[O] = fn([]u8) !ParserResult[O]
type TF[O] = fn([]u8) O

fn take_part(count u32) TParser[[]u8] {
    return fn [count] (i []u8) !ParserResult[[]u8] {
        if i.len<count { return error('error len: ${i}') }
                return ParserResult[[]u8] {
                i: i[count..],
                o: i[..count],
               }
    }
}

fn map<O>(p TParser[u8], f TF[O]) TParser[O] {
    return fn [p, f] <O>(i []u8) !ParserResult[O] {
             r:=p(i)!
             return ParserResult{i:r.i, o:f(r.o)}
    }
} 

fn test_1() {
input := '10_ttt_uuuu_qqq_'.bytes()

  nnn:=take_part(2)  
  println(' it is: ${nnn(input)!}')
  fnf := fn(i[]u8) int { return 1 }
  n := map[int](nnn, fnf)

assert ['nn'] == ['ttt_', 'uuuu_', 'qqq_'] 
}

`
--- Testing... -----------------------------------------------------------------------------------------------------------------------------------------------------------
 FAIL     0.000 ms /home/prof/projects/v/parselona/src/parselona_test.v
>> compilation failed:
================== C compilation error (from tcc): ==============
cc: /tmp/v_1000/tsession_704f1d69f740_01J4Q5YZCTYXCVAK9ESWAGAX7W/parselona_test.01J4Q5Z0T9ZS2Q9JCXM6E0YW4D.tmp.c:106: error: identifier expected
=================================================================
(You can pass `-cg`, or `-show-c-output` as well, to print all the C error messages).
builder error: 
==================
C error found. It should never happen, when compiling pure V code.
This is a V compiler bug, please report it using `v bug file.v`,
or goto https://github.com/vlang/v/issues/new/choose .
You can also use #help on Discord: https://discord.gg/vlang .

`
Cergoo commented 2 months ago

However, a more complete example will be required before anything can be done about this. With the partial code you show above, there are lots of V errors, and the C compiler is never called at all:

I updated the text

spytheman commented 2 months ago

I confirm that your updated example, does produce a C error.