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) {
|
if c.table.sumtype_has_variant(expected, ast.mktyp(got), false) {
|
||||||
return true
|
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
|
// type alias
|
||||||
if (got_sym.kind == .alias && got_sym.parent_idx == expected.idx())
|
if (got_sym.kind == .alias && got_sym.parent_idx == expected.idx())
|
||||||
|| (exp_sym.kind == .alias && exp_sym.parent_idx == got.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 {
|
if field_sym.name == gt_name {
|
||||||
for t in node.fields {
|
for t in node.fields {
|
||||||
if ft.name == t.name && t.typ != 0 {
|
if ft.name == t.name && t.typ != 0 {
|
||||||
concrete_types << t.typ
|
concrete_types << ast.mktyp(t.typ)
|
||||||
continue gname
|
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.nr_muls() > 0 {
|
||||||
elem_typ = elem_typ.set_nr_muls(0)
|
elem_typ = elem_typ.set_nr_muls(0)
|
||||||
}
|
}
|
||||||
concrete_types << elem_typ
|
concrete_types << ast.mktyp(elem_typ)
|
||||||
continue gname
|
continue gname
|
||||||
}
|
}
|
||||||
break
|
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.nr_muls() > 0 {
|
||||||
elem_typ = elem_typ.set_nr_muls(0)
|
elem_typ = elem_typ.set_nr_muls(0)
|
||||||
}
|
}
|
||||||
concrete_types << elem_typ
|
concrete_types << ast.mktyp(elem_typ)
|
||||||
continue gname
|
continue gname
|
||||||
}
|
}
|
||||||
break
|
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.nr_muls() > 0 {
|
||||||
key_typ = key_typ.set_nr_muls(0)
|
key_typ = key_typ.set_nr_muls(0)
|
||||||
}
|
}
|
||||||
concrete_types << key_typ
|
concrete_types << ast.mktyp(key_typ)
|
||||||
continue gname
|
continue gname
|
||||||
}
|
}
|
||||||
if field_sym.info.value_type.has_flag(.generic)
|
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.nr_muls() > 0 {
|
||||||
val_typ = val_typ.set_nr_muls(0)
|
val_typ = val_typ.set_nr_muls(0)
|
||||||
}
|
}
|
||||||
concrete_types << val_typ
|
concrete_types << ast.mktyp(val_typ)
|
||||||
continue gname
|
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 {
|
if fn_param.typ.nr_muls() > 0 && arg_typ.nr_muls() > 0 {
|
||||||
arg_typ = arg_typ.set_nr_muls(0)
|
arg_typ = arg_typ.set_nr_muls(0)
|
||||||
}
|
}
|
||||||
concrete_types << arg_typ
|
concrete_types << ast.mktyp(arg_typ)
|
||||||
continue gname
|
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.nr_muls() > 0 {
|
||||||
ret_typ = ret_typ.set_nr_muls(0)
|
ret_typ = ret_typ.set_nr_muls(0)
|
||||||
}
|
}
|
||||||
concrete_types << ret_typ
|
concrete_types << ast.mktyp(ret_typ)
|
||||||
continue gname
|
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