Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
felipensp committed Oct 7, 2024
1 parent 469be40 commit bcef5ee
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 17 deletions.
36 changes: 23 additions & 13 deletions vlib/v/ast/table.v
Original file line number Diff line number Diff line change
Expand Up @@ -1868,6 +1868,10 @@ pub fn (mut t Table) generic_type_names(generic_type Type) []string {
}

pub fn (mut t Table) unwrap_generic_type(typ Type, generic_names []string, concrete_types []Type) Type {
return t.unwrap_generic_type_ex(typ, generic_names, concrete_types, false)
}

pub fn (mut t Table) unwrap_generic_type_ex(typ Type, generic_names []string, concrete_types []Type, recheck_concrete_types bool) Type {
mut final_concrete_types := []Type{}
mut fields := []StructField{}
mut needs_unwrap_types := []Type{}
Expand All @@ -1877,12 +1881,14 @@ pub fn (mut t Table) unwrap_generic_type(typ Type, generic_names []string, concr
match ts.info {
Array {
dims, elem_type := t.get_array_dims(ts.info)
unwrap_typ := t.unwrap_generic_type(elem_type, generic_names, concrete_types)
unwrap_typ := t.unwrap_generic_type_ex(elem_type, generic_names, concrete_types,
recheck_concrete_types)
idx := t.find_or_register_array_with_dims(unwrap_typ, dims)
return new_type(idx).derive_add_muls(typ).clear_flag(.generic)
}
ArrayFixed {
unwrap_typ := t.unwrap_generic_type(ts.info.elem_type, generic_names, concrete_types)
unwrap_typ := t.unwrap_generic_type_ex(ts.info.elem_type, generic_names, concrete_types,
recheck_concrete_types)
idx := t.find_or_register_array_fixed(unwrap_typ, ts.info.size, None{}, false)
return new_type(idx).derive_add_muls(typ).clear_flag(.generic)
}
Expand All @@ -1892,15 +1898,16 @@ pub fn (mut t Table) unwrap_generic_type(typ Type, generic_names []string, concr
return new_type(idx).derive_add_muls(typ).clear_flag(.generic)
}
Thread {
unwrap_typ := t.unwrap_generic_type(ts.info.return_type, generic_names, concrete_types)
unwrap_typ := t.unwrap_generic_type_ex(ts.info.return_type, generic_names,
concrete_types, recheck_concrete_types)
idx := t.find_or_register_thread(unwrap_typ)
return new_type(idx).derive_add_muls(typ).clear_flag(.generic)
}
Map {
unwrap_key_type := t.unwrap_generic_type(ts.info.key_type, generic_names,
concrete_types)
unwrap_value_type := t.unwrap_generic_type(ts.info.value_type, generic_names,
concrete_types)
unwrap_key_type := t.unwrap_generic_type_ex(ts.info.key_type, generic_names,
concrete_types, recheck_concrete_types)
unwrap_value_type := t.unwrap_generic_type_ex(ts.info.value_type, generic_names,
concrete_types, recheck_concrete_types)
idx := t.find_or_register_map(unwrap_key_type, unwrap_value_type)
return new_type(idx).derive_add_muls(typ).clear_flag(.generic)
}
Expand Down Expand Up @@ -1952,14 +1959,17 @@ pub fn (mut t Table) unwrap_generic_type(typ Type, generic_names []string, concr
nrt += ']'
idx := t.type_idxs[nrt]
if idx != 0 && t.type_symbols[idx].kind != .placeholder {
fields = ts.info.fields.clone()
for i in 0 .. fields.len {
if fields[i].typ.has_flag(.generic) {
if recheck_concrete_types {
fields = ts.info.fields.clone()
for i in 0 .. fields.len {
if !fields[i].typ.has_flag(.generic) {
continue
}
// Map[T], []Type[T]
if fields[i].typ.has_flag(.generic)
&& t.type_kind(fields[i].typ) in [.array, .array_fixed, .map]
if t.type_kind(fields[i].typ) in [.array, .array_fixed, .map]
&& t.check_if_elements_need_unwrap(typ, fields[i].typ) {
t.unwrap_generic_type(fields[i].typ, t_generic_names, t_concrete_types)
t.unwrap_generic_type_ex(fields[i].typ, t_generic_names, t_concrete_types,
recheck_concrete_types)
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions vlib/v/checker/fn.v
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,9 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
}
if c.needs_unwrap_generic_type(node.return_type) {
// resolve generic Array[T], Map[T] generics, avoid recursive generic resolving type
if c.table.cur_concrete_types.any(it == node.return_type) {
c.table.unwrap_generic_type(node.return_type, c.table.cur_fn.generic_names,
c.table.cur_concrete_types)
if !c.table.cur_concrete_types.any(it == node.return_type) {
c.table.unwrap_generic_type_ex(node.return_type, c.table.cur_fn.generic_names,
c.table.cur_concrete_types, true)
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion vlib/v/checker/struct.v
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,8 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini
}
// register generic struct type when current fn is generic fn
if c.table.cur_fn != unsafe { nil } && c.table.cur_fn.generic_names.len > 0 {
c.table.unwrap_generic_type(node.typ, c.table.cur_fn.generic_names, c.table.cur_concrete_types)
c.table.unwrap_generic_type_ex(node.typ, c.table.cur_fn.generic_names, c.table.cur_concrete_types,
true)
}
if !is_field_zero_struct_init {
c.ensure_type_exists(node.typ, node.pos)
Expand Down

0 comments on commit bcef5ee

Please sign in to comment.