mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
This commit is contained in:
parent
88dab8fc2d
commit
1cad788779
@ -784,8 +784,9 @@ fn (t Tree) alias_type_decl(node ast.AliasTypeDecl) &Node {
|
||||
mut obj := new_object()
|
||||
obj.add_terse('ast_type', t.string_node('AliasTypeDecl'))
|
||||
obj.add_terse('name', t.string_node(node.name))
|
||||
obj.add_terse('is_pub', t.bool_node(node.is_pub))
|
||||
obj.add_terse('typ', t.type_node(node.typ))
|
||||
obj.add_terse('parent_type', t.type_node(node.parent_type))
|
||||
obj.add_terse('is_pub', t.bool_node(node.is_pub))
|
||||
obj.add('comments', t.array_node_comment(node.comments))
|
||||
obj.add('pos', t.pos(node.pos))
|
||||
return obj
|
||||
|
@ -1183,6 +1183,7 @@ pub struct AliasTypeDecl {
|
||||
pub:
|
||||
name string
|
||||
is_pub bool
|
||||
typ Type
|
||||
parent_type Type
|
||||
pos token.Pos
|
||||
type_pos token.Pos
|
||||
|
@ -435,32 +435,88 @@ fn (mut c Checker) alias_type_decl(node ast.AliasTypeDecl) {
|
||||
c.check_valid_pascal_case(node.name, 'type alias', node.pos)
|
||||
}
|
||||
c.ensure_type_exists(node.parent_type, node.type_pos) or { return }
|
||||
mut typ_sym := c.table.sym(node.parent_type)
|
||||
if typ_sym.kind in [.placeholder, .int_literal, .float_literal] {
|
||||
c.error('unknown type `${typ_sym.name}`', node.type_pos)
|
||||
} else if typ_sym.kind == .alias {
|
||||
orig_sym := c.table.sym((typ_sym.info as ast.Alias).parent_type)
|
||||
c.error('type `${typ_sym.str()}` is an alias, use the original alias type `${orig_sym.name}` instead',
|
||||
node.type_pos)
|
||||
} else if typ_sym.kind == .chan {
|
||||
c.error('aliases of `chan` types are not allowed.', node.type_pos)
|
||||
} else if typ_sym.kind == .function {
|
||||
orig_sym := c.table.type_to_str(node.parent_type)
|
||||
c.error('type `${typ_sym.str()}` is an alias, use the original alias type `${orig_sym}` instead',
|
||||
node.type_pos)
|
||||
} else if typ_sym.kind == .struct_ {
|
||||
if mut typ_sym.info is ast.Struct {
|
||||
// check if the generic param types have been defined
|
||||
for ct in typ_sym.info.concrete_types {
|
||||
ct_sym := c.table.sym(ct)
|
||||
if ct_sym.kind == .placeholder {
|
||||
c.error('unknown type `${ct_sym.name}`', node.type_pos)
|
||||
mut parent_typ_sym := c.table.sym(node.parent_type)
|
||||
match parent_typ_sym.kind {
|
||||
.placeholder, .int_literal, .float_literal {
|
||||
c.error('unknown aliased type `${parent_typ_sym.name}`', node.type_pos)
|
||||
}
|
||||
.alias {
|
||||
orig_sym := c.table.sym((parent_typ_sym.info as ast.Alias).parent_type)
|
||||
c.error('type `${parent_typ_sym.str()}` is an alias, use the original alias type `${orig_sym.name}` instead',
|
||||
node.type_pos)
|
||||
}
|
||||
.chan {
|
||||
c.error('aliases of `chan` types are not allowed', node.type_pos)
|
||||
}
|
||||
.thread {
|
||||
c.error('aliases of `thread` types are not allowed', node.type_pos)
|
||||
}
|
||||
.multi_return {
|
||||
c.error('aliases of function multi return types are not allowed', node.type_pos)
|
||||
}
|
||||
.void {
|
||||
c.error('aliases of the void type are not allowed', node.type_pos)
|
||||
}
|
||||
.function {
|
||||
orig_sym := c.table.type_to_str(node.parent_type)
|
||||
c.error('type `${parent_typ_sym.str()}` is an alias, use the original alias type `${orig_sym}` instead',
|
||||
node.type_pos)
|
||||
}
|
||||
.struct_ {
|
||||
if mut parent_typ_sym.info is ast.Struct {
|
||||
// check if the generic param types have been defined
|
||||
for ct in parent_typ_sym.info.concrete_types {
|
||||
ct_sym := c.table.sym(ct)
|
||||
if ct_sym.kind == .placeholder {
|
||||
c.error('unknown type `${ct_sym.name}`', node.type_pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.array {
|
||||
c.check_alias_vs_element_type_of_parent(node, (parent_typ_sym.info as ast.Array).elem_type,
|
||||
'array')
|
||||
}
|
||||
.array_fixed {
|
||||
c.check_alias_vs_element_type_of_parent(node, (parent_typ_sym.info as ast.ArrayFixed).elem_type,
|
||||
'fixed array')
|
||||
}
|
||||
.map {
|
||||
info := parent_typ_sym.info as ast.Map
|
||||
c.check_alias_vs_element_type_of_parent(node, info.key_type, 'map key')
|
||||
c.check_alias_vs_element_type_of_parent(node, info.value_type, 'map value')
|
||||
}
|
||||
.sum_type {
|
||||
// TODO: decide whether the following should be allowed. Note that it currently works,
|
||||
// while `type Sum = int | Sum` is explicitly disallowed:
|
||||
// type Sum = int | Alias
|
||||
// type Alias = Sum
|
||||
}
|
||||
// The rest of the parent symbol kinds are also allowed, since they are either primitive types,
|
||||
// that in turn do not allow recursion, or are abstract enough so that they can not be checked at comptime:
|
||||
else {}
|
||||
/*
|
||||
.voidptr, .byteptr, .charptr {}
|
||||
.char, .rune, .bool {}
|
||||
.string, .enum_, .none_, .any {}
|
||||
.i8, .i16, .int, .i64, .isize {}
|
||||
.u8, .u16, .u32, .u64, .usize {}
|
||||
.f32, .f64 {}
|
||||
.interface_ {}
|
||||
.generic_inst {}
|
||||
.aggregate {}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut c Checker) check_alias_vs_element_type_of_parent(node ast.AliasTypeDecl, element_type_of_parent ast.Type, label string) {
|
||||
if node.typ.idx() != element_type_of_parent.idx() {
|
||||
return
|
||||
}
|
||||
c.error('recursive declarations of aliases are not allowed - the alias `${node.name}` is used in the ${label}',
|
||||
node.type_pos)
|
||||
}
|
||||
|
||||
fn (mut c Checker) fn_type_decl(node ast.FnTypeDecl) {
|
||||
c.check_valid_pascal_case(node.name, 'fn type', node.pos)
|
||||
typ_sym := c.table.sym(node.typ)
|
||||
@ -4230,6 +4286,12 @@ fn (mut c Checker) ensure_generic_type_specify_type_names(typ ast.Type, pos toke
|
||||
}
|
||||
|
||||
sym := c.table.final_sym(typ)
|
||||
if c.ensure_generic_type_level > 38 {
|
||||
dump(typ)
|
||||
dump(sym.kind)
|
||||
dump(pos)
|
||||
dump(c.ensure_generic_type_level)
|
||||
}
|
||||
match sym.kind {
|
||||
.function {
|
||||
fn_info := sym.info as ast.FnType
|
||||
|
50
vlib/v/checker/tests/recursive_alias_type_err.out
Normal file
50
vlib/v/checker/tests/recursive_alias_type_err.out
Normal file
@ -0,0 +1,50 @@
|
||||
vlib/v/checker/tests/recursive_alias_type_err.vv:1:24: error: recursive declarations of aliases are not allowed - the alias `VTableTypeArray` is used in the array
|
||||
1 | type VTableTypeArray = []VTableTypeArray
|
||||
| ~~~~~~~~~~~~~~~~~
|
||||
2 | type VTableTypeArrayPointer = []&VTableTypeArrayPointer
|
||||
3 |
|
||||
vlib/v/checker/tests/recursive_alias_type_err.vv:2:31: error: recursive declarations of aliases are not allowed - the alias `VTableTypeArrayPointer` is used in the array
|
||||
1 | type VTableTypeArray = []VTableTypeArray
|
||||
2 | type VTableTypeArrayPointer = []&VTableTypeArrayPointer
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
3 |
|
||||
4 | type VTableTypeArrayFixed = [5]VTableTypeArrayFixed
|
||||
vlib/v/checker/tests/recursive_alias_type_err.vv:4:29: error: recursive declarations of aliases are not allowed - the alias `VTableTypeArrayFixed` is used in the fixed array
|
||||
2 | type VTableTypeArrayPointer = []&VTableTypeArrayPointer
|
||||
3 |
|
||||
4 | type VTableTypeArrayFixed = [5]VTableTypeArrayFixed
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~
|
||||
5 | type VTableTypeArrayFixedPointer = [5]&VTableTypeArrayFixedPointer
|
||||
6 |
|
||||
vlib/v/checker/tests/recursive_alias_type_err.vv:5:36: error: recursive declarations of aliases are not allowed - the alias `VTableTypeArrayFixedPointer` is used in the fixed array
|
||||
3 |
|
||||
4 | type VTableTypeArrayFixed = [5]VTableTypeArrayFixed
|
||||
5 | type VTableTypeArrayFixedPointer = [5]&VTableTypeArrayFixedPointer
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
6 |
|
||||
7 | type VTableTypeMap = map[string]VTableTypeMap
|
||||
vlib/v/checker/tests/recursive_alias_type_err.vv:7:22: error: recursive declarations of aliases are not allowed - the alias `VTableTypeMap` is used in the map value
|
||||
5 | type VTableTypeArrayFixedPointer = [5]&VTableTypeArrayFixedPointer
|
||||
6 |
|
||||
7 | type VTableTypeMap = map[string]VTableTypeMap
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
8 | type VTableTypeMapOfPointer = map[string]&VTableTypeMapOfPointer
|
||||
9 |
|
||||
vlib/v/checker/tests/recursive_alias_type_err.vv:8:31: error: recursive declarations of aliases are not allowed - the alias `VTableTypeMapOfPointer` is used in the map value
|
||||
6 |
|
||||
7 | type VTableTypeMap = map[string]VTableTypeMap
|
||||
8 | type VTableTypeMapOfPointer = map[string]&VTableTypeMapOfPointer
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
9 |
|
||||
10 | type VTableTypeMapKey = map[VTableTypeMapKey]int
|
||||
vlib/v/checker/tests/recursive_alias_type_err.vv:10:25: error: recursive declarations of aliases are not allowed - the alias `VTableTypeMapKey` is used in the map key
|
||||
8 | type VTableTypeMapOfPointer = map[string]&VTableTypeMapOfPointer
|
||||
9 |
|
||||
10 | type VTableTypeMapKey = map[VTableTypeMapKey]int
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
11 | type VTableTypeMapOfPointerKey = map[&VTableTypeMapOfPointerKey]int
|
||||
vlib/v/checker/tests/recursive_alias_type_err.vv:11:34: error: recursive declarations of aliases are not allowed - the alias `VTableTypeMapOfPointerKey` is used in the map key
|
||||
9 |
|
||||
10 | type VTableTypeMapKey = map[VTableTypeMapKey]int
|
||||
11 | type VTableTypeMapOfPointerKey = map[&VTableTypeMapOfPointerKey]int
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
11
vlib/v/checker/tests/recursive_alias_type_err.vv
Normal file
11
vlib/v/checker/tests/recursive_alias_type_err.vv
Normal file
@ -0,0 +1,11 @@
|
||||
type VTableTypeArray = []VTableTypeArray
|
||||
type VTableTypeArrayPointer = []&VTableTypeArrayPointer
|
||||
|
||||
type VTableTypeArrayFixed = [5]VTableTypeArrayFixed
|
||||
type VTableTypeArrayFixedPointer = [5]&VTableTypeArrayFixedPointer
|
||||
|
||||
type VTableTypeMap = map[string]VTableTypeMap
|
||||
type VTableTypeMapOfPointer = map[string]&VTableTypeMapOfPointer
|
||||
|
||||
type VTableTypeMapKey = map[VTableTypeMapKey]int
|
||||
type VTableTypeMapOfPointerKey = map[&VTableTypeMapOfPointerKey]int
|
@ -4000,6 +4000,7 @@ fn (mut p Parser) type_decl() ast.TypeDecl {
|
||||
return ast.AliasTypeDecl{
|
||||
name: name
|
||||
is_pub: is_pub
|
||||
typ: idx
|
||||
parent_type: parent_type
|
||||
type_pos: type_pos.extend(type_end_pos)
|
||||
pos: decl_pos
|
||||
|
Loading…
Reference in New Issue
Block a user