V version: V 0.1.24 778a1cc
OS: Linux lambda 4.19.91-1-MANJARO #1 SMP Sat Dec 21 11:18:44 UTC 2019 x86_64 GNU/Linux
What did you do?
import os
fn main () {
mut s := ''
s = os.read_file("mike.dat") or {
panic('boom')
}
println(s)
}
What did you expect to see?
content of file mike.dat
What did you see instead?
$ v run utf.v
/home/mpech/.cache/v/utf.tmp.c: In function ‘main__main’:
/home/mpech/.cache/v/utf.tmp.c:5229:10: error: redeclaration of ‘s’ with no linkage
5229 | string s ;
| ^
/home/mpech/.cac...
(Use `v -g` to print the entire error message)
V error: C error. This should never happen.
Please create a GitHub issue: https://github.com/vlang/v/issues/new/choose
C output:
void main__main () {
string s= tos3("") ;
Option_string tmp1 = os__read_file ( tos3("mike.dat") ) ;
string s ;
if (!tmp1 .ok) {
string err = tmp1 . error;
int errcode = tmp1 . ecode;
v_panic ( tos3("boom") ) ;
}
s = *(string*)tmp1.data;
;
println ( s ) ;
}
The gen_handle_option_or_else method that generates the optional value always redeclares the target variable first: https://github.com/vlang/v/blob/ae4c8af674e70486210222a304f191eacef6e600/vlib/compiler/gen_c.v#L119-L122
Which leads to the duplicate string s declaration above.
Seeing as C does not have the ability to check if a variable has been initialized, the V compiler has to be aware of the existing variable. I'm unfamiliar with the compiler, but maybe passing p.known_var(var_name) as an argument to gen_var_decl in https://github.com/vlang/v/blob/ae4c8af674e70486210222a304f191eacef6e600/vlib/compiler/parser.v#L1690
I can still fail it another way:
$ v -v
V 0.1.24 c24a1b3
fn mike() ?int {
return 122
}
fn main() {
mut a := 0
a = mike()
or {
panic('boom')
}
a++
println('$a')
}
$ v run ff.v
/home/mpech/.cache/v/ff.tmp.c: In function ‘main__main’:
/home/mpech/.cache/v/ff.tmp.c:3909:7: error: redeclaration of ‘a’ with no linkage
3909 | int a ;
| ^
/home/mpech/.cache/v/ff.t...
(Use `v -g` to print the entire error message)
V error: C error. This should never happen.
Please create a GitHub issue: https://github.com/vlang/v/issues/new/choose
is_var_decl is set to false explicitly just earlier during assignment: https://github.com/vlang/v/blob/master/vlib/compiler/aparser.v#L1605-L1607
Setting it back to true before handing it to gen_handle_option_or_else call in line 1623 fixes this case too, but this just feels wrong, and I'm a bit lost on what's going on in those three lines above. I would expect an initialization assignment to fail after this patch, but it doesn't... I'll have to defer to someone with more knowledge of this.
This issue was also reported in #3389, but IMO that has a better title, so I'm closing this one. :)
Most helpful comment
C output:
The
gen_handle_option_or_elsemethod that generates the optional value always redeclares the target variable first: https://github.com/vlang/v/blob/ae4c8af674e70486210222a304f191eacef6e600/vlib/compiler/gen_c.v#L119-L122Which leads to the duplicate
string sdeclaration above.Seeing as C does not have the ability to check if a variable has been initialized, the V compiler has to be aware of the existing variable. I'm unfamiliar with the compiler, but maybe passing
p.known_var(var_name)as an argument togen_var_declin https://github.com/vlang/v/blob/ae4c8af674e70486210222a304f191eacef6e600/vlib/compiler/parser.v#L1690