mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: fix enums in builtin (#10366)
This commit is contained in:
parent
012f866619
commit
c14b357fec
@ -6588,16 +6588,15 @@ pub fn (mut c Checker) index_expr(mut node ast.IndexExpr) ast.Type {
|
|||||||
pub fn (mut c Checker) enum_val(mut node ast.EnumVal) ast.Type {
|
pub fn (mut c Checker) enum_val(mut node ast.EnumVal) ast.Type {
|
||||||
mut typ_idx := if node.enum_name == '' {
|
mut typ_idx := if node.enum_name == '' {
|
||||||
c.expected_type.idx()
|
c.expected_type.idx()
|
||||||
} else { //
|
} else {
|
||||||
c.table.find_type_idx(node.enum_name)
|
c.table.find_type_idx(node.enum_name)
|
||||||
}
|
}
|
||||||
// println('checker: enum_val: $node.enum_name typeidx=$typ_idx')
|
|
||||||
if typ_idx == 0 {
|
if typ_idx == 0 {
|
||||||
// Handle `builtin` enums like `ChanState`, so that `x := ChanState.closed` works.
|
// Handle `builtin` enums like `ChanState`, so that `x := ChanState.closed` works.
|
||||||
// In the checker the name for such enums was set to `main.ChanState` instead of
|
// In the checker the name for such enums was set to `main.ChanState` instead of
|
||||||
// just `ChanState`.
|
// just `ChanState`.
|
||||||
if node.enum_name.starts_with('main.') {
|
if node.enum_name.starts_with('${c.mod}.') {
|
||||||
typ_idx = c.table.find_type_idx(node.enum_name['.main'.len..])
|
typ_idx = c.table.find_type_idx(node.enum_name['${c.mod}.'.len..])
|
||||||
if typ_idx == 0 {
|
if typ_idx == 0 {
|
||||||
c.error('unknown enum `$node.enum_name` (type_idx=0)', node.pos)
|
c.error('unknown enum `$node.enum_name` (type_idx=0)', node.pos)
|
||||||
return ast.void_type
|
return ast.void_type
|
||||||
@ -6615,7 +6614,6 @@ pub fn (mut c Checker) enum_val(mut node ast.EnumVal) ast.Type {
|
|||||||
return ast.void_type
|
return ast.void_type
|
||||||
}
|
}
|
||||||
mut typ_sym := c.table.get_type_symbol(typ)
|
mut typ_sym := c.table.get_type_symbol(typ)
|
||||||
// println('tname=$typ_sym.name $node.pos.line_nr $c.file.path')
|
|
||||||
if typ_sym.kind == .array && node.enum_name.len == 0 {
|
if typ_sym.kind == .array && node.enum_name.len == 0 {
|
||||||
array_info := typ_sym.info as ast.Array
|
array_info := typ_sym.info as ast.Array
|
||||||
typ = array_info.elem_type
|
typ = array_info.elem_type
|
||||||
@ -6633,10 +6631,7 @@ pub fn (mut c Checker) enum_val(mut node ast.EnumVal) ast.Type {
|
|||||||
if !(typ_sym.is_public || typ_sym.mod == c.mod) {
|
if !(typ_sym.is_public || typ_sym.mod == c.mod) {
|
||||||
c.error('enum `$typ_sym.name` is private', node.pos)
|
c.error('enum `$typ_sym.name` is private', node.pos)
|
||||||
}
|
}
|
||||||
// info := typ_sym.info as ast.Enum
|
|
||||||
info := typ_sym.enum_info()
|
info := typ_sym.enum_info()
|
||||||
// rintln('checker: x = $info.x enum val $c.expected_type $typ_sym.name')
|
|
||||||
// println(info.vals)
|
|
||||||
if node.val !in info.vals {
|
if node.val !in info.vals {
|
||||||
suggestion := util.new_suggestion(node.val, info.vals)
|
suggestion := util.new_suggestion(node.val, info.vals)
|
||||||
c.error(suggestion.say('enum `$typ_sym.name` does not have a value `$node.val`'),
|
c.error(suggestion.say('enum `$typ_sym.name` does not have a value `$node.val`'),
|
||||||
|
25
vlib/v/tests/projects_that_should_compile_test.v
Normal file
25
vlib/v/tests/projects_that_should_compile_test.v
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
fn testsuite_begin() {
|
||||||
|
os.setenv('VCOLORS', 'never', true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn vroot_path(relpath string) string {
|
||||||
|
return os.real_path(os.join_path(@VMODROOT, relpath))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn vrun_ok(options string, path string) string {
|
||||||
|
cmd := '${@VEXE} $options $path'
|
||||||
|
res := os.execute(cmd)
|
||||||
|
if res.exit_code != 0 {
|
||||||
|
eprintln('> failing vrun cmd: $cmd')
|
||||||
|
eprintln('> output:\n$res.output')
|
||||||
|
assert res.exit_code == 0
|
||||||
|
}
|
||||||
|
return res.output
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_projects_should_run() {
|
||||||
|
res := vrun_ok('run', vroot_path('vlib/v/tests/testdata/enum_in_builtin') + os.path_separator)
|
||||||
|
assert res.trim_space() == 'v0'
|
||||||
|
}
|
18
vlib/v/tests/testdata/enum_in_builtin/builtin.v
vendored
Normal file
18
vlib/v/tests/testdata/enum_in_builtin/builtin.v
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
module builtin
|
||||||
|
|
||||||
|
pub enum BTest_enum {
|
||||||
|
v0 = 0
|
||||||
|
v1
|
||||||
|
v2
|
||||||
|
v3
|
||||||
|
v_t
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (x BTest_enum) tst_f() string {
|
||||||
|
match x {
|
||||||
|
.v0 { return 'v0' }
|
||||||
|
.v1 { return 'v1' }
|
||||||
|
.v2 { return 'v2' }
|
||||||
|
else { return 'v_t' }
|
||||||
|
}
|
||||||
|
}
|
6
vlib/v/tests/testdata/enum_in_builtin/c.v
vendored
Normal file
6
vlib/v/tests/testdata/enum_in_builtin/c.v
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
module c
|
||||||
|
|
||||||
|
pub fn tst_enum() {
|
||||||
|
a := BTest_enum.v0
|
||||||
|
println(a.tst_f())
|
||||||
|
}
|
5
vlib/v/tests/testdata/enum_in_builtin/main.v
vendored
Normal file
5
vlib/v/tests/testdata/enum_in_builtin/main.v
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import c
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
c.tst_enum()
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user