v.checker: fix multi insts of generics fn with generic struct (#11161)
parent
576664e31f
commit
579aa7b1b5
|
@ -960,7 +960,7 @@ pub fn (mut c Checker) struct_init(mut node ast.StructInit) ast.Type {
|
|||
unwrapped_struct_type := c.unwrap_generic_type(node.typ, c.table.cur_fn.generic_names,
|
||||
c.table.cur_concrete_types)
|
||||
c.ensure_type_exists(unwrapped_struct_type, node.pos) or {}
|
||||
type_sym := c.table.get_type_symbol(unwrapped_struct_type)
|
||||
type_sym := c.table.get_type_symbol(node.typ)
|
||||
if !c.inside_unsafe && type_sym.kind == .sum_type {
|
||||
c.note('direct sum type init (`x := SumType{}`) will be removed soon', node.pos)
|
||||
}
|
||||
|
@ -1091,7 +1091,7 @@ pub fn (mut c Checker) struct_init(mut node ast.StructInit) ast.Type {
|
|||
if is_embed {
|
||||
expected_type = embed_type
|
||||
c.expected_type = expected_type
|
||||
expr_type = c.unwrap_generic(c.expr(field.expr))
|
||||
expr_type = c.expr(field.expr)
|
||||
expr_type_sym := c.table.get_type_symbol(expr_type)
|
||||
if expr_type != ast.void_type && expr_type_sym.kind != .placeholder {
|
||||
c.check_expected(expr_type, embed_type) or {
|
||||
|
@ -1106,7 +1106,7 @@ pub fn (mut c Checker) struct_init(mut node ast.StructInit) ast.Type {
|
|||
field_type_sym := c.table.get_type_symbol(field_info.typ)
|
||||
expected_type = field_info.typ
|
||||
c.expected_type = expected_type
|
||||
expr_type = c.unwrap_generic(c.expr(field.expr))
|
||||
expr_type = c.expr(field.expr)
|
||||
if !field_info.typ.has_flag(.optional) {
|
||||
expr_type = c.check_expr_opt_call(field.expr, expr_type)
|
||||
}
|
||||
|
@ -1228,7 +1228,7 @@ pub fn (mut c Checker) struct_init(mut node ast.StructInit) ast.Type {
|
|||
c.error('expression is not an lvalue', node.update_expr.position())
|
||||
}
|
||||
}
|
||||
return unwrapped_struct_type
|
||||
return node.typ
|
||||
}
|
||||
|
||||
fn (mut c Checker) check_div_mod_by_zero(expr ast.Expr, op_kind token.Kind) {
|
||||
|
|
|
@ -12,3 +12,10 @@ vlib/v/checker/tests/generic_fn_decl_without_generic_names_err.vv:32:1: error: g
|
|||
| ~~~~~~~~~~~~~~
|
||||
33 | println("hi")
|
||||
34 | }
|
||||
vlib/v/checker/tests/generic_fn_decl_without_generic_names_err.vv:23:9: error: cannot use `Generic` as type `Generic<Concrete>` in return argument
|
||||
21 | go g_worker(g)
|
||||
22 |
|
||||
23 | return g
|
||||
| ^
|
||||
24 | }
|
||||
25 |
|
||||
|
|
|
@ -5,9 +5,3 @@ vlib/v/checker/tests/generics_fn_return_generic_struct_err.vv:13:32: error: retu
|
|||
| ~~~~~~~~~~~~~~~~~~~~
|
||||
14 | d := GenericChannelStruct{
|
||||
15 | ch: chan T{}
|
||||
vlib/v/checker/tests/generics_fn_return_generic_struct_err.vv:17:9: error: cannot use `GenericChannelStruct<Simple>` as type `GenericChannelStruct` in return argument
|
||||
15 | ch: chan T{}
|
||||
16 | }
|
||||
17 | return d
|
||||
| ^
|
||||
18 | }
|
||||
|
|
|
@ -16,7 +16,7 @@ fn main() {
|
|||
}
|
||||
|
||||
pub fn new_channel_struct<T>() GenericChannelStruct<T> {
|
||||
d := GenericChannelStruct{
|
||||
d := GenericChannelStruct<T>{
|
||||
ch: chan T{}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ struct Test<T> {
|
|||
}
|
||||
|
||||
fn get_test<T>(v T) Test<T> {
|
||||
return Test{
|
||||
return Test<T>{
|
||||
v: v
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ mut:
|
|||
}
|
||||
|
||||
pub fn new_some<T>(value T) Optional<T> {
|
||||
return Optional{
|
||||
return Optional<T>{
|
||||
value: value
|
||||
some: true
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ pub struct Foo {
|
|||
}
|
||||
|
||||
pub fn (f Foo) new_some<T>(value T) Optional<T> {
|
||||
return Optional{
|
||||
return Optional<T>{
|
||||
value: value
|
||||
some: true
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ mut:
|
|||
}
|
||||
|
||||
pub fn iter<T>(arr []T) ArrayIterator<T> {
|
||||
return ArrayIterator{
|
||||
return ArrayIterator<T>{
|
||||
data: arr
|
||||
index: 11
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ pub fn (mut i Iterator<T>) next<T>() ?T {
|
|||
}
|
||||
|
||||
pub fn iter_data<T>(data []T) Iterator<T> {
|
||||
return Iterator{
|
||||
return Iterator<T>{
|
||||
data: data
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ mut:
|
|||
}
|
||||
|
||||
pub fn new_some<T, B>(value T, b B) Optional<T> {
|
||||
return Optional{
|
||||
return Optional<T>{
|
||||
value: value
|
||||
some: true
|
||||
typ: typeof(b).name
|
||||
|
@ -54,7 +54,7 @@ pub struct Foo {
|
|||
}
|
||||
|
||||
pub fn (f Foo) new_some<T, B>(value T, b B) Optional<T> {
|
||||
return Optional{
|
||||
return Optional<T>{
|
||||
value: value
|
||||
some: true
|
||||
typ: typeof(b).name
|
||||
|
|
|
@ -5,7 +5,7 @@ mut:
|
|||
}
|
||||
|
||||
fn new_foo<A, B>(a A, b B) Foo<A, B> {
|
||||
return Foo{
|
||||
return Foo<A,B>{
|
||||
a: a
|
||||
b: b
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ mut:
|
|||
}
|
||||
|
||||
fn make_node<T>(val []T) Node<T> {
|
||||
return Node{
|
||||
return Node<T>{
|
||||
val: val[0]
|
||||
next: 0
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ struct Foo<T> {
|
|||
}
|
||||
|
||||
fn new_foo<T>(len int) &Foo<T> {
|
||||
return &Foo{
|
||||
return &Foo<T>{
|
||||
data: []T{len: len}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ fn group_new<T>(val ...T) Group<T> {
|
|||
for i in val {
|
||||
arr << i
|
||||
}
|
||||
mut g := Group{
|
||||
mut g := Group<T>{
|
||||
len: val.len
|
||||
val: arr
|
||||
}
|
||||
|
|
|
@ -13,11 +13,11 @@ mut:
|
|||
|
||||
fn create<T>(arr []T) &List<T> {
|
||||
assert arr.len > 0
|
||||
mut n := &ListNode{
|
||||
mut n := &ListNode<T>{
|
||||
val: arr[0]
|
||||
next: 0
|
||||
}
|
||||
mut l := &List{
|
||||
mut l := &List<T>{
|
||||
first: n
|
||||
last: n
|
||||
count: 1
|
||||
|
@ -26,7 +26,23 @@ fn create<T>(arr []T) &List<T> {
|
|||
}
|
||||
|
||||
fn test_generics_with_generic_structs_init() {
|
||||
n := create([1, 2, 3])
|
||||
println(n)
|
||||
assert n.count == 1
|
||||
list1 := create([1, 2, 3])
|
||||
println(list1)
|
||||
assert list1.count == 1
|
||||
assert list1.first.val == 1
|
||||
|
||||
list2 := create(['a', 'b', 'c'])
|
||||
println(list2)
|
||||
assert list2.count == 1
|
||||
assert list2.first.val == 'a'
|
||||
|
||||
list3 := create([1.1, 2.2, 3.3])
|
||||
println(list3)
|
||||
assert list3.count == 1
|
||||
assert list3.first.val == 1.1
|
||||
|
||||
list4 := create([true, false, true])
|
||||
println(list4)
|
||||
assert list4.count == 1
|
||||
assert list4.first.val == true
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ fn init_singlylinkedlist<T>(nodes ...Node<T>) SinglyLinkedList<T> {
|
|||
current_node.next = &nodes[i + 1]
|
||||
}
|
||||
|
||||
return SinglyLinkedList{&nodes[0]}
|
||||
return SinglyLinkedList<T>{&nodes[0]}
|
||||
}
|
||||
|
||||
fn test_generic_with_variadic_generic_args() {
|
||||
|
|
Loading…
Reference in New Issue