v
v copied to clipboard
parser, cgen: fix option variable error (fix #17460)
This PR fix option variable error (fix #17460, fix #17461).
- Fix option variable error.
- Add test.
struct Foo {
name ?string
}
fn main() {
foo := Foo{}
other := foo.name
println(typeof(other).name)
if name := other {
println('with name: ${name}')
assert false
} else {
println('without name')
assert true
}
println(foo.name)
}
PS D:\Test\v\tt1> v run .
?string
without name
Option(error: none)
struct Foo {
name ?string
}
fn main() {
foo := Foo{}
other := foo.name
mut counter := 0
val := other or {
counter++
'default'
}
assert val == 'default'
assert counter == 1
}
PS D:\Test\v\tt1> v run .
Why does the second example print without name 2 times?
it generated wrongly :-| :
if (other.state != 0) {
IError err = other.err;
println(_SLIT("without name"));
*(string*) other.data = _SLIT("default");
}
string val = /*opt*/(*(string*)other.data);
if (other.state != 0) {
println(_SLIT("without name"));
val = _SLIT("default");
}
;
The second if body should not be there, then it will produce the without name just once.
Ok, I'll fix it.
Something like this can test it:
struct Foo {
name ?string
}
fn test_or_block_should_be_evaluated_just_once() {
foo := Foo{}
other := foo.name
mut counter := 0
val := other or {
counter++
'default'
}
assert val == 'default'
assert counter == 1
}