From 3cd540decce95106f37d62e8d87708ba39d0e09e Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sat, 5 Oct 2024 09:15:03 -0300 Subject: [PATCH] fix --- vlib/v/ast/table.v | 11 ++++ .../structs/struct_array_generic_field_test.v | 58 +++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 vlib/v/tests/structs/struct_array_generic_field_test.v diff --git a/vlib/v/ast/table.v b/vlib/v/ast/table.v index 7481543176a0aa..44ed747e3dbccc 100644 --- a/vlib/v/ast/table.v +++ b/vlib/v/ast/table.v @@ -1952,6 +1952,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) { + // Map[T], []Type[T] + if fields[i].typ.has_flag(.generic) + && 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) + } + } + } return new_type(idx).derive(typ).clear_flag(.generic) } else { // fields type translate to concrete type diff --git a/vlib/v/tests/structs/struct_array_generic_field_test.v b/vlib/v/tests/structs/struct_array_generic_field_test.v new file mode 100644 index 00000000000000..122e18cad9c54b --- /dev/null +++ b/vlib/v/tests/structs/struct_array_generic_field_test.v @@ -0,0 +1,58 @@ +// callback types +type CBnoret[T] = fn (val T) + +type CBnoret2[T] = fn (val T, prev T) + +type CBvret[T] = fn (val T) T + +type CBvret2[T] = fn (val T, prev T) T + +type Callback[T] = CBnoret[T] | CBnoret2[T] | CBvret[T] | CBvret2[T] + +interface IObv[T] { + v T + prev T + cb []Callback[T] +} + +struct Obv[T] { +mut: + v T + prev T + cb []Callback[T] +} + +fn (o Obv[T]) get() T { + return o.v +} + +fn (o Obv[T]) do_callbacks() T { + return o.v +} + +fn (mut o Obv[T]) set(new_value T) T { + prev := o.v + if prev != new_value { + o.v = new_value + o.prev = prev + } + + return o.v +} + +fn oo[T](init T) Obv[T] { + return Obv[T]{ + v: init + } +} + +fn test_main() { + one := oo(1) + txt := oo('lala') + + println('txt: ${txt.get()}') + println('one: ${one.get()}') + + assert txt.get() == 'lala' + assert one.get() == 1 +}