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.67k stars 2.15k forks source link

C error: Lambda function does not compile #21591

Closed elogir closed 3 months ago

elogir commented 3 months ago

V doctor:

V full version: V 0.4.6 433f914.09eaae5
OS: linux, "Manjaro Linux"
Processor: 24 cpus, 64bit, little endian, 12th Gen Intel(R) Core(TM) i9-12900K

getwd: /home/rim/Documents/Git-Repos/superstream-server/src
vexe: /home/rim/Documents/Git-Repos/v/v
vexe mtime: 2024-05-28 17:57:06

vroot: OK, value: /home/rim/Documents/Git-Repos/v
VMODULES: OK, value: /home/rim/.vmodules
VTMP: OK, value: /tmp/v_1000

Git version: git version 2.45.0
Git vroot status: weekly.2023.50-1096-g09eaae5f
.git/config present: true

CC version: cc (GCC) 13.2.1 20240417
thirdparty/tcc status: thirdparty-linux-amd64 40e5cbb5

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

module main

import encoding.xml

fn main() {
    get_text := fn (node xml.XMLNode, tag string) !string {
        return node.get_elements_by_tag(tag)[0]!.children[0]!.str()
    }
}

What did you expect to see?

compiles

What did you see instead?

bug.v:6:2: warning: unused variable: `get_text`
    4 | 
    5 | fn main() {
    6 |     get_text := fn (node xml.XMLNode, tag string) !string {
      |     ~~~~~~~~
    7 |         return node.get_elements_by_tag(tag)[0]!.children[0]!.str()
    8 |     }
==================
/tmp/v_1000/bug.01HZ1QH45SM2ZX2QGQQZBK3T5T.tmp.c:4031: error: lvalue expected
...
==================
(Use `v -cg` to print the entire error message)

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.

spytheman commented 3 months ago

Splitting the return expression into several statements can be used as a workaround:

module main

import encoding.xml

fn main() {
    get_text := fn (node xml.XMLNode, tag string) !string {
        elements := node.get_elements_by_tag(tag)[0]!
        children := elements.children[0]!
        return children.str()
    }
    dump(get_text)
}
spytheman commented 3 months ago

A simpler (less dependencies, and easier to isolate) reproduction of the same problem is:

struct Element {
    children []int
}

fn f() []Element {
    return [Element{
        children: [1, 2, 3]
    }]
}

a := f()[0]!.children[0]!.str()
dump(a)