checker: add error for `type StructAlias = Struct struct Struct { field StructAlias }`
							parent
							
								
									64f1ea6fe9
								
							
						
					
					
						commit
						41e763f79c
					
				|  | @ -610,7 +610,7 @@ pub fn (t &Table) find_type_idx(name string) int { | |||
| } | ||||
| 
 | ||||
| [inline] | ||||
| pub fn (t &Table) find_type(name string) ?&TypeSymbol { | ||||
| pub fn (t &Table) find_sym(name string) ?&TypeSymbol { | ||||
| 	idx := t.type_idxs[name] | ||||
| 	if idx > 0 { | ||||
| 		return t.type_symbols[idx] | ||||
|  | @ -618,6 +618,15 @@ pub fn (t &Table) find_type(name string) ?&TypeSymbol { | |||
| 	return none | ||||
| } | ||||
| 
 | ||||
| [inline] | ||||
| pub fn (t &Table) find_sym_and_type_idx(name string) (&TypeSymbol, int) { | ||||
| 	idx := t.type_idxs[name] | ||||
| 	if idx > 0 { | ||||
| 		return t.type_symbols[idx], idx | ||||
| 	} | ||||
| 	return ast.invalid_type_symbol, idx | ||||
| } | ||||
| 
 | ||||
| pub const invalid_type_symbol = &TypeSymbol{ | ||||
| 	idx: -1 | ||||
| 	parent_idx: -1 | ||||
|  |  | |||
|  | @ -2224,7 +2224,7 @@ fn (mut c Checker) import_stmt(node ast.Import) { | |||
| 	for sym in node.syms { | ||||
| 		name := '${node.mod}.$sym.name' | ||||
| 		if sym.name[0].is_capital() { | ||||
| 			if type_sym := c.table.find_type(name) { | ||||
| 			if type_sym := c.table.find_sym(name) { | ||||
| 				if type_sym.kind != .placeholder { | ||||
| 					if !type_sym.is_public { | ||||
| 						c.error('module `$node.mod` type `$sym.name` is private', sym.pos) | ||||
|  |  | |||
|  | @ -8,7 +8,7 @@ pub fn (mut c Checker) struct_decl(mut node ast.StructDecl) { | |||
| 	if node.language == .v && !c.is_builtin_mod { | ||||
| 		c.check_valid_pascal_case(node.name, 'struct name', node.pos) | ||||
| 	} | ||||
| 	mut struct_sym := c.table.find_type(node.name) or { ast.invalid_type_symbol } | ||||
| 	mut struct_sym, struct_typ_idx := c.table.find_sym_and_type_idx(node.name) | ||||
| 	mut has_generic_types := false | ||||
| 	if mut struct_sym.info is ast.Struct { | ||||
| 		for embed in node.embeds { | ||||
|  | @ -48,6 +48,14 @@ pub fn (mut c Checker) struct_decl(mut node ast.StructDecl) { | |||
| 					c.error('field name `$field.name` duplicate', field.pos) | ||||
| 				} | ||||
| 			} | ||||
| 			if field.typ != 0 { | ||||
| 				if !field.typ.is_ptr() { | ||||
| 					if c.table.unaliased_type(field.typ) == struct_typ_idx { | ||||
| 						c.error('Field `$field.name` is part of `$node.name`, they can not both have the same type', | ||||
| 							field.type_pos) | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			if sym.kind == .struct_ { | ||||
| 				info := sym.info as ast.Struct | ||||
| 				if info.is_heap && !field.typ.is_ptr() { | ||||
|  |  | |||
|  | @ -0,0 +1,7 @@ | |||
| vlib/v/checker/tests/field_can_not_be_from_the_same_type_as_containing_struct.vv:5:9: error: Field `field` is part of `Bar`, they can not both have the same type | ||||
|     3 | struct Bar { | ||||
|     4 |     pfield &Foo = 0 | ||||
|     5 |     field  Foo  = Bar{} | ||||
|       |            ~~~ | ||||
|     6 | } | ||||
|     7 | | ||||
|  | @ -0,0 +1,11 @@ | |||
| type Foo = Bar | ||||
| 
 | ||||
| struct Bar { | ||||
| 	pfield &Foo = 0 | ||||
| 	field  Foo  = Bar{} | ||||
| } | ||||
| 
 | ||||
| fn main() { | ||||
| 	bar := Bar{} | ||||
| 	println(bar) | ||||
| } | ||||
|  | @ -175,7 +175,7 @@ pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) string { | |||
| 	g.enter_namespace('main') | ||||
| 	// generate JS methods for interface methods
 | ||||
| 	for iface_name, iface_types in g.table.iface_types { | ||||
| 		iface := g.table.find_type(iface_name) or { panic('unreachable: interface must exist') } | ||||
| 		iface := g.table.find_sym(iface_name) or { panic('unreachable: interface must exist') } | ||||
| 		for ty in iface_types { | ||||
| 			sym := g.table.sym(ty) | ||||
| 			for method in iface.methods { | ||||
|  |  | |||
|  | @ -249,7 +249,7 @@ pub fn mark_used(mut table ast.Table, pref &pref.Preferences, ast_files []&ast.F | |||
| 	if pref.is_test { | ||||
| 		all_fn_root_names << 'main.cb_assertion_ok' | ||||
| 		all_fn_root_names << 'main.cb_assertion_failed' | ||||
| 		if benched_tests_sym := table.find_type('main.BenchedTests') { | ||||
| 		if benched_tests_sym := table.find_sym('main.BenchedTests') { | ||||
| 			bts_type := benched_tests_sym.methods[0].params[0].typ | ||||
| 			all_fn_root_names << '${bts_type}.testing_step_start' | ||||
| 			all_fn_root_names << '${bts_type}.testing_step_end' | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue