mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: fix generic struct init with generic struct items (#18152)
This commit is contained in:
parent
492a93ecd9
commit
a87f2d9d11
@ -367,6 +367,12 @@ fn (mut c Checker) check_basic(got ast.Type, expected ast.Type) bool {
|
||||
if c.table.sumtype_has_variant(expected, ast.mktyp(got), false) {
|
||||
return true
|
||||
}
|
||||
// struct
|
||||
if exp_sym.kind == .struct_ && got_sym.kind == .struct_ {
|
||||
if c.table.type_to_str(expected) == c.table.type_to_str(got) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
// type alias
|
||||
if (got_sym.kind == .alias && got_sym.parent_idx == expected.idx())
|
||||
|| (exp_sym.kind == .alias && exp_sym.parent_idx == got.idx()) {
|
||||
@ -671,7 +677,7 @@ fn (mut c Checker) infer_struct_generic_types(typ ast.Type, node ast.StructInit)
|
||||
if field_sym.name == gt_name {
|
||||
for t in node.fields {
|
||||
if ft.name == t.name && t.typ != 0 {
|
||||
concrete_types << t.typ
|
||||
concrete_types << ast.mktyp(t.typ)
|
||||
continue gname
|
||||
}
|
||||
}
|
||||
@ -695,7 +701,7 @@ fn (mut c Checker) infer_struct_generic_types(typ ast.Type, node ast.StructInit)
|
||||
&& elem_typ.nr_muls() > 0 {
|
||||
elem_typ = elem_typ.set_nr_muls(0)
|
||||
}
|
||||
concrete_types << elem_typ
|
||||
concrete_types << ast.mktyp(elem_typ)
|
||||
continue gname
|
||||
}
|
||||
break
|
||||
@ -723,7 +729,7 @@ fn (mut c Checker) infer_struct_generic_types(typ ast.Type, node ast.StructInit)
|
||||
&& elem_typ.nr_muls() > 0 {
|
||||
elem_typ = elem_typ.set_nr_muls(0)
|
||||
}
|
||||
concrete_types << elem_typ
|
||||
concrete_types << ast.mktyp(elem_typ)
|
||||
continue gname
|
||||
}
|
||||
break
|
||||
@ -744,7 +750,7 @@ fn (mut c Checker) infer_struct_generic_types(typ ast.Type, node ast.StructInit)
|
||||
&& key_typ.nr_muls() > 0 {
|
||||
key_typ = key_typ.set_nr_muls(0)
|
||||
}
|
||||
concrete_types << key_typ
|
||||
concrete_types << ast.mktyp(key_typ)
|
||||
continue gname
|
||||
}
|
||||
if field_sym.info.value_type.has_flag(.generic)
|
||||
@ -754,7 +760,7 @@ fn (mut c Checker) infer_struct_generic_types(typ ast.Type, node ast.StructInit)
|
||||
&& val_typ.nr_muls() > 0 {
|
||||
val_typ = val_typ.set_nr_muls(0)
|
||||
}
|
||||
concrete_types << val_typ
|
||||
concrete_types << ast.mktyp(val_typ)
|
||||
continue gname
|
||||
}
|
||||
}
|
||||
@ -773,7 +779,7 @@ fn (mut c Checker) infer_struct_generic_types(typ ast.Type, node ast.StructInit)
|
||||
if fn_param.typ.nr_muls() > 0 && arg_typ.nr_muls() > 0 {
|
||||
arg_typ = arg_typ.set_nr_muls(0)
|
||||
}
|
||||
concrete_types << arg_typ
|
||||
concrete_types << ast.mktyp(arg_typ)
|
||||
continue gname
|
||||
}
|
||||
}
|
||||
@ -784,7 +790,7 @@ fn (mut c Checker) infer_struct_generic_types(typ ast.Type, node ast.StructInit)
|
||||
&& ret_typ.nr_muls() > 0 {
|
||||
ret_typ = ret_typ.set_nr_muls(0)
|
||||
}
|
||||
concrete_types << ret_typ
|
||||
concrete_types << ast.mktyp(ret_typ)
|
||||
continue gname
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,85 @@
|
||||
struct Item[T] {
|
||||
val T
|
||||
}
|
||||
|
||||
struct Items[A, B] {
|
||||
item1 Item[A]
|
||||
item2 Item[B]
|
||||
}
|
||||
|
||||
fn combine[A, B](a A, b B) Items[A, B] {
|
||||
return Items[A, B]{
|
||||
item1: Item[A]{
|
||||
val: a
|
||||
}
|
||||
item2: Item[B]{
|
||||
val: b
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn test_generic_struct_with_generic_struct_items() {
|
||||
_ := Items[int, string]{Item{42}, Item{'bye'}}
|
||||
_ := Items[int, string]{
|
||||
item1: Item{42}
|
||||
item2: Item{'bye'}
|
||||
}
|
||||
_ := Items[int, string]{
|
||||
item1: Item{
|
||||
val: 42
|
||||
}
|
||||
item2: Item{
|
||||
val: 'bye'
|
||||
}
|
||||
}
|
||||
_ := Items[int, string]{
|
||||
item1: Item[int]{
|
||||
val: 42
|
||||
}
|
||||
item2: Item[string]{
|
||||
val: 'bye'
|
||||
}
|
||||
}
|
||||
_ := Items[string, int]{
|
||||
item1: Item[string]{
|
||||
val: 'hallo'
|
||||
}
|
||||
item2: Item[int]{
|
||||
val: 42
|
||||
}
|
||||
}
|
||||
_ := Items[string, string]{
|
||||
item1: Item[string]{
|
||||
val: 'hallo'
|
||||
}
|
||||
item2: Item[string]{
|
||||
val: 'bye'
|
||||
}
|
||||
}
|
||||
|
||||
// calling function all combination OK
|
||||
r1 := combine('Hallo', 42)
|
||||
println(r1)
|
||||
assert r1.item1.val == 'Hallo'
|
||||
assert r1.item2.val == 42
|
||||
|
||||
r2 := combine(42, 'Hallo')
|
||||
println(r2)
|
||||
assert r2.item1.val == 42
|
||||
assert r2.item2.val == 'Hallo'
|
||||
|
||||
r3 := combine('Hallo', 'Bye')
|
||||
println(r3)
|
||||
assert r3.item1.val == 'Hallo'
|
||||
assert r3.item2.val == 'Bye'
|
||||
|
||||
r4 := combine(42, 44)
|
||||
println(r4)
|
||||
assert r4.item1.val == 42
|
||||
assert r4.item2.val == 44
|
||||
|
||||
r5 := combine(`🥸`, `🤡`)
|
||||
println(r5)
|
||||
assert r5.item1.val == `🥸`
|
||||
assert r5.item2.val == `🤡`
|
||||
}
|
Loading…
Reference in New Issue
Block a user