parent
f4c8f897fe
commit
1250ce4353
|
@ -3353,11 +3353,19 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) ast.Type {
|
|||
}
|
||||
if array_init.is_fixed {
|
||||
idx := c.table.find_or_register_array_fixed(elem_type, array_init.exprs.len)
|
||||
if elem_type.has_flag(.generic) {
|
||||
array_init.typ = ast.new_type(idx).set_flag(.generic)
|
||||
} else {
|
||||
array_init.typ = ast.new_type(idx)
|
||||
}
|
||||
} else {
|
||||
idx := c.table.find_or_register_array(elem_type)
|
||||
if elem_type.has_flag(.generic) {
|
||||
array_init.typ = ast.new_type(idx).set_flag(.generic)
|
||||
} else {
|
||||
array_init.typ = ast.new_type(idx)
|
||||
}
|
||||
}
|
||||
array_init.elem_type = elem_type
|
||||
} else if array_init.is_fixed && array_init.exprs.len == 1
|
||||
&& array_init.elem_type != ast.void_type {
|
||||
|
@ -3391,8 +3399,11 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) ast.Type {
|
|||
c.error('fixed size cannot be zero or negative', init_expr.position())
|
||||
}
|
||||
idx := c.table.find_or_register_array_fixed(array_init.elem_type, fixed_size)
|
||||
array_type := ast.new_type(idx)
|
||||
array_init.typ = array_type
|
||||
if array_init.elem_type.has_flag(.generic) {
|
||||
array_init.typ = ast.new_type(idx).set_flag(.generic)
|
||||
} else {
|
||||
array_init.typ = ast.new_type(idx)
|
||||
}
|
||||
if array_init.has_default {
|
||||
c.expr(array_init.default_expr)
|
||||
}
|
||||
|
@ -6047,10 +6058,13 @@ pub fn (mut c Checker) map_init(mut node ast.MapInit) ast.Type {
|
|||
c.check_dup_keys(node, i)
|
||||
}
|
||||
}
|
||||
map_type := ast.new_type(c.table.find_or_register_map(key0_type, val0_type))
|
||||
mut map_type := ast.new_type(c.table.find_or_register_map(key0_type, val0_type))
|
||||
node.typ = map_type
|
||||
node.key_type = key0_type
|
||||
node.value_type = val0_type
|
||||
if node.key_type.has_flag(.generic) || node.value_type.has_flag(.generic) {
|
||||
map_type = map_type.set_flag(.generic)
|
||||
}
|
||||
return map_type
|
||||
}
|
||||
return node.typ
|
||||
|
|
|
@ -3633,7 +3633,7 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) {
|
|||
// arr << val
|
||||
tmp := g.new_tmp_var()
|
||||
info := left_final_sym.info as ast.Array
|
||||
if right_final_sym.kind == .array && info.elem_type != node.right_type {
|
||||
if right_final_sym.kind == .array && info.elem_type != g.unwrap_generic(node.right_type) {
|
||||
// push an array => PUSH_MANY, but not if pushing an array to 2d array (`[][]int << []int`)
|
||||
g.write('_PUSH_MANY(')
|
||||
mut expected_push_many_atype := left_type
|
||||
|
|
|
@ -605,7 +605,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
|
|||
}
|
||||
// TODO performance, detect `array` method differently
|
||||
if left_sym.kind == .array
|
||||
&& node.name in ['repeat', 'sort_with_compare', 'free', 'push_many', 'trim', 'first', 'last', 'pop', 'clone', 'reverse', 'slice'] {
|
||||
&& node.name in ['repeat', 'sort_with_compare', 'free', 'push_many', 'trim', 'first', 'last', 'pop', 'clone', 'reverse', 'slice', 'pointers'] {
|
||||
// && rec_sym.name == 'array' {
|
||||
// && rec_sym.name == 'array' && receiver_name.starts_with('array') {
|
||||
// `array_byte_clone` => `array_clone`
|
||||
|
|
|
@ -33,7 +33,11 @@ fn (mut p Parser) array_init() ast.ArrayInit {
|
|||
// this is set here because it's a known type, others could be the
|
||||
// result of expr so we do those in checker
|
||||
idx := p.table.find_or_register_array(elem_type)
|
||||
if elem_type.has_flag(.generic) {
|
||||
array_type = ast.new_type(idx).set_flag(.generic)
|
||||
} else {
|
||||
array_type = ast.new_type(idx)
|
||||
}
|
||||
has_type = true
|
||||
}
|
||||
last_pos = p.tok.position()
|
||||
|
|
|
@ -43,6 +43,9 @@ pub fn (mut p Parser) parse_array_type() ast.Type {
|
|||
}
|
||||
// sym := p.table.get_type_symbol(elem_type)
|
||||
idx := p.table.find_or_register_array_fixed(elem_type, fixed_size)
|
||||
if elem_type.has_flag(.generic) {
|
||||
return ast.new_type(idx).set_flag(.generic)
|
||||
}
|
||||
return ast.new_type(idx)
|
||||
}
|
||||
// array
|
||||
|
@ -61,6 +64,9 @@ pub fn (mut p Parser) parse_array_type() ast.Type {
|
|||
nr_dims++
|
||||
}
|
||||
idx := p.table.find_or_register_array_with_dims(elem_type, nr_dims)
|
||||
if elem_type.has_flag(.generic) {
|
||||
return ast.new_type(idx).set_flag(.generic)
|
||||
}
|
||||
return ast.new_type(idx)
|
||||
}
|
||||
|
||||
|
@ -101,6 +107,9 @@ pub fn (mut p Parser) parse_map_type() ast.Type {
|
|||
return 0
|
||||
}
|
||||
idx := p.table.find_or_register_map(key_type, value_type)
|
||||
if key_type.has_flag(.generic) || value_type.has_flag(.generic) {
|
||||
return ast.new_type(idx).set_flag(.generic)
|
||||
}
|
||||
return ast.new_type(idx)
|
||||
}
|
||||
|
||||
|
@ -115,6 +124,9 @@ pub fn (mut p Parser) parse_chan_type() ast.Type {
|
|||
is_mut := p.tok.kind == .key_mut
|
||||
elem_type := p.parse_type()
|
||||
idx := p.table.find_or_register_chan(elem_type, is_mut)
|
||||
if elem_type.has_flag(.generic) {
|
||||
return ast.new_type(idx).set_flag(.generic)
|
||||
}
|
||||
return ast.new_type(idx)
|
||||
}
|
||||
|
||||
|
@ -140,17 +152,24 @@ pub fn (mut p Parser) parse_thread_type() ast.Type {
|
|||
}
|
||||
ret_type := p.parse_type()
|
||||
idx := p.table.find_or_register_thread(ret_type)
|
||||
if ret_type.has_flag(.generic) {
|
||||
return ast.new_type(idx).set_flag(.generic)
|
||||
}
|
||||
return ast.new_type(idx)
|
||||
}
|
||||
|
||||
pub fn (mut p Parser) parse_multi_return_type() ast.Type {
|
||||
p.check(.lpar)
|
||||
mut mr_types := []ast.Type{}
|
||||
mut has_generic := false
|
||||
for p.tok.kind != .eof {
|
||||
mr_type := p.parse_type()
|
||||
if mr_type.idx() == 0 {
|
||||
break
|
||||
}
|
||||
if mr_type.has_flag(.generic) {
|
||||
has_generic = true
|
||||
}
|
||||
mr_types << mr_type
|
||||
if p.tok.kind == .comma {
|
||||
p.next()
|
||||
|
@ -164,6 +183,9 @@ pub fn (mut p Parser) parse_multi_return_type() ast.Type {
|
|||
return mr_types[0]
|
||||
}
|
||||
idx := p.table.find_or_register_multi_return(mr_types)
|
||||
if has_generic {
|
||||
return ast.new_type(idx).set_flag(.generic)
|
||||
}
|
||||
return ast.new_type(idx)
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
struct Group<T> {
|
||||
len int
|
||||
val []T
|
||||
mut:
|
||||
index int
|
||||
}
|
||||
|
||||
fn group_new<T>(val ...T) Group<T> {
|
||||
mut arr := []T{cap: val.len}
|
||||
for i in val {
|
||||
arr << i
|
||||
}
|
||||
mut g := Group{
|
||||
len: val.len
|
||||
val: arr
|
||||
}
|
||||
|
||||
return g
|
||||
}
|
||||
|
||||
fn (mut it Group<T>) next<T>() ?T {
|
||||
if it.index >= it.len {
|
||||
return none
|
||||
}
|
||||
v := it.val[it.index]
|
||||
it.index++
|
||||
return v
|
||||
}
|
||||
|
||||
fn test_generics_with_embed_generics() {
|
||||
gx := group_new<int>(1, 2, 3)
|
||||
for x in gx.val {
|
||||
println(x)
|
||||
}
|
||||
assert gx.val == [1, 2, 3]
|
||||
}
|
Loading…
Reference in New Issue