checker: fix enums in builtin (#10366)
							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`'), | ||||||
|  |  | ||||||
|  | @ -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' | ||||||
|  | } | ||||||
|  | @ -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' } | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -0,0 +1,6 @@ | ||||||
|  | module c | ||||||
|  | 
 | ||||||
|  | pub fn tst_enum() { | ||||||
|  | 	a := BTest_enum.v0 | ||||||
|  | 	println(a.tst_f()) | ||||||
|  | } | ||||||
|  | @ -0,0 +1,5 @@ | ||||||
|  | import c | ||||||
|  | 
 | ||||||
|  | fn main() { | ||||||
|  | 	c.tst_enum() | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue